<?php
declare(strict_types=1);

namespace App\Modules\Forms\Services;

use App\Core\App;
use App\Modules\Forms\Models\FormSchema;

final class FormRenderer
{
    public static function render(FormSchema $schema, ?array $existingData = null, ?array $errors = null, bool $readOnly = false): string
    {
        $sections = $schema->getSections();
        $data = $existingData ?? [];
        $errors = $errors ?? [];
        $html = '';

        foreach ($sections as $section) {
            $sectionKey = $section['key'] ?? '';
            $sectionLabel = $section['label_ar'] ?? '';
            $visibleWhen = $section['visible_when'] ?? null;
            $repeatable = $section['repeatable'] ?? false;
            $maxRepeats = $section['max_repeats'] ?? 10;

            $visAttr = '';
            if ($visibleWhen) {
                $visAttr = ' data-visible-when=\'' . htmlspecialchars(json_encode($visibleWhen), ENT_QUOTES) . '\'';
                $visAttr .= ' style="display:none;"';
            }

            $repeatAttr = '';
            if ($repeatable && !$readOnly) {
                $repeatAttr = ' data-repeatable="true" data-section-key="' . e($sectionKey) . '" data-max-repeats="' . (int) $maxRepeats . '"';
            }

            $html .= '<div class="card" style="margin-bottom:20px;" id="section-' . e($sectionKey) . '"' . $visAttr . $repeatAttr . '>';
            $html .= '<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;display:flex;justify-content:space-between;align-items:center;">';
            $html .= '<h3 style="margin:0;color:#0D7377;">' . e($sectionLabel) . '</h3>';
            if ($repeatable && !$readOnly) {
                $html .= '<span style="font-size:12px;color:#9CA3AF;">الحد الأقصى: ' . (int) $maxRepeats . ' سجلات</span>';
            }
            $html .= '</div>';
            $html .= '<div style="padding:20px;"><div class="repeatable-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:15px;">';

            $fields = $section['fields'] ?? [];
            usort($fields, fn($a, $b) => ($a['order'] ?? 999) <=> ($b['order'] ?? 999));

            foreach ($fields as $field) {
                $html .= self::renderField($field, $data, $errors, $readOnly);
            }

            // If repeatable and we have submitted data with indexed fields, render additional rows
            if ($repeatable && !empty($data)) {
                $additionalRows = self::detectRepeatableRows($fields, $data);
                foreach ($additionalRows as $rowIndex) {
                    $html .= '<div style="grid-column:1/-1;border-top:2px dashed #E5E7EB;margin:10px 0;padding-top:10px;" data-row-index="' . $rowIndex . '">';
                    $html .= '<span style="color:#0D7377;font-weight:600;">سجل #' . $rowIndex . '</span>';
                    $html .= '</div>';
                    foreach ($fields as $field) {
                        $indexedField = $field;
                        $origKey = $field['key'] ?? '';
                        $indexedField['key'] = $origKey . '_' . $rowIndex;
                        $html .= self::renderField($indexedField, $data, $errors, $readOnly);
                    }
                }
            }

            $html .= '</div></div></div>';
        }

        return $html;
    }

    private static function detectRepeatableRows(array $fields, array $data): array
    {
        if (empty($fields)) return [];
        $firstFieldKey = $fields[0]['key'] ?? '';
        if ($firstFieldKey === '') return [];

        $indices = [];
        foreach ($data as $key => $value) {
            if (preg_match('/^' . preg_quote($firstFieldKey, '/') . '_(\d+)$/', $key, $m)) {
                $idx = (int) $m[1];
                if ($idx > 1) {
                    $indices[] = $idx;
                }
            }
        }
        sort($indices);
        return array_unique($indices);
    }

    public static function renderField(array $field, array $data, array $errors, bool $readOnly): string
    {
        $key = $field['key'] ?? '';
        $type = $field['type'] ?? 'text';
        $labelAr = $field['label_ar'] ?? $key;
        $required = $field['required'] ?? false;
        $editable = $field['editable'] ?? true;
        $value = $data[$key] ?? ($field['default_value'] ?? '');
        $fieldErrors = $errors[$key] ?? [];
        $helpText = $field['help_text_ar'] ?? '';
        $options = $field['options'] ?? [];
        $visibleWhen = $field['visible_when'] ?? null;
        $autoParse = $field['auto_parse'] ?? false;
        $populates = $field['populates'] ?? [];

        $width = $field['width'] ?? 'half';
        $colStyle = '';
        if ($width === 'full') {
            $colStyle = 'grid-column:1/-1;';
        }

        $disabled = ($readOnly || !$editable) ? ' disabled' : '';
        $requiredAttr = ($required && !$readOnly && $editable) ? ' required' : '';
        $requiredMark = $required ? ' <span style="color:#DC2626;">*</span>' : '';
        $errorClass = !empty($fieldErrors) ? 'border-color:#DC2626;' : '';

        $visAttr = '';
        if ($visibleWhen) {
            $visAttr = ' data-visible-when=\'' . htmlspecialchars(json_encode($visibleWhen), ENT_QUOTES) . '\' style="display:none;' . $colStyle . '"';
        } else {
            $visAttr = ' style="' . $colStyle . '"';
        }

        $dataAttrs = '';
        if ($autoParse) {
            $dataAttrs .= ' data-auto-parse="true"';
        }
        if (!empty($populates)) {
            $dataAttrs .= ' data-populates=\'' . htmlspecialchars(json_encode($populates), ENT_QUOTES) . '\'';
        }

        $html = '<div class="form-group"' . $visAttr . ' id="field-wrap-' . e($key) . '">';

        if ($type !== 'hidden' && $type !== 'checkbox') {
            $html .= '<label class="form-label" for="field-' . e($key) . '">' . e($labelAr) . $requiredMark . '</label>';
        }

        switch ($type) {
            case 'text':
            case 'passport':
            case 'phone':
            case 'phone_eg':
            case 'email':
                $inputType = ($type === 'email') ? 'email' : (($type === 'phone' || $type === 'phone_eg') ? 'tel' : 'text');
                $html .= '<input type="' . $inputType . '" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input" style="' . $errorClass . '"' . $disabled . $requiredAttr . $dataAttrs . '>';
                break;

            case 'national_id':
                $html .= '<input type="text" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input nid-input" maxlength="14" pattern="\\d{14}" style="direction:ltr;text-align:left;' . $errorClass . '"' . $disabled . $requiredAttr . $dataAttrs . ' data-nid-parser="true">';
                break;

            case 'number':
            case 'decimal':
                $step = ($type === 'decimal') ? '0.01' : '1';
                $html .= '<input type="number" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" step="' . $step . '" class="form-input" style="' . $errorClass . '"' . $disabled . $requiredAttr . '>';
                break;

            case 'currency':
                $displayVal = $value !== '' && $value !== null ? number_format((float) $value, 2) : '';
                $html .= '<div style="position:relative;">';
                $html .= '<input type="text" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e($displayVal) . '" class="form-input" style="direction:ltr;text-align:left;padding-left:40px;background:#F3F4F6;' . $errorClass . '" readonly>';
                $html .= '<span style="position:absolute;left:10px;top:50%;transform:translateY(-50%);color:#6B7280;font-size:12px;">ج.م</span>';
                $html .= '</div>';
                break;

            case 'date':
                $html .= '<input type="date" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input" style="' . $errorClass . '"' . $disabled . $requiredAttr . '>';
                break;

            case 'select':
                $html .= '<select id="field-' . e($key) . '" name="' . e($key) . '" class="form-select" style="' . $errorClass . '"' . $disabled . $requiredAttr . '>';
                $html .= '<option value="">-- اختر --</option>';
                foreach ($options as $opt) {
                    $optVal = $opt['value'] ?? '';
                    $optLabel = $opt['label_ar'] ?? $optVal;
                    $selected = ((string) $value === (string) $optVal) ? ' selected' : '';
                    $html .= '<option value="' . e($optVal) . '"' . $selected . '>' . e($optLabel) . '</option>';
                }
                $html .= '</select>';
                break;

            case 'select_dynamic':
                $dataSource = $field['data_source'] ?? '';
                $html .= '<select id="field-' . e($key) . '" name="' . e($key) . '" class="form-select" style="' . $errorClass . '"' . $disabled . $requiredAttr . ' data-source="' . e($dataSource) . '">';
                $html .= '<option value="">-- اختر --</option>';
                $dynamicOptions = self::loadDynamicOptions($dataSource);
                foreach ($dynamicOptions as $opt) {
                    $selected = ((string) $value === (string) $opt['value']) ? ' selected' : '';
                    $html .= '<option value="' . e($opt['value']) . '"' . $selected . '>' . e($opt['label']) . '</option>';
                }
                $html .= '</select>';
                break;

            case 'textarea':
                $html .= '<textarea id="field-' . e($key) . '" name="' . e($key) . '" class="form-textarea" rows="3" style="' . $errorClass . '"' . $disabled . $requiredAttr . '>' . e((string) $value) . '</textarea>';
                break;

            case 'checkbox':
                $checked = $value ? ' checked' : '';
                $reqStr = ($required && !$readOnly) ? ' required' : '';
                $html .= '<label style="display:flex;align-items:center;gap:8px;cursor:pointer;">';
                $html .= '<input type="checkbox" id="field-' . e($key) . '" name="' . e($key) . '" value="1"' . $checked . $disabled . $reqStr . '>';
                $html .= '<span>' . e($labelAr) . ($required ? ' <span style="color:#DC2626;">*</span>' : '') . '</span>';
                $html .= '</label>';
                break;

            case 'radio':
                foreach ($options as $opt) {
                    $optVal = $opt['value'] ?? '';
                    $optLabel = $opt['label_ar'] ?? $optVal;
                    $checked = ((string) $value === (string) $optVal) ? ' checked' : '';
                    $html .= '<label style="display:flex;align-items:center;gap:8px;margin-bottom:5px;"><input type="radio" name="' . e($key) . '" value="' . e($optVal) . '"' . $checked . $disabled . '> <span>' . e($optLabel) . '</span></label>';
                }
                break;

            case 'file':
                if (!$readOnly) {
                    $html .= '<input type="file" id="field-' . e($key) . '" name="' . e($key) . '" class="form-input"' . $disabled . $requiredAttr . '>';
                } else {
                    $html .= '<span style="color:#6B7280;font-size:13px;">' . ($value ? e((string) $value) : 'لا يوجد ملف') . '</span>';
                }
                break;

            case 'computed':
                $html .= '<input type="text" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input" style="background:#F3F4F6;font-weight:600;' . $errorClass . '" readonly>';
                break;

            case 'static_text':
                $html .= '<div id="field-' . e($key) . '" style="padding:8px 12px;background:#F9FAFB;border:1px solid #E5E7EB;border-radius:6px;font-size:14px;min-height:38px;display:flex;align-items:center;">' . e((string) $value) . '</div>';
                break;

            case 'hidden':
                $html .= '<input type="hidden" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '">';
                break;

            case 'auto_increment':
                $html .= '<input type="text" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input" style="background:#F3F4F6;font-weight:700;color:#0D7377;" readonly>';
                break;

            case 'signature':
                if ($readOnly) {
                    $html .= '<span style="color:' . ($value ? '#059669' : '#DC2626') . ';font-weight:600;">' . ($value ? '✓ تم الإقرار' : '✗ لم يتم الإقرار') . '</span>';
                } else {
                    $checked = $value ? ' checked' : '';
                    $html .= '<label style="display:flex;align-items:center;gap:8px;cursor:pointer;padding:10px;background:#FFF7ED;border:1px solid #FED7AA;border-radius:6px;">';
                    $html .= '<input type="checkbox" id="field-' . e($key) . '" name="' . e($key) . '" value="1"' . $checked . $requiredAttr . '>';
                    $html .= '<span style="font-weight:600;">' . e($labelAr) . '</span>';
                    $html .= '</label>';
                }
                break;

            default:
                $html .= '<input type="text" id="field-' . e($key) . '" name="' . e($key) . '" value="' . e((string) $value) . '" class="form-input" style="background:#F3F4F6;" readonly>';
                break;
        }

        if (!empty($fieldErrors)) {
            foreach ((array) $fieldErrors as $err) {
                $html .= '<div style="color:#DC2626;font-size:12px;margin-top:4px;">' . e($err) . '</div>';
            }
        }

        if ($helpText) {
            $html .= '<small style="color:#9CA3AF;font-size:12px;display:block;margin-top:3px;">' . e($helpText) . '</small>';
        }

        $html .= '</div>';
        return $html;
    }

    private static function loadDynamicOptions(string $source): array
    {
        $db = App::getInstance()->db();

        switch ($source) {
            case 'governorates':
                $rows = $db->select("SELECT code as value, name_ar as label FROM governorates WHERE is_active = 1 ORDER BY name_ar");
                return array_map(fn($r) => ['value' => $r['value'], 'label' => $r['label']], $rows);

            case 'countries':
                $rows = $db->select("SELECT nationality_ar as value, nationality_ar as label FROM countries WHERE is_active = 1 ORDER BY name_ar");
                return array_map(fn($r) => ['value' => $r['value'], 'label' => $r['label']], $rows);

            case 'qualifications':
                $rows = $db->select("SELECT id as value, name_ar as label FROM qualifications WHERE is_active = 1 ORDER BY sort_order");
                return array_map(fn($r) => ['value' => (string) $r['value'], 'label' => $r['label']], $rows);

            case 'branches':
                $rows = $db->select("SELECT id as value, name_ar as label FROM branches WHERE is_active = 1 ORDER BY name_ar");
                return array_map(fn($r) => ['value' => (string) $r['value'], 'label' => $r['label']], $rows);

            case 'religions':
                return [
                    ['value' => 'muslim', 'label' => 'مسلم'],
                    ['value' => 'christian', 'label' => 'مسيحي'],
                    ['value' => 'other', 'label' => 'أخرى'],
                ];

            case 'marital_statuses':
                return [
                    ['value' => 'single', 'label' => 'أعزب'],
                    ['value' => 'married', 'label' => 'متزوج'],
                    ['value' => 'divorced', 'label' => 'مطلق'],
                    ['value' => 'widowed', 'label' => 'أرمل'],
                ];

            case 'employment_types':
                return [
                    ['value' => 'employed', 'label' => 'موظف'],
                    ['value' => 'self_employed', 'label' => 'أعمال حرة'],
                    ['value' => 'professions', 'label' => 'مهن حرة'],
                    ['value' => 'retired', 'label' => 'متقاعد'],
                    ['value' => 'other', 'label' => 'أخرى'],
                ];

            default:
                return [];
        }
    }
}