<?php

namespace PloverCRM\Modules\Integrations\Endpoints;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
use PloverCRM\Core\Api\AbstractEndpoint;
use PloverCRM\Modules\Integrations\Services\DataSourceService;
use PloverCRM\Modules\Integrations\Providers\GoogleAdsProvider;
use PloverCRM\Modules\Integrations\Services\AdsLogger;

/**
 * Google Ads Webhook Endpoint
 * 
 * Handles Google Ads Lead Form Extension webhooks.
 * Receives lead data directly from Google Ads.
 */
class GoogleAdsWebhookEndpoint extends AbstractEndpoint
{
  public function getRoute(): string
  {
    return '/webhook/google-ads';
  }

  public function getMethod()
  {
    return 'POST';
  }

  /**
   * Public endpoint - no authentication required
   */
  public function checkPermission(WP_REST_Request $request)
  {
    return true;
  }

  public function handle(WP_REST_Request $request)
  {
    $body = $request->get_body();
    $data = json_decode($body, true);

    $logger = new AdsLogger();

    if (empty($data)) {
      return new WP_Error('invalid_payload', 'Invalid JSON payload', ['status' => 400]);
    }

    // Validate required fields
    if (empty($data['form_id']) || empty($data['google_key'])) {
      return new WP_Error('missing_fields', 'Missing required fields', ['status' => 400]);
    }

    $formId = (string) $data['form_id'];
    $googleKey = $data['google_key'];
    $isTest = $data['is_test'] ?? false;
    $leadId = $data['lead_id'] ?? '';

    // Validate google_key
    $expectedKey = $this->getExpectedKey();
    if (!hash_equals($expectedKey, $googleKey)) {
      $logger->logSignatureValidationFailed('google_ads');
      return new WP_Error('invalid_key', 'Invalid google_key', ['status' => 403]);
    }

    // Log webhook received
    $logger->logWebhookReceived('google_ads', $formId, 1);

    // Handle test lead
    if ($isTest) {
      $this->handleTestLead($data, $logger);
      return new WP_REST_Response(['status' => 'test_received'], 200);
    }

    // Process production lead
    $this->processLead($data, $logger);

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

  /**
   * Handle test lead - cache form fields
   */
  private function handleTestLead(array $data, AdsLogger $logger): void
  {
    $formId = (string) $data['form_id'];
    $fields = [];

    // Extract fields from user_column_data
    foreach ($data['user_column_data'] ?? [] as $field) {
      $columnId = $field['column_id'] ?? '';
      $columnName = $field['column_name'] ?? $columnId;

      if ($columnId) {
        $fields[] = [
          'key' => $columnId,
          'label' => $columnName,
          'type' => $this->mapFieldType($columnId),
          'group' => 'form',
        ];
      }
    }

    // Cache fields for 7 days
    GoogleAdsProvider::cacheFormFields($formId, $fields);

    $logger->logTestLeadReceived(
      'google_ads',
      $formId,
      count($fields),
      array_column($fields, 'key')
    );
  }

  /**
   * Process production lead
   */
  private function processLead(array $data, AdsLogger $logger): void
  {
    $formId = (string) $data['form_id'];

    // Flatten lead data
    $flatData = $this->flattenLeadData($data);

    // Log lead received (raw payload contains all lead data)
    $logger->logLeadReceived('google_ads', $formId, $data['lead_id'] ?? '', $data);

    // Debug: log flattened data
    $logger->info('Google Ads lead data flattened', [
      'form_id' => $formId,
      'flat_data_keys' => array_keys($flatData),
    ]);

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

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

    // Flatten user_column_data array
    foreach ($data['user_column_data'] ?? [] as $field) {
      $key = $field['column_id'] ?? '';
      $value = $field['string_value'] ?? '';

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

    // Add metadata with prefix
    $metaFields = [
      'lead_id',
      'form_id',
      'campaign_id',
      'adgroup_id',
      'creative_id',
      'asset_group_id',
      'gcl_id',
      'lead_stage',
      'lead_submit_time',
    ];

    foreach ($metaFields as $meta) {
      if (isset($data[$meta])) {
        $flat['_google_' . $meta] = $data[$meta];
      }
    }

    return $flat;
  }

  /**
   * Map Google Ads field type to standard type
   */
  private function mapFieldType(string $columnId): string
  {
    return match ($columnId) {
      'EMAIL', 'WORK_EMAIL' => 'email',
      'PHONE_NUMBER', 'WORK_PHONE' => 'phone',
      'DEPARTURE_DATE', 'RETURN_DATE' => 'date',
      default => 'text',
    };
  }

  /**
   * Get expected webhook key
   */
  private function getExpectedKey(): string
  {
    return self::generateWebhookKey();
  }

  /**
   * Generate webhook key from domain
   * 
   * Creates a unique, deterministic key based on the site domain.
   * Always returns the same key for the same domain.
   * 
   * @return string 16-character alphanumeric key
   */
  private static function generateWebhookKey(): string
  {
    $domain = parse_url(home_url(), PHP_URL_HOST);
    return substr(md5($domain . 'plovercrm_google_ads_salt'), 0, 16);
  }

  /**
   * Get webhook URL for display to users
   */
  public static function getWebhookUrl(): string
  {
    return rest_url('plover-crm/v1/webhook/google-ads');
  }

  /**
   * Get webhook key for display to users
   */
  public static function getWebhookKey(): string
  {
    return self::generateWebhookKey();
  }
}
