<?php

declare(strict_types=1);

namespace PloverCRM\Modules\Integrations\Endpoints;

use WP_REST_Request;
use WP_REST_Response;
use PloverCRM\Core\Api\AbstractEndpoint;
use PloverCRM\Core\Services\SystemFieldProvisioner;
use PloverCRM\Core\Services\SystemFieldRegistry;
use PloverCRM\Modules\Integrations\Services\MetaApiService;
use PloverCRM\Modules\Integrations\Services\DataSourceService;
use PloverCRM\Modules\Integrations\Services\AdsLogger;

/**
 * Meta Webhook Endpoint
 * 
 * Receives forwarded webhook events from the central server (webplover.com).
 */
class MetaWebhookEndpoint extends AbstractEndpoint
{
    /**
     * Get endpoint route
     */
    public function getRoute(): string
    {
        return '/meta/webhook';
    }

    /**
     * Get HTTP method
     */
    public function getMethod(): string
    {
        return 'POST';
    }

    /**
     * Public endpoint - validate via X-Forwarded-From header
     */
    public function checkPermission(WP_REST_Request $request)
    {
        // Public endpoint - no auth required
        // Validation done in handle() via X-Forwarded-From header
        return true;
    }

    /**
     * Handle incoming webhook
     */
    public function handle(WP_REST_Request $request)
    {
        // Validate request came from central server
        if (!$this->isValidRequest()) {
            return new WP_REST_Response(['error' => 'Invalid source'], 403);
        }

        $payload = $request->get_json_params();

        if (empty($payload['entry'])) {
            return new WP_REST_Response(['error' => 'Invalid payload'], 400);
        }

        $logger = new AdsLogger();

        // Process each entry
        foreach ($payload['entry'] as $entry) {
            $pageId = $entry['id'] ?? null;
            $changesCount = count($entry['changes'] ?? []);

            // Log webhook received
            if ($pageId) {
                $logger->logWebhookReceived('meta_lead_ads', $pageId, $changesCount);
            }

            // Process each change
            foreach ($entry['changes'] ?? [] as $change) {
                if (($change['field'] ?? '') !== 'leadgen') {
                    continue;
                }

                $value = $change['value'] ?? [];
                $leadgenId = $value['leadgen_id'] ?? null;
                $formId = $value['form_id'] ?? null;

                if (!$leadgenId || !$formId) {
                    continue;
                }

                $this->processLead($leadgenId, $formId, $pageId, $logger);
            }
        }

        // Always return 200 to acknowledge receipt
        return new WP_REST_Response(['status' => 'received'], 200);
    }

    /**
     * Validate request came from central server
     */
    private function isValidRequest(): bool
    {
        $forwardedFrom = $_SERVER['HTTP_X_FORWARDED_FROM'] ?? '';
        return $forwardedFrom === 'webplover-central';
    }

    /**
     * Process a single lead
     */
    private function processLead(string $leadgenId, string $formId, ?string $pageId, AdsLogger $logger): void
    {
        $provisioner = new SystemFieldProvisioner($this->container);
        $provisioner->ensureCapabilityIfActive(SystemFieldRegistry::CAPABILITY_META_LEAD_ADS);

        $api = new MetaApiService();

        // Fetch full lead data from Facebook
        $leadData = $api->fetchLead($leadgenId);

        if (!$leadData) {
            $logger->logProcessingError('meta_lead_ads', $formId, 0, 'Failed to fetch lead data from Facebook', [
                'leadgen_id' => $leadgenId,
            ]);
            return;
        }

        // Transform to flat array
        $flatData = $this->flattenLeadData($leadData);

        // Add metadata
        if ($pageId) {
            $flatData['_meta_page_id'] = $pageId;
        }

        // Process through DataSourceService
        // This handles all integrations, field mapping, conditions, CRM creation
        $service = new DataSourceService($this->container);
        $service->handleEvent('meta_lead_ads', $formId, $flatData);
    }

    /**
     * Flatten Facebook lead data to simple key-value array
     */
    private function flattenLeadData(array $leadData): array
    {
        $flat = [];

        // Flatten field_data
        foreach ($leadData['field_data'] ?? [] as $field) {
            $key = $field['name'] ?? '';
            $values = $field['values'] ?? [];
            $value = is_array($values) ? ($values[0] ?? '') : $values;

            if ($key) {
                $flat[$key] = $value;
            }
        }

        // Add metadata
        $metaFields = [
            'form_id', 'ad_id', 'ad_name', 'adset_name',
            'campaign_name', 'created_time', 'id'
        ];

        foreach ($metaFields as $key) {
            if (isset($leadData[$key])) {
                $flat['_meta_' . $key] = $leadData[$key];
            }
        }

        return $flat;
    }
}
