<?php

/**
 * Spellmatic_License
 *
 * Central plan / license / scan-credit management.
 * Freemius plan slugs must match what is configured in the Freemius dashboard.
 */
defined( 'ABSPATH' ) || exit;
class Spellmatic_License {
    // =========================================================================
    // Plan slug constants (must match Freemius dashboard)
    // =========================================================================
    const PLAN_FREE = 'free';

    const PLAN_SITE_SCAN = 'site_scan';

    const PLAN_THREE_PACK = 'three_pack';

    const PLAN_PRO = 'pro';

    const PLAN_AGENCY = 'agency';

    /** Credits granted on first activation per one-time plan. */
    const PLAN_CREDITS = [
        self::PLAN_SITE_SCAN  => 1,
        self::PLAN_THREE_PACK => 3,
    ];

    /** wp_options key for remaining scan credits. */
    const OPTION_CREDITS = 'spellmatic_scan_credits';

    /** Plan display data. */
    const PRICING = [];

    /** @return array Plan display data. */
    public static function get_pricing() : array {
        return [];
    }

    // =========================================================================
    // Plan detection
    // =========================================================================
    /**
     * Returns the current active plan slug.
     * Checks in priority order: agency → pro → three_pack → site_scan → free.
     */
    public static function get_plan() : string {
        $fs = self::fs();
        if ( !$fs ) {
            return self::PLAN_FREE;
        }
        // Check annual plans first (highest tier to lowest).
        foreach ( [self::PLAN_AGENCY, self::PLAN_PRO] as $plan ) {
            if ( $fs->is_plan( $plan, false ) ) {
                return $plan;
            }
        }
        // One-time credit plans.
        foreach ( [self::PLAN_THREE_PACK, self::PLAN_SITE_SCAN] as $plan ) {
            if ( $fs->is_plan( $plan, false ) ) {
                return $plan;
            }
        }
        return self::PLAN_FREE;
    }

    /** Any paid plan (annual or one-time credit). */
    public static function is_paid() : bool {
        return self::get_plan() !== self::PLAN_FREE;
    }

    /** Whether the current licence is an annual subscription plan. */
    public static function is_pro() : bool {
        $fs = self::fs();
        if ( !$fs ) {
            return false;
        }
        return $fs->is_plan( self::PLAN_PRO, false ) || $fs->is_plan( self::PLAN_AGENCY, false );
    }

    /** Whether the current licence is the top-tier plan. */
    public static function is_agency() : bool {
        $fs = self::fs();
        if ( !$fs ) {
            return false;
        }
        return $fs->is_plan( self::PLAN_AGENCY, false );
    }

    /** Whether the current licence permits AI scans. */
    public static function can_use_ai() : bool {
        return self::is_pro() || self::get_scan_credits() > 0;
    }

    // =========================================================================
    // Scan-credit system (for one-time plans)
    // =========================================================================
    /** Remaining scan credits (null = unlimited, 0 = none, int = remaining). */
    public static function get_scan_credits() : ?int {
        if ( self::is_pro() ) {
            return null;
        }
        $plan = self::get_plan();
        if ( $plan === self::PLAN_FREE ) {
            return 0;
        }
        // Credits have never been initialised for this plan — seed from constant.
        if ( false === ($stored = get_option( self::OPTION_CREDITS, false )) ) {
            $initial = self::PLAN_CREDITS[$plan] ?? 0;
            update_option( self::OPTION_CREDITS, $initial, false );
            return $initial;
        }
        return max( 0, (int) $stored );
    }

    /**
     * Consume one scan credit after a successful full scan.
     * Returns remaining credits (null = unlimited; 0+ = credits remaining).
     */
    public static function consume_scan_credit() : ?int {
        if ( self::is_pro() ) {
            return null;
        }
        $current = self::get_scan_credits();
        if ( $current === 0 ) {
            return 0;
        }
        $new = max( 0, $current - 1 );
        update_option( self::OPTION_CREDITS, $new, false );
        return $new;
    }

    /**
     * Add scan credits — called by the Freemius after-purchase hook when a
     * new site_scan or three_pack licence is activated.
     */
    public static function add_scan_credits( int $count ) : int {
        $current = (int) get_option( self::OPTION_CREDITS, 0 );
        $new = $current + $count;
        update_option( self::OPTION_CREDITS, $new, false );
        return $new;
    }

    /** Reset credits to zero (e.g. on plan downgrade). */
    public static function reset_scan_credits() : void {
        delete_option( self::OPTION_CREDITS );
    }

    // =========================================================================
    // Plan info helpers (for UI)
    // =========================================================================
    /**
     * Human-readable plan label.
     */
    public static function get_plan_label() : string {
        $plan = self::get_plan();
        $pricing = self::get_pricing();
        return $pricing[$plan]['label'] ?? ucfirst( $plan );
    }

    /** Plan management URL. */
    public static function get_upgrade_url() : string {
        return '';
    }

    /** Checkout URL for a specific plan. */
    public static function get_checkout_url( string $plan ) : string {
        return '';
    }

    /** Account management URL. */
    public static function get_account_url() : string {
        return '';
    }

    // =========================================================================
    // Freemius lifecycle hooks
    // =========================================================================
    /** Register Freemius lifecycle hooks (called after SDK init). */
    public static function register_fs_hooks() : void {
        $fs = self::fs();
        if ( !$fs ) {
            return;
        }
        // Grant scan credits when a one-time plan is purchased / activated.
        $fs->add_action( 'after_purchase_action', function ( $plan, $package ) {
            if ( !is_object( $plan ) ) {
                return;
            }
            $slug = $plan->name ?? '';
            $credits = self::PLAN_CREDITS[$slug] ?? 0;
            if ( $credits > 0 ) {
                self::add_scan_credits( $credits );
            }
        } );
        // Reset credits if the user switches back to free.
        $fs->add_action( 'after_plan_downgrade_action', function () {
            self::reset_scan_credits();
        } );
    }

    // =========================================================================
    // Feature restriction helper
    // =========================================================================
    /** Whether features should be restricted for the current licence. */
    public static function has_feature_restrictions() : bool {
        return false;
    }

    // =========================================================================
    // Internal helpers
    // =========================================================================
    // =========================================================================
    // Internal helpers
    // =========================================================================
    private static function fs() : ?object {
        if ( function_exists( 'spellmatic_fs' ) ) {
            return ( spellmatic_fs() ?: null );
        }
        return null;
    }

}
