<?php

namespace FSPoster\App\Providers\SocialNetwork;

use FSPoster\App\Providers\Core\Request;
use FSPoster\App\Providers\License\PlanFeatures;

class SocialNetworkAddon
{
    private static $socialNetworks = [];

    protected $name;
    protected $icon;
    protected $slug;
    protected $sort;

    public function getName()
    {
        return $this->name;
    }

    public function getIcon()
    {
        return $this->icon;
    }

    public function getSlug()
    {
        return $this->slug;
    }

    public function getSort()
    {
        return $this->sort;
    }

    public function getCallbackUrl(): ?string
    {
        return self_admin_url('admin.php?fs-poster-callback=true');
    }

    public function checkIsCallbackRequest(): bool
    {
        $callbackParameter = Request::get('fs-poster-callback', '', 'string', ['true']);

        return ! empty($callbackParameter);
    }

    public static function register()
    {
        $newSN = new static();

        if (! PlanFeatures::isSocialNetworkAllowed($newSN->getSlug())) {
            return;
        }

        if (method_exists($newSN, 'init')) {
            $newSN->init();
        }

        self::$socialNetworks[ $newSN->getSlug() ] = $newSN;
    }

    /**
     * Registers auth-method-specific routes/hooks only when the current plan allows the method.
     * Shared (non-method-specific) code in init() should stay outside this helper.
     */
    protected function initMethod(string $method, \Closure $register): void
    {
        if (! PlanFeatures::isSocialNetworkMethodAllowed($this->getSlug(), $method)) {
            return;
        }

        $register();
    }

    /**
     * Registers hooks that are multiplexed across multiple auth methods (e.g., a single handler
     * serves both "app" and "instagram_app"). Skips registration only when ALL listed methods are
     * blocked. Per-method distinction inside such a handler must be enforced with an inline
     * PlanFeatures::isSocialNetworkMethodAllowed() check.
     *
     * @param array<int, string> $methods
     */
    protected function initMethodAny(array $methods, \Closure $register): void
    {
        foreach ($methods as $method) {
            if (PlanFeatures::isSocialNetworkMethodAllowed($this->getSlug(), $method)) {
                $register();

                return;
            }
        }
    }

    /**
     * @return SocialNetworkAddon[]
     */
    public static function getSocialNetworks()
    {
        uasort(self::$socialNetworks, function ($a, $b) {
            if ($a->getSort() == $b->getSort()) {
                return 0;
            }

            return ($a->getSort() < $b->getSort()) ? -1 : 1;
        });

        return self::$socialNetworks;
    }

    public static function getActiveSocialNetworks(array $savedSettings = []): array
    {
        $allNetworks = self::getSocialNetworks();
        $result = [];

        foreach ($allNetworks as $slug => $network) {
            $result[$slug] = $savedSettings[$slug] ?? true;
        }

        return $result;
    }

    /**
     * @param $networkSlug
     * @return SocialNetworkAddon
     */
    public static function getNetwork($networkSlug)
    {
        return self::$socialNetworks[$networkSlug] ?? (new self());
    }

    public static function getNetworkName($networkSlug)
    {
        $network = self::getNetwork($networkSlug);

        return $network ? $network->getName() : $networkSlug;
    }

    public static function getInstance()
    {
        $ins = new static();
        $slug = $ins->getSlug();
        unset($ins);

        return self::getNetwork($slug);
    }
}
