<?php
namespace admin\Support\Forms;

use admin\ViewModels\Forms\FormEditViewModel;
use admin\ViewModels\Forms\FormField;
use admin\ViewModels\Forms\FormFieldType;

/**
 * Renderer pól formularza
 */
class FormFieldRenderer
{
    private FormEditViewModel $form;

    public function __construct(FormEditViewModel $form)
    {
        $this->form = $form;
    }

    /**
     * Renderuje pojedyncze pole
     */
    public function renderField(FormField $field): string
    {
        $method = 'render' . ucfirst($field->type);
        
        if (method_exists($this, $method)) {
            return $this->$method($field);
        }
        
        // Fallback dla nieznanych typów - renderuj jako text
        return $this->renderText($field);
    }

    /**
     * Renderuje pole tekstowe
     */
    public function renderText(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        
        $params = [
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'text',
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ];
        
        if ($field->placeholder) {
            $params['placeholder'] = $field->placeholder;
        }
        
        if ($error) {
            $params['class'] .= ' error';
        }

        return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
    }

    /**
     * Renderuje pole number
     */
    public function renderNumber(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        
        $params = [
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'number',
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ];
        
        if ($error) {
            $params['class'] .= ' error';
        }

        return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
    }

    /**
     * Renderuje pole email
     */
    public function renderEmail(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        
        $params = [
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'email',
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ];
        
        if ($error) {
            $params['class'] .= ' error';
        }

        return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
    }

    /**
     * Renderuje pole password
     */
    public function renderPassword(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        return \Shared\Html\Html::input([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'password',
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ]);
    }

    /**
     * Renderuje pole daty
     */
    public function renderDate(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        
        $params = [
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'text',
            'class' => 'date ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ];
        
        if ($error) {
            $params['class'] .= ' error';
        }

        return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
    }

    /**
     * Renderuje pole daty i czasu
     */
    public function renderDatetime(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        return \Shared\Html\Html::input([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'text',
            'class' => 'datetime ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ]);
    }

    /**
     * Renderuje przełącznik (switch)
     */
    public function renderSwitch(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        // Domyślna wartość dla nowego rekordu
        if ($value === null && $field->value === true) {
            $checked = true;
        } else {
            $checked = (bool) $value;
        }
        
        return \Shared\Html\Html::input_switch([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'checked' => $checked,
        ]);
    }

    /**
     * Renderuje select
     */
    public function renderSelect(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        
        $params = [
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'values' => $field->options,
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ];
        
        if ($error) {
            $params['class'] .= ' error';
        }

        return $this->wrapWithError(\Shared\Html\Html::select($params), $error);
    }

    /**
     * Renderuje textarea
     */
    public function renderTextarea(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        return \Shared\Html\Html::textarea([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'rows' => $field->attributes['rows'] ?? 4,
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ]);
    }

    /**
     * Renderuje edytor (CKEditor)
     */
    public function renderEditor(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        return \Shared\Html\Html::textarea([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'rows' => max(10, ($field->attributes['rows'] ?? 10)),
            'class' => 'editor ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ]);
    }

    /**
     * Renderuje pole obrazu z filemanagerem
     */
    public function renderImage(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        $filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($field->id);
        
        return \Shared\Html\Html::input_icon([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'value' => $value ?? '',
            'type' => 'text',
            'icon_content' => 'przeglądaj',
            'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
        ]);
    }

    /**
     * Renderuje pole pliku
     */
    public function renderFile(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        if ($field->useFilemanager) {
            $filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($field->id);
            
            return \Shared\Html\Html::input_icon([
                'label' => $field->label,
                'name' => $field->name,
                'id' => $field->id,
                'value' => $value ?? '',
                'type' => 'text',
                'icon_content' => 'przeglądaj',
                'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
            ]);
        }
        
        return \Shared\Html\Html::input([
            'label' => $field->label,
            'name' => $field->name,
            'id' => $field->id,
            'type' => 'file',
            'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
        ]);
    }

    /**
     * Renderuje ukryte pole
     */
    public function renderHidden(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        
        return '<input type="hidden" name="' . htmlspecialchars($field->name) . '" ' .
               'id="' . htmlspecialchars($field->id) . '" ' .
               'value="' . htmlspecialchars($value ?? '') . '">';
    }

    /**
     * Renderuje pole koloru (color picker + text input)
     */
    public function renderColor(FormField $field): string
    {
        $value = $this->form->getFieldValue($field);
        $error = $this->form->getError($field->name);
        $colorValue = htmlspecialchars($value ?? '#000000', ENT_QUOTES, 'UTF-8');
        $fieldName = htmlspecialchars($field->name, ENT_QUOTES, 'UTF-8');
        $fieldId = htmlspecialchars($field->id, ENT_QUOTES, 'UTF-8');
        $label = htmlspecialchars($field->label, ENT_QUOTES, 'UTF-8');

        $html = '<div class="form-group row">';
        $html .= '<label class="col-lg-4 control-label">' . $label . ':</label>';
        $html .= '<div class="col-lg-8">';
        $html .= '<div style="display:flex;align-items:center;gap:8px;">';
        $html .= '<input type="color" id="' . $fieldId . '_picker" value="' . $colorValue . '" style="width:40px;height:34px;padding:2px;border:1px solid #ccc;cursor:pointer;" />';
        $html .= '<input type="text" name="' . $fieldName . '" id="' . $fieldId . '" value="' . $colorValue . '" class="form-control" style="max-width:150px;" />';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '<script>$(function(){'
            . 'var $p=$("#' . $fieldId . '_picker"),$t=$("#' . $fieldId . '");'
            . '$p.on("input",function(){$t.val(this.value);});'
            . '$t.on("input",function(){var v=this.value;if(/^#[0-9a-fA-F]{6}$/.test(v))$p.val(v);});'
            . '});</script>';

        return $this->wrapWithError($html, $error);
    }

    public function renderCustom(FormField $field): string
    {
        return (string)($field->customHtml ?? '');
    }

    /**
     * Renderuje sekcję językową
     */
    public function renderLangSection(FormField $section): string
    {
        if ($section->langFields === null || $this->form->languages === null) {
            return '';
        }
        
        $out = '<div id="languages-' . $section->name . '" class="languages-tabs">';
        
        // Zakładki języków
        $out .= '<ul class="resp-tabs-list languages-tabs htabs">';
        foreach ($this->form->languages as $lang) {
            if ($lang['status']) {
                $out .= '<li>' . htmlspecialchars($lang['name']) . '</li>';
            }
        }
        $out .= '</ul>';
        
        // Kontenery języków
        $out .= '<div class="resp-tabs-container languages-tabs">';
        foreach ($this->form->languages as $lang) {
            if ($lang['status']) {
                $out .= '<div>';
                foreach ($section->langFields as $field) {
                    $out .= $this->renderLangField($field, $lang['id'], $section->name);
                }
                $out .= '</div>';
            }
        }
        $out .= '</div>';
        
        $out .= '</div>';
        
        return $out;
    }

    /**
     * Renderuje pole w sekcji językowej
     */
    private function renderLangField(FormField $field, $languageId, string $sectionName): string
    {
        $value = $this->form->getFieldValue($field, $languageId, $field->name);
        $error = $this->form->getError($sectionName . '_' . $field->name, $languageId);
        
        $name = $field->getLocalizedName($languageId);
        $id = $field->getLocalizedId($languageId);
        
        switch ($field->type) {
            case FormFieldType::IMAGE:
                $filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($id);
                return $this->wrapWithError(\Shared\Html\Html::input_icon([
                    'label' => $field->label,
                    'name' => $name,
                    'id' => $id,
                    'value' => $value ?? '',
                    'type' => 'text',
                    'icon_content' => 'przeglądaj',
                    'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
                ]), $error);
                
            case FormFieldType::TEXTAREA:
            case FormFieldType::EDITOR:
                return $this->wrapWithError(\Shared\Html\Html::textarea([
                    'label' => $field->label,
                    'name' => $name,
                    'id' => $id,
                    'value' => $value ?? '',
                    'rows' => $field->type === FormFieldType::EDITOR ? 10 : ($field->attributes['rows'] ?? 4),
                    'class' => $field->type === FormFieldType::EDITOR ? 'editor' : '',
                ]), $error);
                
            case FormFieldType::SWITCH:
                return \Shared\Html\Html::input_switch([
                    'label' => $field->label,
                    'name' => $name,
                    'id' => $id,
                    'checked' => (bool) $value,
                ]);

            case FormFieldType::SELECT:
                return $this->wrapWithError(\Shared\Html\Html::select([
                    'label' => $field->label,
                    'name' => $name,
                    'id' => $id,
                    'value' => $value ?? '',
                    'values' => $field->options,
                    'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
                ]), $error);
                
            default: // TEXT, URL, etc.
                if (!empty($field->attributes['icon_content'])) {
                    $iconJs = (string)($field->attributes['icon_js'] ?? '');
                    if ($iconJs !== '') {
                        $iconJs = str_replace('{lang}', (string)$languageId, $iconJs);
                    }

                    return $this->wrapWithError(\Shared\Html\Html::input_icon([
                        'label' => $field->label,
                        'name' => $name,
                        'id' => $id,
                        'value' => $value ?? '',
                        'type' => $field->type === FormFieldType::EMAIL ? 'email' : 'text',
                        'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
                        'icon_content' => (string)$field->attributes['icon_content'],
                        'icon_class' => (string)($field->attributes['icon_class'] ?? ''),
                        'icon_js' => $iconJs,
                    ]), $error);
                }

                return $this->wrapWithError(\Shared\Html\Html::input([
                    'label' => $field->label,
                    'name' => $name,
                    'id' => $id,
                    'value' => $value ?? '',
                    'type' => $field->type === FormFieldType::EMAIL ? 'email' : 'text',
                    'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
                ]), $error);
        }
    }

    /**
     * Generuje URL do filemanagera
     */
    private function generateFilemanagerUrl(string $fieldId): string
    {
        $rfmAkey = $_SESSION['rfm_akey'] ?? bin2hex(random_bytes(16));
        $_SESSION['rfm_akey'] = $rfmAkey;
        $_SESSION['rfm_akey_expires'] = time() + 20 * 60;
        $_SESSION['can_use_rfm'] = true;

        $fieldIdParam = rawurlencode($fieldId);
        $akeyParam = rawurlencode($rfmAkey);
        return "/libraries/filemanager-9.14.2/dialog.php?type=1&popup=1&field_id={$fieldIdParam}&akey={$akeyParam}";
    }

    /**
     * Opakowuje pole w kontener błędu
     */
    private function wrapWithError(string $html, ?string $error): string
    {
        if ($error) {
            return '<div class="field-with-error">' . $html . 
                   '<span class="error-message">' . htmlspecialchars($error) . '</span></div>';
        }
        return $html;
    }
}
