<?php
/**
 * License Manager for BoostBot.
 *
 * @package BoostBot
 */

// Prevent direct access to the file.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if (!defined('ABSPATH')) {
    exit;
}

/**
 * BoostBot_License_Manager class.
 *
 * Manages license status, feature gating, and subscription handling.
 *
 * @since 1.0.0
 */
class BoostBot_License_Manager
{
    /**
     * License status constants.
     */
    const LICENSE_FREE        = 'free';
    const LICENSE_PRO         = 'pro';
    const LICENSE_PRO_BUNDLES = 'pro_bundles'; // Pro + Bundle Builder
    const LICENSE_EXPIRED     = 'expired';

    /**
     * PayPal payment link.
     *
     * @since 1.0.0
     * @access public static
     * @var string
     */
    public static $paypal_link = 'https://paypal.me/boostmedialtd';

    /**
     * Monthly price in USD.
     *
     * @since 1.0.0
     * @access public static
     * @var int
     */
    public static $monthly_price = 20;

    /**
     * Pricing (BYOK model - customer pays Anthropic directly for API).
     * Prices are loaded from constants if defined, otherwise use defaults.
     *
     * @since 1.0.0
     * @access public static
     * @var int
     */
    public static $price_pro = 20;           // $20/month (base)
    public static $price_pro_bundles = 40;  // $40/month (Pro + Bundles)

    /**
     * Available add-ons with their prices.
     *
     * @since 1.0.0
     * @access public static
     * @var array
     */
    public static $addons = [
        'bundles' => [
            'id' => 'bundles',
            'name' => 'AI Bundle Builder',
            'price' => 20,
            'features' => ['bundle_builder', 'dynamic_pricing', 'ai_recommendations'],
        ],
        // Future add-ons can be added here
    ];

    /**
     * Get pricing from constants.
     *
     * @since 1.0.0
     * @return array Pricing data.
     */
    public static function get_pricing(): array
    {
        $base_price = defined('BOOSTBOT_PRICE_BASE_PRO') ? BOOSTBOT_PRICE_BASE_PRO : self::$price_pro;
        
        $addons = [];
        foreach (self::$addons as $id => $addon) {
            $const_name = 'BOOSTBOT_ADDON_PRICE_' . strtoupper($id);
            $addons[$id] = [
                'id' => $id,
                'name' => $addon['name'],
                'price' => defined($const_name) ? constant($const_name) : $addon['price'],
                'features' => $addon['features'],
            ];
        }

        return [
            'base' => $base_price,
            'pro' => $base_price,
            'pro_bundles' => $base_price + ($addons['bundles']['price'] ?? 20),
            'addons' => $addons,
        ];
    }

    /**
     * Calculate total price based on selected add-ons.
     *
     * @since 1.0.0
     * @param array $addon_ids Selected add-on IDs.
     * @return int Total monthly price.
     */
    public static function calculate_price(array $addon_ids = []): int
    {
        $pricing = self::get_pricing();
        $total = $pricing['base'];

        foreach ($addon_ids as $addon_id) {
            if (isset($pricing['addons'][$addon_id])) {
                $total += $pricing['addons'][$addon_id]['price'];
            }
        }

        return $total;
    }

    /**
     * Pro-only features.
     *
     * @since 1.0.0
     * @access private
     * @var array
     */
    private $pro_features = [
        'all_pages',          // Chat on all pages (not just homepage)
        'widgets',            // Interactive widgets
        'woocommerce',        // WooCommerce integration
        'analytics',          // Analytics & reports
        'leads_management',   // Full leads management
        'knowledge_base',     // Advanced RAG
        'triggers',           // Smart triggers
        'webhooks',           // Webhooks
        'advanced_styling',   // Advanced customization
        'export',             // Data export
    ];

    /**
     * Free features.
     *
     * @since 1.0.0
     * @access private
     * @var array
     */
    private $free_features = [
        'homepage_chat',    // Chat only on homepage
        'basic_settings',   // Basic settings
        'claude_api_key',   // Enter Claude API key
        'basic_leads',      // View leads (limited)
    ];

    /**
     * Get the current license status.
     *
     * @since 1.0.0
     * @return string License status (free, pro, pro_bundles, expired).
     */
    public function get_license_status()
    {
        // Legacy subscription licensing is deprecated.
        // Default behavior is "Pro unlocked" for all sites.
        return self::LICENSE_PRO;
    }

    /**
     * Check if a specific feature is enabled.
     *
     * @since 1.0.0
     * @param string $feature Feature key.
     * @return bool True if feature is enabled.
     */
    public function is_feature_enabled($feature)
    {
        // Legacy subscription licensing is deprecated; all features are enabled.
        return true;
    }

    /**
     * Check if dev mode is enabled.
     *
     * ⚠️ DEV ONLY: Remove before production! See WEEK_12.md
     *
     * @since 1.0.0
     * @return bool True if dev mode is enabled.
     */
    public function is_dev_mode()
    {
        // Dev mode has been removed; Pro is the default.
        return false;
    }

    /**
     * Dev-mode is allowed only when explicitly enabled for local debugging.
     *
     * @return bool
     */
    private static function is_dev_mode_allowed(): bool
    {
        return ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'BOOSTBOT_ALLOW_DEV_MODE' ) && BOOSTBOT_ALLOW_DEV_MODE );
    }

    /**
     * Toggle dev mode (Pro features for development).
     *
     * ⚠️ DEV ONLY: Remove before production! See WEEK_12.md
     *
     * @since 1.0.0
     * @param bool $enabled Enable or disable dev mode.
     * @return bool The new state.
     */
    public function set_dev_mode($enabled)
    {
        // Dev mode has been removed; keep method for backward compatibility.
        BoostBot_Logger::warning( 'Dev mode toggle requested but dev mode is deprecated', [ 'requested' => (bool) $enabled ] );
        return false;
    }

    /**
     * Get list of disabled features for current license.
     *
     * @since 1.0.0
     * @return array Disabled feature keys.
     */
    public function get_disabled_features()
    {
        return [];
    }

    /**
     * Get list of enabled features for current license.
     *
     * @since 1.0.0
     * @return array Enabled feature keys.
     */
    public function get_enabled_features()
    {
        return array_merge($this->free_features, $this->pro_features);
    }

    /**
     * Activate Pro license.
     *
     * @since 1.0.0
     * @param string $subscription_id PayPal subscription ID.
     * @param string $payer_email     Payer's email address.
     * @param int    $months          Number of months (default: 1).
     * @param string $plan_type       Plan type: 'pro' or 'pro_bundles' (default: 'pro').
     * @return bool True on success.
     */
    public function activate_pro($subscription_id, $payer_email, $months = 1, $plan_type = 'pro')
    {
        $expires = time() + ($months * 30 * 24 * 60 * 60); // months in seconds
        $license_status = ($plan_type === 'pro_bundles') ? self::LICENSE_PRO_BUNDLES : self::LICENSE_PRO;

        $license = [
            'status'         => $license_status,
            'subscription_id' => $subscription_id,
            'payer_email'    => $payer_email,
            'activated_at'   => time(),
            'expires_at'     => $expires,
        ];

        update_option('boostbot_license', $license);
        update_option('boostbot_license_status', $license_status); // Backward compatibility
        update_option('boostbot_subscription_id', sanitize_text_field($subscription_id));
        update_option('boostbot_payer_email', sanitize_email($payer_email));
        update_option('boostbot_subscription_start', current_time('mysql'));
        update_option('boostbot_settings_frozen', false);

        // Save subscription details
        $subscription = [
            'id'               => $subscription_id,
            'status'           => 'active',
            'payer_email'      => $payer_email,
            'start_date'       => current_time('mysql'),
            'next_billing_date' => gmdate('Y-m-d', $expires),
        ];

        update_option('boostbot_subscription', $subscription);

        // Store in license table
        $this->save_license_record([
            'license_status'     => $license_status,
            'subscription_id'    => $subscription_id,
            'payer_email'        => $payer_email,
            'subscription_start' => current_time('mysql'),
        ]);

        // Send welcome email
        $this->send_welcome_email($payer_email);

        // Log activation
        BoostBot_Logger::info('Pro license activated', [
            'subscription_id' => $subscription_id,
            'payer_email'     => $payer_email,
            'plan_type'      => $plan_type,
        ]);

        // Fire action for other components
        do_action('boostbot_license_activated', $subscription_id, $payer_email);

        return true;
    }

    /**
     * Extend Pro subscription (on payment).
     *
     * @since 1.0.0
     * @param int $months Number of months to extend (default: 1).
     * @return void
     */
    public function extend_pro($months = 1)
    {
        $license = get_option('boostbot_license', []);

        if (empty($license)) {
            return;
        }

        // Extend from current expiry or now
        $current_expires = max($license['expires_at'] ?? time(), time());
        $new_expires = $current_expires + ($months * 30 * 24 * 60 * 60);

        $license['expires_at'] = $new_expires;
        $license['status'] = $license['status'] ?? self::LICENSE_PRO;

        update_option('boostbot_license', $license);

        // Update subscription next billing
        $subscription = get_option('boostbot_subscription', []);
        $subscription['next_billing_date'] = gmdate('Y-m-d', $new_expires);
        update_option('boostbot_subscription', $subscription);
    }

    /**
     * Deactivate subscription (expired or cancelled).
     *
     * @since 1.0.0
     * @return bool True on success.
     */
    public function deactivate_subscription()
    {
        $old_status = get_option('boostbot_license_status');

        // Keep expiry but mark as cancelled
        $subscription = get_option('boostbot_subscription', []);
        $subscription['status'] = 'cancelled';
        $subscription['cancelled_at'] = current_time('mysql');
        update_option('boostbot_subscription', $subscription);

        // Don't immediately expire - let them use until end of period
        // update_option('boostbot_license_status', self::LICENSE_EXPIRED);
        // update_option('boostbot_settings_frozen', true);
        // update_option('boostbot_subscription_end', current_time('mysql'));

        // Update license record
        // $this->update_license_record([
        //     'license_status'   => self::LICENSE_EXPIRED,
        //     'subscription_end' => current_time('mysql'),
        //     'settings_frozen'  => true,
        // ]);

        BoostBot_Logger::info('Subscription cancelled', [
            'subscription_id' => $subscription['id'] ?? '',
        ]);

        do_action('boostbot_license_deactivated');

        return true;
    }

    /**
     * Reactivate subscription (after payment renewal).
     *
     * @since 1.0.0
     * @return bool True on success.
     */
    public function reactivate_subscription()
    {
        update_option('boostbot_license_status', self::LICENSE_PRO);
        update_option('boostbot_settings_frozen', false);

        // Update license record
        $this->update_license_record([
            'license_status'  => self::LICENSE_PRO,
            'last_payment'    => current_time('mysql'),
            'settings_frozen' => false,
        ]);

        BoostBot_Logger::info('License reactivated');

        do_action('boostbot_license_reactivated');

        return true;
    }

    /**
     * Check if settings are frozen (expired license).
     *
     * @since 1.0.0
     * @return bool True if frozen.
     */
    public function are_settings_frozen()
    {
        // Legacy subscription licensing is deprecated; settings are never frozen.
        return false;
    }

    /**
     * Get upgrade URL.
     *
     * @since 1.0.0
     * @return string PayPal upgrade URL.
     */
    public function get_upgrade_url()
    {
        // Legacy subscription licensing is deprecated.
        return '';
    }

    /**
     * Get subscription info.
     *
     * @since 1.0.0
     * @return array Subscription information.
     */
    public function get_subscription_info()
    {
        return [
            'status'             => $this->get_license_status(),
            'subscription_id'    => get_option('boostbot_subscription_id', ''),
            'payer_email'        => get_option('boostbot_payer_email', ''),
            'subscription_start' => get_option('boostbot_subscription_start', ''),
            'subscription_end'   => get_option('boostbot_subscription_end', ''),
            'settings_frozen'    => $this->are_settings_frozen(),
        ];
    }

    /**
     * Verify subscription is still active.
     *
     * @since 1.0.0
     * @return bool True if active.
     */
    public function verify_subscription()
    {
        // Check if subscription ID exists
        $subscription_id = get_option('boostbot_subscription_id', '');
        if (empty($subscription_id)) {
            return false;
        }

        // Check last payment date
        $last_payment = get_option('boostbot_last_payment', '');
        if (!empty($last_payment)) {
            $last_payment_time = strtotime($last_payment);
            $expiry_time = $last_payment_time + (35 * DAY_IN_SECONDS); // 35 days grace period

            if (time() > $expiry_time) {
                return false;
            }
        }

        // For manual verification, check if marked as active
        $manual_active = get_option('boostbot_subscription_active', false);
        if ($manual_active) {
            return true;
        }

        // In production, this would call PayPal API to verify
        // For now, trust the stored status
        return get_option('boostbot_license_status') === self::LICENSE_PRO;
    }

    /**
     * Handle expired subscription.
     *
     * @since 1.0.0
     */
    private function handle_expired_subscription()
    {
        // Only process once
        if (get_option('boostbot_license_status') === self::LICENSE_EXPIRED) {
            return;
        }

        $this->deactivate_subscription();

        // Send notification email
        $this->send_expiry_notification();
    }

    /**
     * Send expiry notification email.
     *
     * @since 1.0.0
     */
    private function send_expiry_notification()
    {
        $admin_email = get_option('admin_email');
        $payer_email = get_option('boostbot_payer_email', '');
        $site_name = get_bloginfo('name');

        $subject = sprintf(
            /* translators: %s: site name */
            __('[%s] מנוי BoostBot Pro פג תוקף', 'boostbot'),
            $site_name
        );

        $message = sprintf(
            /* translators: 1: site name, 2: upgrade URL */
            __(
                'שלום,

מנוי BoostBot Pro עבור האתר %1$s פג תוקף.

ההגדרות שלך הוקפאו. הצ\'אטבוט ימשיך לפעול בגרסה החינמית (רק בדף הבית).

לחידוש המנוי:
%2$s

צוות BoostBot',
                'boostbot'
            ),
            $site_name,
            $this->get_upgrade_url()
        );

        wp_mail($admin_email, $subject, $message);

        // Also notify payer if different
        if (!empty($payer_email) && $payer_email !== $admin_email) {
            wp_mail($payer_email, $subject, $message);
        }

        BoostBot_Logger::info('Expiry notification sent', [
            'admin_email' => $admin_email,
            'payer_email' => $payer_email,
        ]);
    }

    /**
     * Save license record to database.
     *
     * @since 1.0.0
     * @param array $data License data.
     */
    private function save_license_record($data)
    {
        global $wpdb;
        $table = self::sanitize_identifier( $wpdb->prefix . 'boostbot_license' );

        // Check if record exists
        $existing = $wpdb->get_var("SELECT id FROM {$table} LIMIT 1"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().

        if ($existing) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().
            $wpdb->update($table, $data, ['id' => $existing]);
        } else {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().
            $wpdb->insert($table, $data);
        }
    }

    /**
     * Update license record in database.
     *
     * @since 1.0.0
     * @param array $data Data to update.
     */
    private function update_license_record($data)
    {
        global $wpdb;
        $table = self::sanitize_identifier( $wpdb->prefix . 'boostbot_license' );

        $existing = $wpdb->get_var("SELECT id FROM {$table} LIMIT 1"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().

        if ($existing) {
            $data['updated_at'] = current_time('mysql');
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table identifier sanitized via sanitize_identifier(); values bind via prepare().
            $wpdb->update($table, $data, ['id' => $existing]);
        }
    }

    /**
     * Record payment in history.
     *
     * @since 1.0.0
     * @param array $payment_data Payment data from PayPal.
     */
    public function record_payment($payment_data)
    {
        // Update options
        update_option('boostbot_last_payment', current_time('mysql'));

        // Calculate next payment date (monthly)
        $next_payment = gmdate('Y-m-d H:i:s', strtotime('+1 month'));
        update_option('boostbot_next_payment', $next_payment);

        // Add to payment history (old format for backward compatibility)
        $history = get_option('boostbot_payment_history', []);
        $history[] = [
            'date'            => current_time('mysql'),
            'amount'          => $payment_data['amount'] ?? self::$monthly_price,
            'currency'        => $payment_data['currency'] ?? 'USD',
            'transaction_id'  => $payment_data['transaction_id'] ?? '',
            'subscription_id' => $payment_data['subscription_id'] ?? '',
        ];

        // Keep last 24 months
        if (count($history) > 24) {
            array_shift($history);
        }

        update_option('boostbot_payment_history', $history);

        // Also save to new payments format
        $payments = get_option('boostbot_payments', []);
        $payments[] = [
            'transaction_id' => $payment_data['transaction_id'] ?? '',
            'amount'        => $payment_data['amount'] ?? self::$monthly_price,
            'currency'      => $payment_data['currency'] ?? 'USD',
            'status'        => $payment_data['status'] ?? 'completed',
            'date'          => current_time('mysql'),
            'payer_email'   => $payment_data['payer_email'] ?? '',
        ];

        // Keep last 50 payments
        $payments = array_slice($payments, -50);
        update_option('boostbot_payments', $payments);

        // Update license record
        $this->update_license_record([
            'last_payment' => current_time('mysql'),
            'next_payment' => $next_payment,
            'amount'       => $payment_data['amount'] ?? self::$monthly_price,
        ]);

        BoostBot_Logger::info('Payment recorded', [
            'amount'         => $payment_data['amount'] ?? self::$monthly_price,
            'transaction_id' => $payment_data['transaction_id'] ?? '',
        ]);
    }

    /**
     * Get payment history.
     *
     * @since 1.0.0
     * @param int $limit Number of records to return.
     * @return array Payment history.
     */
    public function get_payment_history($limit = 12)
    {
        $history = get_option('boostbot_payment_history', []);
        return array_slice(array_reverse($history), 0, $limit);
    }

    /**
     * Get payments (alias for get_payment_history).
     *
     * @since 1.0.0
     * @return array Payment history.
     */
    public function get_payments()
    {
        return get_option('boostbot_payments', []);
    }

    /**
     * Get subscription details.
     *
     * @since 1.0.0
     * @return array Subscription details.
     */
    public function get_subscription()
    {
        return get_option('boostbot_subscription', []);
    }

    /**
     * Send welcome email.
     *
     * @since 1.0.0
     * @param string $email Email address.
     * @return void
     */
    private function send_welcome_email($email)
    {
        $subject = '🎉 ברוך הבא ל-BoostBot Pro!';

        $message = "
שלום,

תודה שבחרת לשדרג ל-BoostBot Pro!

מה הלאה?
- כל הפיצ'רים פתוחים לך
- הפעל את הצ'אטבוט בכל עמודי האתר
- צור Widgets אינטראקטיביים
- עקוב אחרי הלידים שלך

יש שאלות? צור קשר: office@boost-media.co.il

צוות BoostBot
        ";

        wp_mail($email, $subject, $message);
    }

    /**
     * Check if user has Pro license (Pro or Pro+Bundles).
     *
     * @since 1.0.0
     * @return bool True if Pro or Pro+Bundles.
     */
    public function is_pro()
    {
        return true;
    }

    /**
     * Check if user has Bundle Builder addon.
     *
     * @since 1.0.0
     * @return bool True if Pro+Bundles or dev mode.
     */
    public function has_bundles()
    {
        // Legacy add-on gating is deprecated; Bundle Builder is always enabled.
        return true;
    }

    /**
     * Render upgrade button HTML.
     *
     * @since 1.0.0
     * @param string $text Optional button text.
     * @return string Button HTML.
     */
    public function render_upgrade_button($text = '')
    {
        if (empty($text)) {
            $text = sprintf(
                /* translators: %d: monthly price */
                __('שדרג ל-Pro - $%d/חודש', 'boostbot'),
                self::$monthly_price
            );
        }

        return sprintf(
            '<a href="%s" target="_blank" class="boostbot-upgrade-btn">
                <span class="dashicons dashicons-star-filled"></span>
                %s
            </a>',
            esc_url($this->get_upgrade_url()),
            esc_html($text)
        );
    }

    /**
     * Restrict a SQL identifier to [A-Za-z0-9_] characters.
     *
     * DDL cannot use $wpdb->prepare() for identifiers, so any identifier
     * that ends up interpolated into a query first passes through this
     * allow-list.
     *
     * @param string $identifier Raw identifier.
     * @return string Identifier with disallowed characters removed.
     */
    private static function sanitize_identifier( $identifier ) {
        return preg_replace( '/[^A-Za-z0-9_]/', '', (string) $identifier );
    }
}



