<?php

namespace PloverCRM\Modules\Integrations\Providers;

/**
 * Contact Form 7 Provider
 */
class ContactForm7Provider implements DataSourceProviderInterface
{
  private $eventCallback;

  public function getKey(): string
  {
    return 'contactform7';
  }

  public function getName(): string
  {
    return 'Contact Form 7';
  }

  public function getIcon(): string
  {
    return 'contact-form-7.svg';
  }

  public function getCategory(): string
  {
    return 'forms';
  }

  public function isAvailable(): bool
  {
    return defined('WPCF7_VERSION') || class_exists('WPCF7_ContactForm');
  }

  public function getSupportedEvents(): array
  {
    return [
      ['key' => 'submission', 'label' => 'Form Submission'],
    ];
  }

  public function getSources(): array
  {
    if (!$this->isAvailable() || !class_exists('WPCF7_ContactForm')) {
      return [];
    }

    $forms = \WPCF7_ContactForm::find();

    if (empty($forms)) {
      return [];
    }

    return array_map(fn($form) => [
      'id' => (string) $form->id(),
      'title' => $form->title(),
    ], $forms);
  }

  public function getSourceFields(string $sourceId): array
  {
    if (!$this->isAvailable() || !class_exists('WPCF7_ContactForm')) {
      return [];
    }

    $form = \WPCF7_ContactForm::get_instance(absint($sourceId));

    if (!$form) {
      return [];
    }

    // Scan form tags to get all fields
    $tags = $form->scan_form_tags();

    if (empty($tags)) {
      return [];
    }

    $extracted = [];

    foreach ($tags as $tag) {
      // Skip tags without names (like submit buttons, labels, etc.)
      if (empty($tag->name)) {
        continue;
      }

      $fieldType = $tag->basetype ?? $tag->type ?? '';
      $fieldName = $tag->name;

      // Skip non-data fields
      if (in_array($fieldType, ['submit', 'quiz', 'captcha', 'acceptance'])) {
        continue;
      }

      // Generate a readable label from the field name
      $label = ucwords(str_replace(['_', '-'], ' ', $fieldName));

      $extracted[] = [
        'key' => $fieldName,
        'label' => $label,
        'type' => $this->mapFieldType($fieldType),
      ];
    }

    return $extracted;
  }

  public function registerEventListener(callable $callback): void
  {
    $this->eventCallback = $callback;
    add_action('wpcf7_submit', [$this, 'handleSubmission'], 20, 2);
  }

  /**
   * Handle Contact Form 7 submission
   * 
   * @param \WPCF7_ContactForm $contactForm The contact form instance
   * @param array $result The submission result
   */
  public function handleSubmission($contactForm, $result): void
  {
    if (!$this->eventCallback) {
      return;
    }

    // Only process successful submissions
    $status = $result['status'] ?? '';
    if (!in_array($status, ['mail_sent', 'mail_failed'])) {
      return;
    }

    $formId = $contactForm->id();
    if (empty($formId)) {
      return;
    }

    // Get the submission instance to access posted data
    $submission = \WPCF7_Submission::get_instance();
    if (!$submission) {
      return;
    }

    // Get posted data
    $postedData = $submission->get_posted_data();

    if (empty($postedData)) {
      return;
    }

    // Normalize the data - CF7 already provides clean field names as keys
    $normalized = [];
    foreach ($postedData as $key => $value) {
      // Handle array values (like checkboxes)
      if (is_array($value)) {
        $value = implode(', ', $value);
      }

      if ($value !== '' && $value !== null) {
        $normalized[$key] = $value;
      }
    }

    call_user_func($this->eventCallback, $this->getKey(), (string) $formId, $normalized);
  }

  private function mapFieldType(string $type): string
  {
    $map = [
      'text' => 'text',
      'textarea' => 'textarea',
      'email' => 'email',
      'url' => 'url',
      'tel' => 'phone',
      'number' => 'number',
      'range' => 'number',
      'date' => 'date',
      'select' => 'select',
      'radio' => 'radio',
      'checkbox' => 'checkbox',
      'file' => 'file',
      'hidden' => 'hidden',
    ];
    return $map[$type] ?? 'text';
  }
}
