<?php

namespace PloverCRM\Modules\Integrations\Providers;

/**
 * Bit Form Provider
 */
class BitFormProvider implements DataSourceProviderInterface
{
  private $eventCallback;

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

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

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

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

  public function isAvailable(): bool
  {
    return defined('BITFORMS_VERSION') || class_exists('BitCode\BitForm\Plugin');
  }

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

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

    global $wpdb;
    $table = $wpdb->prefix . 'bitforms_form';

    // Check if table exists
    $tableExists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $table));
    if (!$tableExists) {
      return [];
    }

    $forms = $wpdb->get_results("SELECT id, form_name FROM {$table} WHERE status = '1' ORDER BY id DESC");

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

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

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

    global $wpdb;
    $table = $wpdb->prefix . 'bitforms_form';

    $form = $wpdb->get_row($wpdb->prepare(
      "SELECT form_content FROM {$table} WHERE id = %d",
      absint($sourceId)
    ));

    if (!$form || empty($form->form_content)) {
      return [];
    }

    $formContent = json_decode($form->form_content);

    if (!$formContent || !isset($formContent->fields)) {
      return [];
    }

    $fields = [];

    foreach ($formContent->fields as $key => $field) {
      $fieldType = $field->typ ?? '';

      // Skip non-data fields
      if (in_array($fieldType, ['recaptcha', 'hcaptcha', 'turnstile', 'html', 'button', 'divider', 'section'])) {
        continue;
      }

      $label = $field->lbl ?? $field->adminLbl ?? $field->fieldName ?? 'Field ' . $key;

      // Bit Form uses 'b{formId}-{fieldNumber}' format in submissions
      $fieldKey = $key;

      // If key starts with 'bf', convert to 'b' format for submission matching
      if (strpos($key, 'bf') === 0) {
        $fieldKey = 'b' . substr($key, 2);
      }

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

    return $fields;
  }

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

  /**
   * Handle Bit Form submission
   * 
   * @param int $formId The form ID
   * @param int $entryId The entry ID
   * @param array $postData The submitted form data
   * @param array $files The uploaded files
   */
  public function handleSubmission($formId, $entryId, $postData, $files): void
  {
    if (!$this->eventCallback) {
      return;
    }

    if (empty($formId) || empty($postData)) {
      return;
    }

    // Normalize the data
    $normalized = [];
    foreach ($postData as $key => $value) {
      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',
      'number' => 'number',
      'tel' => 'phone',
      'phone-number' => 'phone',
      'date' => 'date',
      'datetime-local' => 'date',
      'time' => 'time',
      'select' => 'select',
      'radio' => 'radio',
      'check' => 'checkbox',
      'checkbox' => 'checkbox',
      'file-up' => 'file',
      'advanced-file-up' => 'file',
      'hidden' => 'hidden',
      'password' => 'text',
      'color' => 'text',
      'rating' => 'number',
      'range' => 'number',
      'country' => 'select',
      'currency' => 'select',
      'signature' => 'text',
      'decision-box' => 'checkbox',
      'html-select' => 'select',
      'image-select' => 'select',
      'paypal' => 'text',
      'stripe' => 'text',
      'razorpay' => 'text',
      'mollie' => 'text',
    ];
    return $map[$type] ?? 'text';
  }
}
