<?php

namespace PloverCRM\Modules\Integrations\Providers;

/**
 * Formidable Forms Provider
 */
class FormidableFormsProvider implements DataSourceProviderInterface
{
  private $eventCallback;

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

  public function getName(): string
  {
    return 'Formidable Forms';
  }

  public function getIcon(): string
  {
    return 'formidable.svg';
  }

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

  public function isAvailable(): bool
  {
    return class_exists('FrmForm') || class_exists('FrmField');
  }

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

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

    $forms = \FrmForm::get_published_forms();

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

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

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

    $fields = \FrmField::get_all_for_form(absint($sourceId));

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

    $extracted = [];

    foreach ($fields as $field) {
      $fieldId = $field->id ?? '';
      $fieldType = $field->type ?? '';
      $fieldKey = $field->field_key ?? '';
      $label = $field->name ?? ucfirst(str_replace('_', ' ', $fieldType));

      // Skip non-data fields
      if (in_array($fieldType, ['html', 'divider', 'break', 'captcha', 'form', 'end_divider', 'submit'])) {
        continue;
      }

      // Use field ID as key (Formidable uses numeric IDs in item_meta)
      $extracted[] = [
        'key' => (string) $fieldId,
        'label' => $label,
        'type' => $this->mapFieldType($fieldType),
      ];
    }

    return $extracted;
  }

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

  /**
   * Handle Formidable Forms submission
   * 
   * @param int $entryId The entry ID
   * @param int $formId  The form ID
   */
  public function handleSubmission($entryId, $formId): void
  {
    if (!$this->eventCallback) {
      return;
    }

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

    // Get the entry with meta data
    $entry = \FrmEntry::getOne($entryId, true);

    if (!$entry || empty($entry->metas)) {
      return;
    }

    // Normalize the data - Formidable stores field values with field ID as key
    $normalized = [];
    foreach ($entry->metas as $fieldId => $value) {
      // Handle array values (like checkboxes)
      if (is_array($value)) {
        $value = implode(', ', $value);
      }

      if ($value !== '' && $value !== null) {
        $normalized[(string) $fieldId] = $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',
      'phone' => 'phone',
      'date' => 'date',
      'time' => 'time',
      'select' => 'select',
      'radio' => 'radio',
      'checkbox' => 'checkbox',
      'file' => 'file',
      'hidden' => 'hidden',
      'name' => 'text',
      'address' => 'text',
      'scale' => 'number',
      'star' => 'number',
      'range' => 'number',
      'password' => 'text',
      'tag' => 'text',
      'data' => 'text',
      'lookup' => 'text',
      'user_id' => 'text',
      'rte' => 'textarea',
      'signature' => 'text',
      'likert' => 'text',
      'nps' => 'number',
      'product' => 'text',
      'quantity' => 'number',
      'total' => 'number',
      'toggle' => 'checkbox',
      'summary' => 'text',
    ];
    return $map[$type] ?? 'text';
  }
}
