<?php

namespace PloverCRM\Modules\Integrations\Providers;

/**
 * Ninja Forms Provider
 */
class NinjaFormsProvider implements DataSourceProviderInterface
{
  private $eventCallback;

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

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

  public function getIcon(): string
  {
    return 'ninja-forms.svg';
  }

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

  public function isAvailable(): bool
  {
    return class_exists('Ninja_Forms') && function_exists('Ninja_Forms');
  }

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

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

    $forms = \Ninja_Forms()->form()->get_forms();

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

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

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

    $fields = \Ninja_Forms()->form(absint($sourceId))->get_fields();

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

    $extracted = [];

    foreach ($fields as $field) {
      $fieldId = $field->get_id();
      $fieldType = $field->get_setting('type');
      $label = $field->get_setting('label') ?: ucfirst(str_replace('_', ' ', $fieldType));
      $fieldKey = $field->get_setting('key');

      // Skip non-data fields
      if (in_array($fieldType, ['html', 'hr', 'submit', 'recaptcha', 'spam', 'divider', 'note'])) {
        continue;
      }

      // Use field key as the identifier (more reliable than ID)
      $extracted[] = [
        'key' => $fieldKey,
        'label' => $label,
        'type' => $this->mapFieldType($fieldType),
      ];
    }

    return $extracted;
  }

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

  /**
   * Handle Ninja Forms submission
   * 
   * @param array $form_data The form submission data
   * @return array The form data (unchanged)
   */
  public function handleSubmission($form_data): array
  {
    if (!$this->eventCallback) {
      return $form_data;
    }

    $formId = $form_data['id'] ?? '';
    if (empty($formId)) {
      return $form_data;
    }

    // Normalize field data for our system
    // Ninja Forms uses field keys to identify fields
    $normalized = [];

    if (!empty($form_data['fields']) && is_array($form_data['fields'])) {
      foreach ($form_data['fields'] as $fieldId => $fieldData) {
        $key = $fieldData['key'] ?? '';
        $value = $fieldData['value'] ?? '';

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

    if (!empty($normalized)) {
      call_user_func($this->eventCallback, $this->getKey(), (string) $formId, $normalized);
    }

    return $form_data;
  }

  private function mapFieldType(string $type): string
  {
    $map = [
      'textbox' => 'text',
      'textarea' => 'textarea',
      'email' => 'email',
      'phone' => 'phone',
      'number' => 'number',
      'date' => 'date',
      'listselect' => 'select',
      'listradio' => 'radio',
      'listcheckbox' => 'checkbox',
      'listmultiselect' => 'multiselect',
      'file_upload' => 'file',
      'hidden' => 'hidden',
      'firstname' => 'text',
      'lastname' => 'text',
      'address' => 'text',
      'city' => 'text',
      'zip' => 'text',
      'starrating' => 'number',
    ];
    return $map[$type] ?? 'text';
  }
}
