<?php

namespace GriffinForms\Includes\Ai;

/**
 * AiAvailabilityState
 *
 * Resolves the current availability state of Griffin Assist based on
 * whether the OpenAI integration is configured and active.
 *
 * Returns one of three canonical states:
 *   - 'active'                — key saved and integration is live
 *   - 'configuration_required' — integration present but no key saved
 *   - 'inactive'              — integration disabled or unavailable
 *
 * @since 3.0.1.0
 */
class AiAvailabilityState
{
    const STATE_ACTIVE                 = 'active';
    const STATE_PROVIDER_MISSING       = 'provider_missing';
    const STATE_CONFIGURATION_REQUIRED = 'configuration_required';
    const STATE_INACTIVE               = 'inactive';

    protected $settings;
    protected $providers;

    public function __construct()
    {
        $this->settings = \GriffinForms\Settings::getInstance();
        $this->providers = \GriffinForms\Includes\Integrations\Providers::getInstance();
    }

    /**
     * Resolve and return the current state string.
     *
     * @return string One of the STATE_* constants.
     */
    public function resolve(): string
    {
        $provider_id = $this->getSelectedProviderId();

        if ($provider_id === '') {
            return self::STATE_PROVIDER_MISSING;
        }

        $integration = $this->providers->getIntegration($provider_id);
        if (!$integration) {
            return self::STATE_INACTIVE;
        }

        if (method_exists($integration, 'isConfigured') && $integration->isConfigured()) {
            return self::STATE_ACTIVE;
        }

        return self::STATE_CONFIGURATION_REQUIRED;
    }

    public function getSelectedProviderId(): string
    {
        $provider_id = sanitize_key((string) $this->settings->getOption('butler_active_provider', ''));
        if ($provider_id === '') {
            $provider_id = sanitize_key((string) $this->settings->getOption('ai_provider', ''));
        }

        return $provider_id;
    }

    public function isProviderMapped(): bool
    {
        return $this->getSelectedProviderId() !== '';
    }

    /**
     * Returns GriffinForms provider IDs that have a key available via WP7 Connectors
     * but are not already the active provider. Empty array on WP6 or when none found.
     *
     * @return array  e.g. ['openai'], ['anthropic', 'gemini'], or []
     */
    public function getAvailableConnectorProviders(): array
    {
        if (!function_exists('wp_get_connector')) {
            return [];
        }

        $active = $this->getSelectedProviderId();

        $map = [
            'openai'    => 'openai',
            'anthropic' => 'anthropic',
            'google'    => 'gemini',
        ];

        $available = [];

        foreach ($map as $connector_id => $provider_id) {
            if ($provider_id === $active) {
                continue;
            }

            $connector = wp_get_connector($connector_id);
            if (!$connector || empty($connector['authentication']['setting_name'])) {
                continue;
            }

            $auth = $connector['authentication'];
            $key  = '';

            if (!empty($auth['env_var_name'])) {
                $env = getenv($auth['env_var_name']);
                if (false !== $env && '' !== $env) {
                    $key = $env;
                }
            }

            if ($key === '' && !empty($auth['constant_name']) && defined($auth['constant_name'])) {
                $const = constant($auth['constant_name']);
                if (is_string($const) && '' !== $const) {
                    $key = $const;
                }
            }

            if ($key === '') {
                $key = (string) get_option($auth['setting_name'], '');
            }

            if (trim($key) !== '') {
                $available[] = $provider_id;
            }
        }

        return $available;
    }

    /**
     * Convenience: true only when fully active.
     *
     * @return bool
     */
    public function isActive(): bool
    {
        return $this->resolve() === self::STATE_ACTIVE;
    }
}
