<?php
/**
 * Feature gating and plan detection — the single switchboard for the
 * free/pro product split.
 *
 * Flip any feature between 'free' and 'pro' in the $features map, or change
 * per-plan numeric limits in the $limits map. Nothing else in the codebase
 * needs to change: everything goes through can() and limit().
 *
 * Works with Freemius (when the SDK is present) and falls back to a manual
 * license-key option so the plugin is never broken without the SDK.
 */
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class BingoCR_License {

	// ── THE SWITCHBOARD ───────────────────────────────────────────────────
	// 'free' = available to everyone, 'pro' = requires a paid plan.
	// Features not listed here are treated as free.
	private static $features = array(
		'extras'          => 'pro',  // optional add-ons at checkout (code absent from free build)
		'discounts'       => 'pro',  // discount codes (code absent from free build)
		'out_of_hours'    => 'pro',  // out-of-hours pickup/return fee (code absent from free build)
		'online_payments' => 'pro',  // online payment / PayPal (code absent from free build)
		// dark_theme, custom_color, offline_payments are fully free — no gate.
	);

	// No numeric limits in the free build — unlimited cars and locations.
	private static $limits = array(
		'cars'      => array( 'free' => -1, 'pro' => -1 ),
		'locations' => array( 'free' => -1, 'pro' => -1 ),
	);

	// ── Plan detection ────────────────────────────────────────────────────

	/**
	 * Returns true when the site is on a paid plan.
	 *
	 * Freemius is the single source of truth — no constant override and no option
	 * fallback, so there is no "flip one boolean" path to unlock Pro. (Test Pro
	 * features with a Freemius sandbox license in dev mode.)
	 */
	public static function is_pro(): bool {
		if ( function_exists( 'bingocr_fs' ) ) {
			$fs = bingocr_fs();
			if ( $fs !== null ) {
				return $fs->can_use_premium_code();
			}
		}

		// No Freemius SDK present (broken/SDK-less install) — treat as free.
		return false;
	}

	// ── Feature / limit gates ─────────────────────────────────────────────

	/**
	 * Returns true when the given feature is available on the current plan.
	 *
	 * @param string $feature  A key from $features, or any custom string (= free).
	 */
	public static function can( string $feature ): bool {
		$tier = self::$features[ $feature ] ?? 'free';
		return 'free' === $tier || self::is_pro();
	}

	/**
	 * Returns the numeric limit for the current plan. PHP_INT_MAX = unlimited.
	 *
	 * @param string $thing  A key from $limits, e.g. 'cars' or 'locations'.
	 */
	public static function limit( string $thing ): int {
		$plan = self::is_pro() ? 'pro' : 'free';
		$n    = self::$limits[ $thing ][ $plan ] ?? -1;
		return $n < 0 ? PHP_INT_MAX : $n;
	}

	public static function car_limit(): int {
		return self::limit( 'cars' );
	}

	public static function location_limit(): int {
		return self::limit( 'locations' );
	}

	// ── UI helpers ────────────────────────────────────────────────────────

	public static function plan_label(): string {
		return self::is_pro()
			? __( 'Pro', 'bingocar' )
			: __( 'Free', 'bingocar' );
	}

	public static function upgrade_url(): string {
		if ( function_exists( 'bingocr_fs' ) ) {
			$fs = bingocr_fs();
			if ( $fs !== null ) {
				return esc_url( $fs->get_upgrade_url() );
			}
		}
		return esc_url( 'https://bingorentals.com/bingocr-pro' );
	}

	/**
	 * Returns a WP_REST_Response 403 with upgrade prompt.
	 * Use this as a one-liner return inside REST callbacks.
	 */
	public static function limit_response( string $message ): WP_REST_Response {
		return new WP_REST_Response( array(
			'message'     => $message,
			'upgrade_url' => self::upgrade_url(),
			'code'        => 'pro_required',
		), 403 );
	}
}
