<?php

namespace PloverCRM\Modules\Integrations\Providers;

/**
 * SureForms Provider
 */
class SureFormsProvider implements DataSourceProviderInterface
{
  private $eventCallback;

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

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

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

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

  public function isAvailable(): bool
  {
    return defined('SRFM_VER') || defined('SRFM_FORMS_POST_TYPE');
  }

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

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

    $forms = get_posts([
      'post_type' => 'sureforms_form',
      'post_status' => 'publish',
      'numberposts' => -1,
    ]);

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

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

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

    $form = get_post(absint($sourceId));

    if (!$form || $form->post_type !== 'sureforms_form') {
      return [];
    }

    $content = $form->post_content;

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

    // Parse Gutenberg blocks from form content
    $blocks = parse_blocks($content);

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

    $fields = [];
    $this->extractFieldsFromBlocks($blocks, $fields);

    return $fields;
  }

  /**
   * Recursively extract fields from Gutenberg blocks
   */
  private function extractFieldsFromBlocks(array $blocks, array &$fields): void
  {
    foreach ($blocks as $block) {
      if (!is_array($block) || empty($block['blockName'])) {
        continue;
      }

      // Check if it's a SureForms block
      if (strpos($block['blockName'], 'srfm/') === 0) {
        $blockType = str_replace('srfm/', '', $block['blockName']);

        // Skip non-input blocks
        if (in_array($blockType, ['inline-button', 'form', 'page-break', 'section'])) {
          // Process inner blocks for container types
          if (!empty($block['innerBlocks'])) {
            $this->extractFieldsFromBlocks($block['innerBlocks'], $fields);
          }
          continue;
        }

        $attrs = $block['attrs'] ?? [];
        $label = $attrs['label'] ?? ucfirst(str_replace('-', ' ', $blockType));
        $slug = $attrs['slug'] ?? '';

        if (!empty($slug)) {
          // SureForms prepare_submission_data uses the slug as the key in the data array
          // The slug is extracted from the field key after the encrypted label part
          // Format: srfm-{type}-{block_id}-lbl-{encrypted_label}-{slug}
          // The $label in prepare_submission_data is actually the slug!
          $fields[] = [
            'key' => $slug,
            'label' => $label,
            'type' => $this->mapFieldType($blockType),
          ];
        }
      }

      // Recursively process inner blocks
      if (!empty($block['innerBlocks'])) {
        $this->extractFieldsFromBlocks($block['innerBlocks'], $fields);
      }
    }
  }

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

  /**
   * Handle SureForms submission
   * 
   * @param array $formSubmitResponse The form submission response containing form_id, entry_id, data
   */
  public function handleSubmission($formSubmitResponse): void
  {
    if (!$this->eventCallback) {
      return;
    }

    if (!is_array($formSubmitResponse)) {
      return;
    }

    $formId = $formSubmitResponse['form_id'] ?? '';
    $data = $formSubmitResponse['data'] ?? [];

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

    // The data array has slugs as keys (from prepare_submission_data)
    $normalized = [];
    foreach ($data as $label => $value) {
      if (is_array($value)) {
        $value = implode(', ', $value);
      }

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

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

  private function mapFieldType(string $type): string
  {
    $map = [
      'input' => 'text',
      'email' => 'email',
      'url' => 'url',
      'number' => 'number',
      'phone' => 'phone',
      'textarea' => 'textarea',
      'dropdown' => 'select',
      'multi-choice' => 'checkbox',
      'checkbox' => 'checkbox',
      'radio' => 'radio',
      'upload' => 'file',
      'date-picker' => 'date',
      'time-picker' => 'time',
      'hidden' => 'hidden',
      'address' => 'text',
      'name' => 'text',
      'rating' => 'number',
      'range' => 'number',
      'signature' => 'text',
      'password' => 'text',
      'gdpr' => 'checkbox',
    ];
    return $map[$type] ?? 'text';
  }
}
