<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ -- NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-plan-enforcer.php
// Description: Plan limit enforcement -- reconciles active modules on plan changes - NUCLEAR+++
// Last Edited: 2026-05-03
// ==================================================
namespace AutoMarketerAI;

if (!defined('ABSPATH')) {
    exit;
}

class PlanEnforcer
{
    // Modules that are always free and never count toward any slot cap
    private const CORE_MODULES = ['facebook', 'instagram'];

    // Premium-only module IDs -- populated as premium modules are built
    private const PREMIUM_MODULES = [];

    // Starter plan: max non-core, non-AI, non-image modules
    private const STARTER_SLOT_LIMIT = 5;

    // Plans eligible for premium modules
    private const PREMIUM_PLANS = ['unlimited_ai', 'agency'];

    // Plans eligible for Starter slot pool
    private const STARTER_PLANS = ['starter', 'starter_pro', 'unlimited_ai', 'agency'];

    // Called after every plan change. New plan slug is passed in.
    public static function reconcile(string $new_plan): void
    {
        $active = (array) get_option('amai_active_modules', []);

        if ($new_plan === 'free') {
            self::reconcileFree($active);
            return;
        }

        if ($new_plan === 'starter' || $new_plan === 'starter_pro') {
            self::reconcileStarter($active, $new_plan);
            return;
        }

        // Upgrade to Unlimited AI or Agency -- clear any over-limit flag
        delete_option('amai_module_over_limit');
    }

    // Free plan: keep only 1 ai-*, 1 img-*, facebook, instagram
    private static function reconcileFree(array $active): void
    {
        $keep      = [];
        $ai_kept   = false;
        $img_kept  = false;

        foreach ($active as $id) {
            if (!is_string($id)) {
                continue;
            }
            if (in_array($id, self::CORE_MODULES, true)) {
                $keep[] = $id;
                continue;
            }
            if (str_starts_with($id, 'ai-') && !$ai_kept) {
                $keep[]  = $id;
                $ai_kept = true;
                continue;
            }
            if (str_starts_with($id, 'img-') && !$img_kept) {
                $keep[]   = $id;
                $img_kept = true;
                continue;
            }
        }

        update_option('amai_active_modules', array_values($keep));
        delete_option('amai_module_over_limit');
    }

    // Starter/Starter Pro: flag over-limit if more than STARTER_SLOT_LIMIT slot modules active
    private static function reconcileStarter(array $active, string $new_plan): void
    {
        // Remove any premium modules -- Starter cannot have them
        $without_premium = array_values(array_filter($active, function(mixed $id): bool {
            return is_string($id) && !in_array($id, self::PREMIUM_MODULES, true);
        }));

        if ($without_premium !== $active) {
            update_option('amai_active_modules', $without_premium);
            $active = $without_premium;
        }

        $slot_count = self::countSlotModules($active);

        if ($slot_count > self::STARTER_SLOT_LIMIT) {
            update_option('amai_module_over_limit', $slot_count - self::STARTER_SLOT_LIMIT);
        } else {
            delete_option('amai_module_over_limit');
        }
    }

    // Count modules that use a Starter slot (excludes core, ai-*, img-*)
    public static function countSlotModules(array $active): int
    {
        $count = 0;
        foreach ($active as $id) {
            if (!is_string($id)) {
                continue;
            }
            if (in_array($id, self::CORE_MODULES, true)) {
                continue;
            }
            if (str_starts_with($id, 'ai-') || str_starts_with($id, 'img-')) {
                continue;
            }
            $count++;
        }
        return $count;
    }

    // Returns true if the given module ID is a premium module
    public static function isPremium(string $module_id): bool
    {
        return in_array($module_id, self::PREMIUM_MODULES, true);
    }

    // Returns true if adding this module would exceed the Starter slot cap
    public static function starterSlotsFull(array $active): bool
    {
        return self::countSlotModules($active) >= self::STARTER_SLOT_LIMIT;
    }
}