<?php
if ( ! defined( 'ABSPATH' ) ) exit;
class SS_Licensing {
    const TRANSIENT_KEY = 'ss_license_status';
    const TTL = 2 * MINUTE_IN_SECONDS;
       
    const REFRESH_EARLY_SEC = 2 * HOUR_IN_SECONDS; // background refresh when <2h left

    public static function init(){
        add_action('update_option_'.SS_Settings::OPT_API_KEY,  [__CLASS__,'invalidate'],10,2);
        add_action('update_option_'.SS_Settings::OPT_DOMAIN,   [__CLASS__,'invalidate'],10,2);
        add_action('update_option_'.SS_Settings::OPT_API_BASE, [__CLASS__,'invalidate'],10,2);

        // background refresh (non-blocking) when cache is getting stale
        add_action('admin_init', [__CLASS__, 'maybe_refresh_async']);
        add_action('ss_license_check', [__CLASS__, 'check_license']); // cron target
        add_action('current_screen', function ($screen) {

            if (!isset($screen->id)) return;

            // Only on SearchShifter admin pages
            if (strpos($screen->id, 'searchshifter') === false) return;

            // If license is cached as free/inactive, refresh once
            $cached = get_transient(SS_Licensing::TRANSIENT_KEY);

            if (is_array($cached) && empty($cached['active'])) {
                SS_Licensing::force_refresh();
            }
            });

        add_action('update_option_'.SS_Settings::OPT_API_KEY, function(){
            SS_Licensing::force_refresh();
        });

    }

    public static function invalidate(){ delete_transient(self::TRANSIENT_KEY); }

    public static function api_base(){
        $from_opt = rtrim((string) get_option(SS_Settings::OPT_API_BASE, ''), '/');
        if ($from_opt) return $from_opt;
        return rtrim(defined('SEARCHSHIFTER_API_BASE') ? SEARCHSHIFTER_API_BASE : '', '/');
    }

    /** Force a fresh request now (used by the "Re-check license" button) */
    public static function force_refresh(){
        delete_transient(self::TRANSIENT_KEY);
        return self::check_license();
    }

    /** Schedule a background refresh when cache is close to expiring */
    public static function maybe_refresh_async(){
        $timeout = (int) get_option('_transient_timeout_'.self::TRANSIENT_KEY, 0);
        if (!$timeout) return; // no cache yet
        if ( time() + self::REFRESH_EARLY_SEC >= $timeout ){
            if (!wp_next_scheduled('ss_license_check')) {
                wp_schedule_single_event(time()+2, 'ss_license_check');
            }
        }
    }

    /** Main check — returns a rich array, but still includes ['active','message'] for back-compat */
    public static function check_license(){
        $cached = get_transient(self::TRANSIENT_KEY);
        if (is_array($cached)) return $cached;

        $apiKey = trim((string) get_option(SS_Settings::OPT_API_KEY, ''));
        $domain = trim((string) get_option(SS_Settings::OPT_DOMAIN, wp_parse_url(get_site_url(), PHP_URL_HOST)));
        $base   = self::api_base();

        $baseRes = [
            'active'      => false,
            'read_only'   => true,
            'status'      => 'inactive',
            'plan'        => null,
            'expires_at'  => null,
            'expires'     => null, // <— alias for UI
            'reason'      => null,
            'message'     => '',
            'checked_at'  => time(),
        ];

        // if (!$apiKey || !$domain || !$base){
        //     $res = $baseRes;
        //     $res['message'] = 'Missing API base, key or domain';
        //     set_transient(self::TRANSIENT_KEY, $res, self::TTL);
        //     return $res;
        // }

        // ✅ FREE MODE — no API key is EXPECTED
        // ✅ NO API KEY YET — allow paid users to enter it
        if (!$apiKey) {

                // If we already KNOW this site is paid, do NOT fallback to free
            $knownPlan = get_option('ss_plan_type', 'free');

            if ($knownPlan !== 'free') {
                $res['active']    = false;   // 🔴 IMPORTANT
                $res['read_only'] = true;    // 🔴 IMPORTANT
                $res['status']    = 'pending_key';
                $res['plan']      = $knownPlan;
                $res['message']   = 'Enter your API key to activate your plan.';
            }


            // Otherwise truly Free
            $res = $baseRes;
            $res['active']     = true;
            $res['read_only']  = false;
            $res['status']     = 'free';
            $res['plan']       = 'free';
            $res['message']    = 'Free plan active';

            set_transient(self::TRANSIENT_KEY, $res, self::TTL);
            update_option('ss_plan_type', 'free');

            return $res;
        }


        $resp = \SS\Core\Http::postJson('license.validate', '/license/validate', [
            'domain'         => $domain,
            'plugin_version' => defined('SEARCHSHIFTER_VERSION') ? SEARCHSHIFTER_VERSION : 'unknown',
        ], ['timeout'=>12]);

        if (empty($resp['ok'])) {

            // 🔥 HARD RESET LOCAL STATE
            delete_transient(self::TRANSIENT_KEY);
            update_option('ss_plan_type', 'free');

            $res = $baseRes;
            $res['status']  = 'inactive';
            $res['plan']    = 'free';
            $res['message'] = !empty($resp['error'])
                ? $resp['error']
                : 'License not found';

            set_transient(self::TRANSIENT_KEY, $res, self::TTL);
            return $res;
        }

        
        $domainFromWp = wp_parse_url(get_site_url(), PHP_URL_HOST);

        // Extract the returned domain if your Laravel API sends it
        if (!empty($resp['json']['data']['registered_domain'])) {
            $registeredDomain = strtolower($resp['json']['data']['registered_domain']);
            $currentDomain = strtolower($domainFromWp);

            if ($registeredDomain !== $currentDomain) {
                $res = $baseRes;
                $res['message'] = 'License mismatch — this key is registered for ' . $registeredDomain;
                set_transient(self::TRANSIENT_KEY, $res, self::TTL);
                return $res;
            }
        }
        $json = is_array($resp['json'] ?? null) ? $resp['json'] : [];
        $data = is_array($json['data'] ?? null) ? $json['data'] : [];

        $status    = strtolower((string)($data['status'] ?? 'inactive'));
        $readOnly  = (bool) ($data['readOnly'] ?? true);
        // $plan      = isset($data['plan']) ? (string)$data['plan'] : null;
        // $expiresAt = isset($data['expiresAt']) ? (string)$data['expiresAt'] : null;
        // $reason    = isset($data['reason']) ? (string)$data['reason'] : null;

        $plan      = isset($data['plan']) ? (string)$data['plan'] : 'free';
        $expiresAt = isset($data['expiresAt']) ? (string)$data['expiresAt'] : null;
        $reason    = isset($data['reason']) ? (string)$data['reason'] : null;
        $features  = isset($data['features']) && is_array($data['features'])
                        ? $data['features']
                        : [];

        $active = in_array($status, ['active','trialing'], true) && !$readOnly;

        $res = $baseRes;
        $res['active']     = $active;
        $res['read_only']  = $readOnly;
        $res['status']     = $status;
        $res['plan']       = $plan;
        $res['expires_at'] = $expiresAt ?: null;
        $res['expires']    = $expiresAt ?: null; // <— alias used by UI
        $res['reason']     = $reason ?: null;

        if ($active) {
            $res['message'] = 'Valid';
        } elseif ($status === 'active' && $readOnly) {
            $res['message'] = 'Read-only mode';
        } elseif ($status === 'expired') {
            $res['message'] = 'License expired';
        } elseif ($reason) {
            $res['message'] = $reason;
        } else {
            $res['message'] = 'Inactive';
        }
        $res['features'] = $features;

        // ✅ Cache for 12 hours
        set_transient(self::TRANSIENT_KEY, $res, self::TTL);

        // ✅ Normalize and sync plan type to wp_options
        $normalizedPlan = strtolower(trim($res['plan'] ?? 'free'));
        if (!in_array($normalizedPlan, ['free','pro','authority','elite'], true)) {
            $normalizedPlan = 'free';
        }

        // If license is inactive or expired → force fallback to free
        if ($res['status'] === 'expired') {
            $normalizedPlan = 'free';
        }

        // Save to wp_options for frontend + dashboard access
        update_option('ss_plan_type', $normalizedPlan);

        // Optional debug log
        // error_log('[SS Licensing] Synced plan: ' . $normalizedPlan . ' | Status: ' . $res['status']);

        return $res;

    }


    
    public static function is_active(){
        $st = self::check_license();
        return !empty($st['active']);
    }
    public static function get_cached_status(){ return self::check_license(); }

    /** Normalize for UI badges */
    // includes/licensing.php
    // public static function ui_state() {
    //     $st   = self::get_cached_status(); // includes plan/expires/expires_at/message
    //     $msg  = isset($st['message']) ? (string)$st['message'] : '';

    //     $badge = ['class' => 'err', 'text' => 'Inactive'];
    //     if (!empty($st['active'])) {
    //         $badge = ['class' => 'ok', 'text' => 'Active'];
    //     } else {
    //         if (stripos($msg, 'expired') !== false) {
    //             $badge = ['class' => 'warn', 'text' => 'Expired'];
    //         } elseif (stripos($msg, 'read-only') !== false || stripos($msg, 'readonly') !== false) {
    //             $badge = ['class' => 'warn', 'text' => 'Read-only'];
    //         } elseif (stripos($msg, 'domain') !== false) {
    //             $badge = ['class' => 'err', 'text' => 'Domain mismatch'];
    //         }
    //     }

    //     return [
    //         'badge'   => $badge,
    //         'message' => $msg,
    //         'plan'    => $st['plan']    ?? null,
    //         'expires' => $st['expires'] ?? ($st['expires_at'] ?? null),
    //     ];
    // }

    
    public static function ui_state() {
        $st  = self::get_cached_status();
        $msg = (string) ($st['message'] ?? '');
            if (($st['status'] ?? '') === 'pending_key') {
            return [
                'badge' => [
                    'class' => 'warn',
                    'text'  => ucfirst($st['plan']) . ' (Pending API Key)',
                ],
                'message' => 'Enter your API key to activate SearchShifter.',
                'plan'    => $st['plan'],
                'expires' => null,
                'mode'    => 'paid',
            ];
        }


    
        // ✅ FREE MODE (no API key, intentional state)
        if (($st['status'] ?? '') === 'free') {
            return [
                'badge' => [
                    'class' => 'ok',
                    'text'  => 'Free (Active)',
                ],
                'message' => 'Running in Free mode with limited features.',
                'plan'    => 'free',
                'expires' => null,
                'mode'    => 'free', // 🔑 REQUIRED FOR UI
            ];
        }

        // Default
        $badge = ['class' => 'err', 'text' => 'Inactive'];

        if (!empty($st['active'])) {
            $badge = ['class' => 'ok', 'text' => 'Active'];
        } else {
            if (stripos($msg, 'expired') !== false) {
                $badge = ['class' => 'warn', 'text' => 'Expired'];
            } elseif (stripos($msg, 'read-only') !== false || stripos($msg, 'readonly') !== false) {
                $badge = ['class' => 'warn', 'text' => 'Read-only'];
            } elseif (stripos($msg, 'domain') !== false) {
                $badge = ['class' => 'err', 'text' => 'Domain mismatch'];
            }
        }

        return [
            'badge'   => $badge,
            'message' => $msg,
            'plan'    => $st['plan']    ?? null,
            'expires' => $st['expires'] ?? ($st['expires_at'] ?? null),
            'mode'    => 'paid',
        ];
    }

    public static function plan() {
    $st = self::get_cached_status();
    return $st['plan'] ?? 'free';
    }

    public static function has_feature($feature) {
        $st = self::get_cached_status();

        // Normalize features array
        $features = [];
        if (!empty($st['features'])) {
            if (is_array($st['features'])) {
                $features = $st['features'];
            } elseif (is_string($st['features'])) {
                $features = explode(',', $st['features']);
            }
        }

        // Return true if license is active AND feature exists
        if (!empty($st['active']) && in_array($feature, $features, true)) {
            return true;
        }
        return false;
    }

    public static function sync_plan_option() {
        // Get current plan from license data
        $plan = self::plan();

        // Normalize
        $allowed = ['free', 'pro', 'authority', 'elite'];
        if (!in_array($plan, $allowed, true)) {
            $plan = 'free';
        }

        // Update wp_options
        update_option('ss_plan_type', $plan);

        // Optional debug log
        // error_log("[SS Licensing] Plan synced: $plan");

        return $plan;
    }


}
