<?php

namespace FSPoster\App\Providers\License;

use FSPoster\App\Providers\Core\Settings;

class PlanFeatures
{
    private const SOCIAL_NETWORK_PREFIX = 'sn.';

    /**
     * @var array<string, bool>|null
     */
    private static ?array $socialNetworkMap = null;

    /**
     * @var array<string, bool>|null
     */
    private static ?array $channelTypeMap = null;

    /**
     * @var array<string, bool>|null
     */
    private static ?array $methodMap = null;

    /**
     * @var array<string, int>|null
     */
    private static ?array $featureLimitMap = null;

    public static function isSocialNetworkAllowed(string $slug): bool
    {
        self::loadMaps();

        return self::$socialNetworkMap[ "sn.{$slug}" ] ?? true;
    }

    public static function isSocialNetworkChannelTypeAllowed(string $networkSlug, string $channelType): bool
    {
        self::loadMaps();

        return self::$channelTypeMap[ "sn.{$networkSlug}.channel.{$channelType}" ] ?? true;
    }

    public static function isSocialNetworkMethodAllowed(string $networkSlug, string $method): bool
    {
        self::loadMaps();

        return self::$methodMap[ "sn.{$networkSlug}.method.{$method}" ] ?? true;
    }

    public static function isFeatureAllowed(string $slug): bool
    {
        self::loadMaps();

        return (self::$featureLimitMap[ $slug ] ?? 1) > 0;
    }

    /**
     * Returns the integer limit for a given feature slug, or null if not set.
     */
    public static function getFeatureLimit(string $slug): ?int
    {
        self::loadMaps();

        return self::$featureLimitMap[ $slug ] ?? null;
    }

    /**
     * Removes channels whose (social_network, channel_type) pair is disabled by the current plan.
     * Entries missing social_network or channel_type are kept untouched.
     *
     * @param array<int, array<string, mixed>> $channels
     * @return array<int, array<string, mixed>>
     */
    public static function filterAllowedChannels(array $channels): array
    {
        $filtered = [];

        foreach ($channels as $channel) {
            $networkSlug = $channel[ 'social_network' ] ?? null;
            $channelType = $channel[ 'channel_type' ] ?? null;

            if (! is_string($networkSlug) || ! is_string($channelType)) {
                $filtered[] = $channel;
                continue;
            }

            if (self::isSocialNetworkChannelTypeAllowed($networkSlug, $channelType)) {
                $filtered[] = $channel;
            }
        }

        return $filtered;
    }

    private static function loadMaps(): void
    {
        if (self::$socialNetworkMap !== null) {
            return;
        }

        $features       = Settings::get('plan_features', []);
        $socialNetworks = [];
        $channelTypes   = [];
        $methods        = [];
        $featureLimits  = [];

        if (is_array($features)) {
            foreach ($features as $feature) {
                if (! is_array($feature) || ! isset($feature[ 'slug' ])) {
                    continue;
                }

                $featureSlug = (string) $feature[ 'slug' ];

                if (strpos($featureSlug, self::SOCIAL_NETWORK_PREFIX) !== 0) {
                    $featureLimits[ $featureSlug ] = (int) ($feature[ 'value' ] ?? 0);
                    continue;
                }

                $isAllowed = (int) ($feature[ 'value' ] ?? 0) === 1;

                if (preg_match('/^sn\.([^.]+)\.channel\.(.+)$/', $featureSlug, $_)) {
                    $channelTypes[ $featureSlug ] = $isAllowed;
                } elseif (preg_match('/^sn\.([^.]+)\.method\.(.+)$/', $featureSlug, $_)) {
                    $methods[ $featureSlug ] = $isAllowed;
                } elseif (preg_match('/^sn\.([^.]+)$/', $featureSlug, $_)) {
                    $socialNetworks[ $featureSlug ] = $isAllowed;
                }
            }
        }

        self::$socialNetworkMap = $socialNetworks;
        self::$channelTypeMap   = $channelTypes;
        self::$methodMap        = $methods;
        self::$featureLimitMap  = $featureLimits;
    }
}
