<?php

declare(strict_types=1);

/**
 * @param array<string, mixed> $field
 * @param list<array<string, mixed>> $availableImageFiles
 * @param array<string, mixed> $options
 */
function myronRenderSectionContentFieldControl(array $field, string $inputName, string $value, array $availableImageFiles, array $options = []): string
{
    $fieldKey = (string) ($field['key'] ?? '');
    $fieldType = myronSectionContentFieldType($field);
    $label = (string) ($field['label'] ?? $fieldKey);
    $formId = trim((string) ($options['formId'] ?? ''));
    $formAttribute = $formId !== '' ? ' form="' . myronEscape($formId) . '"' : '';
    $richtextAttribute = myronSectionContentFieldRichtextAttribute($field, $fieldType);
    $full = $fieldType === 'textarea';

    $html = [];
    $html[] = '<label class="sg-field' . ($full ? ' sg-field--full' : '') . '">';
    $html[] = '<span class="sg-field__label">' . myronEscape($label) . '</span>';
    $acceptedValues = myronSectionContentFieldAcceptedValues($field);
    if ($acceptedValues !== []) {
        $html[] = myronRenderSectionContentEnumSelect($field, $inputName, $value, $formAttribute, $acceptedValues);
    } elseif ($fieldType === 'textarea') {
        $rows = $fieldKey === 'body' ? '8' : '4';
        $html[] = '<textarea class="sg-field__control sg-field__control--textarea"' . $formAttribute . $richtextAttribute . ' name="' . myronEscape($inputName) . '" rows="' . $rows . '">' . myronEscape($value) . '</textarea>';
    } elseif (in_array($fieldType, ['image', 'icon'], true)) {
        $html[] = myronRenderSectionContentAssetSelect($inputName, $value, $availableImageFiles, $formAttribute, $fieldType);
    } elseif ($fieldType === 'url') {
        $html[] = '<input class="sg-field__control" type="text" inputmode="url"' . $formAttribute . ' name="' . myronEscape($inputName) . '" value="' . myronEscape($value) . '">';
    } else {
        $html[] = '<input class="sg-field__control" type="text"' . $formAttribute . $richtextAttribute . ' name="' . myronEscape($inputName) . '" value="' . myronEscape($value) . '">';
    }
    $html[] = '</label>';

    return implode("\n", $html);
}

/**
 * @param array<string, mixed> $field
 * @param list<array<string, mixed>> $availableImageFiles
 * @param array<string, mixed> $options
 */
function myronRenderSectionContentRepeaterFieldControl(array $field, string $inputName, string $value, array $availableImageFiles, array $options = []): string
{
    $fieldKey = (string) ($field['key'] ?? '');
    $fieldType = myronSectionContentFieldType($field);
    $label = (string) ($field['label'] ?? $fieldKey);
    $formId = trim((string) ($options['formId'] ?? ''));
    $formAttribute = $formId !== '' ? ' form="' . myronEscape($formId) . '"' : '';
    $richtextAttribute = myronSectionContentFieldRichtextAttribute($field, $fieldType);

    $html = [];
    $html[] = '<label class="sg-field' . ($fieldType === 'textarea' ? ' sg-field--full' : '') . '">';
    $html[] = '<span class="sg-field__label">' . myronEscape($label) . '</span>';
    if ($fieldType === 'textarea') {
        $html[] = '<textarea class="sg-field__control sg-field__control--textarea"' . $formAttribute . $richtextAttribute . ' name="' . myronEscape($inputName) . '" rows="3">' . myronEscape($value) . '</textarea>';
    } elseif (in_array($fieldType, ['image', 'icon'], true)) {
        $html[] = myronRenderSectionContentAssetSelect($inputName, $value, $availableImageFiles, $formAttribute, $fieldType);
    } elseif ($fieldType === 'url') {
        $html[] = '<input class="sg-field__control" type="text" inputmode="url"' . $formAttribute . ' name="' . myronEscape($inputName) . '" value="' . myronEscape($value) . '">';
    } else {
        $html[] = '<input class="sg-field__control" type="text"' . $formAttribute . $richtextAttribute . ' name="' . myronEscape($inputName) . '" value="' . myronEscape($value) . '">';
    }
    $html[] = '</label>';

    return implode("\n", $html);
}

/**
 * Render a bounded repeatable editor with a client-side item template.
 *
 * @param array<string, mixed> $group
 * @param list<array<string, mixed>> $availableImageFiles
 * @param array<string, mixed> $options
 */
function myronRenderSectionContentRepeaterGroup(
    array $group,
    string $instanceKey,
    array $availableImageFiles,
    array $options = []
): string {
    $groupKey = trim((string) ($group['key'] ?? ''));
    if ($groupKey === '') {
        return '';
    }

    $fields = array_values(array_filter((array) ($group['fields'] ?? []), 'is_array'));
    $items = array_values(array_filter((array) ($group['items'] ?? []), 'is_array'));
    $itemLabel = trim((string) ($group['itemLabel'] ?? 'Item')) ?: 'Item';
    $minItems = max(0, (int) ($group['minItems'] ?? 0));
    $maxItems = max($minItems, (int) ($group['maxItems'] ?? 12));
    $formId = trim((string) ($options['formId'] ?? ''));
    $formAttribute = $formId !== '' ? ' form="' . myronEscape($formId) . '"' : '';
    $gridClass = trim((string) ($options['gridClass'] ?? 'sg-form-grid')) ?: 'sg-form-grid';
    $namePrefix = 'section_content[' . $instanceKey . '][' . $groupKey . ']';

    $renderItem = static function (array $item, string $index) use (
        $fields,
        $availableImageFiles,
        $formId,
        $formAttribute,
        $gridClass,
        $itemLabel,
        $namePrefix
    ): string {
        $html = [];
        $html[] = '<section class="mc-repeatable-item" data-mc-repeatable-item>';
        $html[] = '<div class="mc-repeatable-item__header">';
        $html[] = '<strong data-mc-repeatable-label>' . myronEscape($itemLabel) . '</strong>';
        $html[] = '<div class="mc-repeatable-item__actions">';
        $html[] = '<button class="sg-button sg-button--secondary sg-button--compact" type="button" data-mc-repeatable-up aria-label="Move item up">Up</button>';
        $html[] = '<button class="sg-button sg-button--secondary sg-button--compact" type="button" data-mc-repeatable-down aria-label="Move item down">Down</button>';
        $html[] = '<button class="sg-button sg-button--secondary sg-button--compact" type="button" data-mc-repeatable-remove>Remove</button>';
        $html[] = '</div>';
        $html[] = '</div>';
        $html[] = '<input type="hidden"' . $formAttribute . ' name="' . myronEscape($namePrefix . '[' . $index . '][__remove]') . '" value="0" data-mc-repeatable-remove-input>';
        $html[] = '<input type="hidden"' . $formAttribute . ' name="' . myronEscape($namePrefix . '[' . $index . '][__order]') . '" value="' . myronEscape($index) . '" data-mc-repeatable-order>';
        $html[] = '<div class="' . myronEscape($gridClass) . '">';
        foreach ($fields as $field) {
            $fieldKey = trim((string) ($field['key'] ?? ''));
            if ($fieldKey === '') {
                continue;
            }
            $inputName = $namePrefix . '[' . $index . '][' . $fieldKey . ']';
            $html[] = myronRenderSectionContentRepeaterFieldControl(
                $field,
                $inputName,
                (string) ($item[$fieldKey] ?? ''),
                $availableImageFiles,
                ['formId' => $formId]
            );
        }
        $html[] = '</div>';
        $html[] = '</section>';

        return implode("\n", $html);
    };

    $html = [];
    $html[] = '<fieldset class="sg-field sg-field--full mc-repeatable-fieldset"'
        . ' data-mc-repeatable-group="' . myronEscape($groupKey) . '"'
        . ' data-mc-repeatable-min="' . myronEscape((string) $minItems) . '"'
        . ' data-mc-repeatable-max="' . myronEscape((string) $maxItems) . '"'
        . ' data-mc-repeatable-next-index="' . myronEscape((string) count($items)) . '">';
    $html[] = '<legend class="sg-field__label">' . myronEscape((string) ($group['label'] ?? $groupKey)) . '</legend>';
    $html[] = '<div class="mc-repeatable-fieldset__items" data-mc-repeatable-items>';
    foreach ($items as $index => $item) {
        $html[] = $renderItem($item, (string) $index);
    }
    $html[] = '</div>';
    $html[] = '<template data-mc-repeatable-template>' . $renderItem([], '__INDEX__') . '</template>';
    $html[] = '<div class="mc-repeatable-fieldset__footer">';
    $html[] = '<button class="sg-button sg-button--secondary" type="button" data-mc-repeatable-add>Add ' . myronEscape($itemLabel) . '</button>';
    $html[] = '<span class="sg-field__hint" data-mc-repeatable-status aria-live="polite"></span>';
    $html[] = '</div>';
    $html[] = '</fieldset>';

    return implode("\n", $html);
}

/**
 * @param array<string, mixed> $field
 */
function myronSectionContentFieldIsRichtext(array $field): bool
{
    return filter_var($field['richtext'] ?? false, FILTER_VALIDATE_BOOL);
}

/**
 * @param array<string, mixed> $field
 */
function myronSectionContentFieldRichtextAttribute(array $field, string $fieldType): string
{
    if (!myronSectionContentFieldIsRichtext($field) || !in_array($fieldType, ['text', 'textarea'], true)) {
        return '';
    }

    $mics = is_array($field['mics'] ?? null) ? array_values(array_map('strval', $field['mics'])) : [];
    $micAttribute = ' data-mc-richtext-mics="' . myronEscape(implode(',', $mics)) . '"';
    return ' data-mc-richtext="true"' . ($fieldType === 'text' ? ' data-mc-richtext-singleline="true"' : '') . $micAttribute;
}

/**
 * @param array<string, mixed> $field
 */
function myronSectionContentFieldType(array $field): string
{
    $type = strtolower(trim((string) ($field['type'] ?? 'text')));
    if (in_array($type, ['asset:icon', 'file:icon', 'media:icon'], true)) {
        return 'icon';
    }
    if (in_array($type, ['asset:image', 'file:image', 'media:image'], true)) {
        return 'image';
    }
    if ($type === 'icon' || (string) ($field['presentation'] ?? '') === 'icon') {
        return 'icon';
    }

    return in_array($type, ['textarea', 'url', 'image', 'text'], true) ? $type : 'text';
}

/**
 * @param array<string, mixed> $field
 * @return list<string>
 */
function myronSectionContentFieldAcceptedValues(array $field): array
{
    $constraints = is_array($field['constraints'] ?? null) ? $field['constraints'] : [];
    $values = is_array($constraints['acceptedValues'] ?? null)
        ? $constraints['acceptedValues']
        : (is_array($constraints['enum'] ?? null) ? $constraints['enum'] : []);
    $accepted = [];
    foreach ($values as $value) {
        if (!is_scalar($value)) {
            continue;
        }
        $normalized = trim((string) $value);
        if ($normalized !== '') {
            $accepted[$normalized] = true;
        }
    }

    return array_keys($accepted);
}

/**
 * @param array<string, mixed> $field
 * @param list<string> $acceptedValues
 */
function myronRenderSectionContentEnumSelect(array $field, string $inputName, string $value, string $formAttribute, array $acceptedValues): string
{
    $default = $field['default'] ?? null;
    $defaultLabel = 'Use section default';
    if (is_scalar($default) && trim((string) $default) !== '') {
        $defaultLabel .= ' (' . trim((string) $default) . ')';
    }

    $html = [];
    $html[] = '<select class="sg-field__control" name="' . myronEscape($inputName) . '"' . $formAttribute . '>';
    $html[] = '<option value=""' . ($value === '' ? ' selected' : '') . '>' . myronEscape($defaultLabel) . '</option>';
    foreach ($acceptedValues as $acceptedValue) {
        $optionLabel = ucwords(str_replace(['-', '_'], ' ', $acceptedValue));
        $html[] = '<option value="' . myronEscape($acceptedValue) . '"' . ($value === $acceptedValue ? ' selected' : '') . '>' . myronEscape($optionLabel) . '</option>';
    }
    $html[] = '</select>';

    return implode("\n", $html);
}

/**
 * @param list<array<string, mixed>> $availableImageFiles
 */
function myronRenderSectionContentAssetSelect(string $inputName, string $value, array $availableImageFiles, string $formAttribute, string $fieldType): string
{
    $html = [];
    $html[] = '<select class="sg-field__control" name="' . myronEscape($inputName) . '"' . $formAttribute . '>';
    $html[] = '<option value="">Use section default</option>';
    foreach ($availableImageFiles as $file) {
        $fileId = (string) ($file['id'] ?? '');
        if ($fileId === '') {
            continue;
        }
        $label = (string) (($file['title'] ?? '') ?: ($file['original_filename'] ?? 'Image asset'));
        $html[] = '<option value="' . myronEscape($fileId) . '"' . ($value === $fileId ? ' selected' : '') . '>' . myronEscape($label) . '</option>';
    }
    $html[] = '</select>';
    $html[] = '<span class="sg-field__hint">Choose an existing ' . ($fieldType === 'icon' ? 'image or SVG icon' : 'image') . ' asset.</span>';

    return implode("\n", $html);
}
