<?php

declare(strict_types=1);

namespace PloverCRM\Modules\Integrations\Services;

use PloverCRM\Modules\Integrations\Models\MetaConnection;

/**
 * Meta API Service
 * 
 * Handles all Facebook Graph API interactions.
 */
class MetaApiService
{
    private const API_VERSION = 'v24.0';
    private const API_BASE = 'https://graph.facebook.com/';

    /**
     * Get all lead forms from all connected pages
     * 
     * @return array Forms with page info
     */
    public function getAllForms(): array
    {
        // Check cache
        $cached = get_transient('plover_crm_meta_forms');
        if ($cached !== false) {
            return $cached;
        }

        $connections = MetaConnectionService::getAll(true);
        $allForms = [];

        foreach ($connections as $connection) {
            $forms = $this->getFormsForConnection($connection);
            foreach ($forms as $form) {
                $form['page_id'] = $connection->pageId;
                $form['page_name'] = $connection->pageName;
                $allForms[] = $form;
            }
        }

        // Cache for 1 hour
        set_transient('plover_crm_meta_forms', $allForms, HOUR_IN_SECONDS);

        return $allForms;
    }

    /**
     * Get lead forms for a specific connection
     */
    public function getFormsForConnection(MetaConnection $connection): array
    {
        if (!$connection->isActive()) {
            return [];
        }

        $url = $this->buildUrl("{$connection->pageId}/leadgen_forms", [
            'fields' => 'id,name,status',
            'access_token' => $connection->pageAccessToken,
        ]);

        $response = wp_remote_get($url, ['timeout' => 30, 'sslverify' => true]);

        if (is_wp_error($response)) {
            return [];
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);
        $forms = [];

        foreach ($data['data'] ?? [] as $form) {
            if ($form['status'] === 'ACTIVE') {
                $forms[] = [
                    'id' => $form['id'],
                    'title' => $form['name'] ?: 'Unnamed Form',
                ];
            }
        }

        return $forms;
    }

    /**
     * Get fields for a specific form
     */
    public function getFormFields(string $formId, ?MetaConnection $connection = null): array
    {
        if (!$connection) {
            $connection = $this->findConnectionForForm($formId);
        }

        if (!$connection || !$connection->isActive()) {
            return [];
        }

        $url = $this->buildUrl($formId, [
            'fields' => 'questions',
            'access_token' => $connection->pageAccessToken,
        ]);

        $response = wp_remote_get($url, ['timeout' => 30, 'sslverify' => true]);

        if (is_wp_error($response)) {
            return [];
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);
        $fields = [];

        // Form questions
        foreach ($data['questions'] ?? [] as $question) {
            $fields[] = [
                'key' => $question['key'] ?? '',
                'label' => $question['label'] ?? $question['key'] ?? '',
                'type' => $this->mapFieldType($question['type'] ?? 'CUSTOM'),
            ];
        }

        // Metadata fields
        $metaFields = [
            ['key' => '_meta_ad_name', 'label' => 'Ad Name', 'type' => 'text'],
            ['key' => '_meta_adset_name', 'label' => 'Ad Set Name', 'type' => 'text'],
            ['key' => '_meta_campaign_name', 'label' => 'Campaign Name', 'type' => 'text'],
            ['key' => '_meta_ad_id', 'label' => 'Ad ID', 'type' => 'text'],
            ['key' => '_meta_form_id', 'label' => 'Form ID', 'type' => 'text'],
            ['key' => '_meta_id', 'label' => 'Lead ID', 'type' => 'text'],
            ['key' => '_meta_created_time', 'label' => 'Lead Created Time', 'type' => 'text'],
            ['key' => '_meta_page_id', 'label' => 'Page ID', 'type' => 'text'],
        ];

        return array_merge($fields, $metaFields);
    }

    /**
     * Fetch lead data from Facebook
     */
    public function fetchLead(string $leadId, ?MetaConnection $connection = null): ?array
    {
        if (!$connection) {
            // Try to find any valid connection
            $connections = MetaConnectionService::getAll(true);
            foreach ($connections as $conn) {
                $test = $this->testConnection($conn);
                if ($test['valid']) {
                    $connection = $conn;
                    break;
                }
            }
        }

        if (!$connection || !$connection->isActive()) {
            return null;
        }

        $url = $this->buildUrl($leadId, [
            'fields' => 'created_time,id,ad_id,form_id,field_data,ad_name,adset_name,campaign_name',
            'access_token' => $connection->pageAccessToken,
        ]);

        $response = wp_remote_get($url, ['timeout' => 30, 'sslverify' => true]);

        if (is_wp_error($response)) {
            return null;
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);

        return isset($data['id']) ? $data : null;
    }

    /**
     * Subscribe page to leadgen webhooks
     */
    public function subscribePage(MetaConnection $connection): bool
    {
        if (!$connection->isActive()) {
            return false;
        }

        $url = $this->buildUrl("{$connection->pageId}/subscribed_apps", [
            'subscribed_fields' => 'leadgen',
            'access_token' => $connection->pageAccessToken,
        ]);

        $response = wp_remote_post($url, ['timeout' => 30, 'sslverify' => true]);

        if (is_wp_error($response)) {
            error_log('[Meta] Subscribe failed: ' . $response->get_error_message());
            return false;
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);

        return ($data['success'] ?? false) === true;
    }

    /**
     * Test if connection is valid
     */
    public function testConnection(MetaConnection $connection): array
    {
        if (!$connection->isActive()) {
            return ['valid' => false, 'error' => 'Connection inactive'];
        }

        $url = $this->buildUrl('me', [
            'access_token' => $connection->pageAccessToken,
        ]);

        $response = wp_remote_get($url, ['timeout' => 30, 'sslverify' => true]);

        if (is_wp_error($response)) {
            return ['valid' => false, 'error' => 'Connection failed'];
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);

        if (isset($data['error'])) {
            return [
                'valid' => false,
                'error' => $data['error']['message'] ?? 'Token invalid',
            ];
        }

        return [
            'valid' => true,
            'page_id' => $data['id'] ?? '',
            'page_name' => $data['name'] ?? $connection->pageName,
        ];
    }

    /**
     * Clear forms cache
     */
    public function clearCache(): void
    {
        delete_transient('plover_crm_meta_forms');
    }

    /**
     * Find which connection owns a form
     */
    private function findConnectionForForm(string $formId): ?MetaConnection
    {
        $connections = MetaConnectionService::getAll(true);

        foreach ($connections as $connection) {
            $url = $this->buildUrl($formId, [
                'fields' => 'id',
                'access_token' => $connection->pageAccessToken,
            ]);

            $response = wp_remote_get($url, ['timeout' => 10, 'sslverify' => true]);

            if (!is_wp_error($response)) {
                $data = json_decode(wp_remote_retrieve_body($response), true);
                if (!empty($data['id']) && empty($data['error'])) {
                    return $connection;
                }
            }
        }

        return null;
    }

    /**
     * Build API URL
     */
    private function buildUrl(string $endpoint, array $params): string
    {
        return self::API_BASE . self::API_VERSION . '/' . $endpoint . '?' . http_build_query($params);
    }

    /**
     * Map Facebook field type to standard type
     */
    private function mapFieldType(string $fbType): string
    {
        return match ($fbType) {
            'EMAIL' => 'email',
            'PHONE' => 'phone',
            'DATE_OF_BIRTH' => 'date',
            default => 'text',
        };
    }
}
