<?php

declare(strict_types=1);

final class MicFormResolver implements MicElementResolverInterface, MicElementSearchable
{
    public function __construct(private readonly MicFormRepository $repository)
    {
    }

    public function extractSearchText(array $blockData): ?string
    {
        $id = trim((string) ($blockData['id'] ?? ''));
        if ($id === '') {
            return null;
        }
        $form = $this->repository->findById($id);
        if ($form === null) {
            return null;
        }
        $parts = [];
        foreach (['name', 'description', 'cta_label', 'success_message'] as $key) {
            $value = trim(strip_tags((string) ($form[$key] ?? '')));
            if ($value !== '') {
                $parts[] = $value;
            }
        }
        $fields = is_array($form['fields'] ?? null) ? $form['fields'] : [];
        foreach ($fields as $field) {
            if (!is_array($field)) {
                continue;
            }
            $label = trim(strip_tags((string) ($field['label'] ?? '')));
            if ($label !== '') {
                $parts[] = $label;
            }
            $options = is_array($field['options'] ?? null) ? $field['options'] : [];
            foreach ($options as $option) {
                $optionLabel = is_array($option) ? (string) ($option['label'] ?? $option['value'] ?? '') : (string) $option;
                $optionLabel = trim(strip_tags($optionLabel));
                if ($optionLabel !== '') {
                    $parts[] = $optionLabel;
                }
            }
        }
        return $parts === [] ? null : implode(' ', $parts);
    }

    public function resolve(string $id, array $context): ?string
    {
        $form = $this->repository->findById($id);
        if ($form === null) {
            return null;
        }
        $formHtml = $this->renderForm($form, (string) ($context['channel'] ?? 'public'));
        if ((string) ($form['embed_mode'] ?? 'inline') !== 'cta-modal') {
            return $formHtml;
        }
        $formId = (string) $form['id'];
        $label = (string) ($form['cta_label'] ?? 'Open form');
        return '<button type="button" class="myron-form-cta" data-mic-form-id="' . myronEscape($formId) . '" data-cta-label="' . myronEscape($label) . '">' . myronEscape($label) . '</button>'
            . '<dialog class="myron-form-dialog" id="myron-form-dialog-' . myronEscape($formId) . '">'
            . '<button type="button" class="myron-form-dialog__close" data-mic-form-close aria-label="Close form">x</button>'
            . $formHtml
            . '</dialog><script src="' . myronEscape(myronBuildAssetUrl('runtime/js/forms-modal.js')) . '" defer></script>';
    }

    public function describe(): array
    {
        return [
            'slug' => 'form',
            'label' => 'Form',
            'description' => 'Reusable form from the Content Banks > Forms bank.',
            'icon' => 'form',
            'scopes' => [MyronApiScopes::CONTENT_READ],
            'bankSurface' => 'editor',
            'parentSurfaceUrl' => myronBuildAdminUrl('content.contentBanks', ['bank' => 'forms']),
        ];
    }

    private function renderForm(array $form, string $channel): string
    {
        $formId = (string) ($form['id'] ?? '');
        $attrs = ' class="myron-form" method="post" action="' . myronEscape('/api/v1/content/forms/' . $formId . '/submissions') . '" data-myron-mic-form data-form-id="' . myronEscape($formId) . '" data-success-message="' . myronEscape((string) ($form['success_message'] ?? 'Thanks for submitting.')) . '"';
        if ($channel === 'admin-preview') {
            $attrs .= ' data-mic-form-id="' . myronEscape($formId) . '"';
        }
        $html = ['<form' . $attrs . '>'];
        $html[] = '<input type="hidden" name="csrf_token" value="" data-public-interaction-token data-public-interaction-purpose="form" data-public-interaction-resource="' . myronEscape($formId) . '" data-public-interaction-endpoint="/api/v1/public-interactions/token">';
        $html[] = '<input type="text" name="' . myronEscape((string) ($form['honeypot_field_name'] ?? 'mc_hp')) . '" class="myron-form__honeypot" tabindex="-1" autocomplete="off" aria-hidden="true">';
        foreach (is_array($form['fields'] ?? null) ? $form['fields'] : [] as $field) {
            if (!is_array($field)) {
                continue;
            }
            $html[] = $this->renderField($field);
        }
        $html[] = '<button class="myron-form__submit" type="submit">' . myronEscape((string) ($form['submit_button_label'] ?? 'Submit')) . '</button>';
        $html[] = '<p class="myron-form__message" role="status" aria-live="polite" data-myron-form-message></p>';
        $html[] = '</form>';
        return implode('', $html);
    }

    private function renderField(array $field): string
    {
        $key = (string) ($field['key'] ?? '');
        $type = (string) ($field['type'] ?? 'text');
        $label = (string) ($field['label'] ?? $key);
        $required = !empty($field['required']) ? ' required' : '';
        $placeholder = myronEscape((string) ($field['placeholder'] ?? ''));
        $html = '<label class="myron-form__field myron-form__field--' . myronEscape($type) . '"><span class="myron-form__label">' . $label . (!empty($field['required']) ? ' <span aria-hidden="true">*</span>' : '') . '</span>';
        if ($type === 'textarea') {
            $html .= '<textarea name="' . myronEscape($key) . '" placeholder="' . $placeholder . '"' . $required . '></textarea>';
        } elseif ($type === 'select') {
            $html .= '<select name="' . myronEscape($key) . '"' . $required . '>';
            foreach (is_array($field['options'] ?? null) ? $field['options'] : [] as $option) {
                if (is_array($option)) {
                    $html .= '<option value="' . myronEscape((string) ($option['value'] ?? '')) . '">' . myronEscape((string) ($option['label'] ?? $option['value'] ?? '')) . '</option>';
                }
            }
            $html .= '</select>';
        } elseif ($type === 'radio') {
            foreach (is_array($field['options'] ?? null) ? $field['options'] : [] as $option) {
                if (is_array($option)) {
                    $html .= '<span class="myron-form__choice"><input type="radio" name="' . myronEscape($key) . '" value="' . myronEscape((string) ($option['value'] ?? '')) . '"' . $required . '> ' . myronEscape((string) ($option['label'] ?? $option['value'] ?? '')) . '</span>';
                }
            }
        } elseif ($type === 'checkbox') {
            $html .= '<input type="checkbox" name="' . myronEscape($key) . '" value="1">';
        } else {
            $inputType = in_array($type, ['email', 'number', 'tel', 'url'], true) ? $type : 'text';
            $html .= '<input type="' . myronEscape($inputType) . '" name="' . myronEscape($key) . '" placeholder="' . $placeholder . '"' . $required . '>';
        }
        $help = (string) ($field['help_text'] ?? '');
        if ($help !== '') {
            $html .= '<span class="myron-form__help">' . $help . '</span>';
        }
        return $html . '</label>';
    }
}
