<?php

namespace App\Livewire\Inspections;

use App\Models\InspectionTemplate;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Attributes\On;
use Livewire\Component;
use Livewire\WithFileUploads;
use PhpOffice\PhpSpreadsheet\IOFactory;

#[Layout('layouts.app')]
class GlobalTemplateManager extends Component
{
    use WithFileUploads;

    public $templates;

    public $editingTemplate = null;

    public $showForm = false;

    public $form = [
        'name' => '',
        'description' => '',
        'fields' => [],
    ];

    // ── Importar desde CSV/Excel ───────────────────────────────────────────
    public $showImportFileModal = false;

    public $importFile = null;

    public $importPreviewFields = [];

    public $importTemplateName = '';

    public $importError = '';

    public $fieldTypes = [
        'text' => 'Texto corto',
        'textarea' => 'Texto largo',
        'integer' => 'Número entero',
        'decimal' => 'Número decimal',
        'percentage' => 'Porcentaje (0-100)',
        'boolean' => 'Sí/No (checkbox)',
        'date' => 'Fecha',
        'select' => 'Lista desplegable',
    ];

    public function mount()
    {
        abort_unless(Auth::user()->can('manage templates'), 403);
        $this->loadTemplates();
    }

    public function loadTemplates()
    {
        // Catálogo global: todas las plantillas.
        $this->templates = InspectionTemplate::orderBy('name')->get();
    }

    public function newTemplate()
    {
        $this->resetForm();
        $this->showForm = true;
    }

    #[On('template-edit')]
    public function editTemplate($id)
    {
        $template = InspectionTemplate::findOrFail($id);
        $this->form = [
            'name' => $template->name,
            'description' => $template->description ?? '',
            'fields' => $template->fields ?? [],
        ];
        $this->editingTemplate = $id;
        $this->showForm = true;
    }

    public function cancelForm()
    {
        $this->showForm = false;
        $this->resetForm();
    }

    public function resetForm()
    {
        $this->form = [
            'name' => '',
            'description' => '',
            'fields' => [],
        ];
        $this->editingTemplate = null;
    }

    public function addField()
    {
        $this->form['fields'][] = [
            'group' => '',
            'name' => '',
            'label' => '',
            'question' => '',
            'type' => 'text',
            'options' => '',
            'required' => false,
            'min' => null,
            'max' => null,
            'step' => null,
            'help' => '',
        ];
    }

    public function removeField($index)
    {
        unset($this->form['fields'][$index]);
        $this->form['fields'] = array_values($this->form['fields']);
    }

    public function saveTemplate()
    {
        $this->validate([
            'form.name' => 'required|string|max:255',
            'form.fields' => 'array',
        ]);

        $data = [
            'name' => $this->form['name'],
            'description' => $this->form['description'],
            'project_id' => null,
            'fields' => array_values($this->form['fields']),
        ];

        if ($this->editingTemplate) {
            InspectionTemplate::findOrFail($this->editingTemplate)->update($data);
            $this->dispatch('notify', 'Plantilla actualizada');
        } else {
            InspectionTemplate::create($data);
            $this->dispatch('notify', 'Plantilla creada');
        }

        $this->cancelForm();
        $this->loadTemplates();
        $this->dispatch('templates-changed');
    }

    #[On('template-delete')]
    public function deleteTemplate($id)
    {
        InspectionTemplate::findOrFail($id)->delete();
        $this->loadTemplates();
        $this->dispatch('templates-changed');
        $this->dispatch('notify', 'Plantilla eliminada');
    }

    // ── Importar desde CSV/Excel ───────────────────────────────────────────

    public function openImportFileModal()
    {
        $this->importFile = null;
        $this->importPreviewFields = [];
        $this->importTemplateName = '';
        $this->importError = '';
        $this->showImportFileModal = true;
    }

    public function downloadExampleCsv()
    {
        $headers = ['Content-Type' => 'text/csv'];
        $csv = "\xEF\xBB\xBF" // BOM UTF-8 (para que Excel respete los acentos)
             ."group,name,label,question,type,required,options,min,max,step,help\n"
             ."Dimensiones,altura,Altura (m),¿Cumple la altura de proyecto?,decimal,1,,0,100,0.1,Medir con flexómetro\n"
             ."Dimensiones,material,Material,,select,1,Hormigón|Acero|Madera,,,,\n"
             ."Acabados,ok,¿Acabado correcto?,,boolean,1,,,,,\n";

        return response()->streamDownload(fn () => print ($csv), 'plantilla_ejemplo.csv', $headers);
    }

    public function parseImportFile()
    {
        $this->importError = '';
        $this->validate([
            'importFile' => 'required|file|mimes:csv,txt,xlsx,xls|max:5120',
            'importTemplateName' => 'required|string|max:255',
        ]);

        try {
            $rows = $this->readFileRows();
        } catch (\Throwable $e) {
            $this->importError = 'No se pudo leer el archivo: '.$e->getMessage();

            return;
        }

        $fields = $this->parseRows($rows);
        if (empty($fields)) {
            $this->importError = 'No se encontraron filas válidas.';

            return;
        }
        $this->importPreviewFields = $fields;
    }

    public function confirmImportFile()
    {
        if (empty($this->importPreviewFields) || empty($this->importTemplateName)) {
            return;
        }

        InspectionTemplate::create([
            'name' => $this->importTemplateName,
            'description' => 'Importado desde archivo',
            'project_id' => null,
            'fields' => array_values($this->importPreviewFields),
        ]);

        $this->showImportFileModal = false;
        $this->importPreviewFields = [];
        $this->importTemplateName = '';
        $this->importFile = null;
        $this->loadTemplates();
        $this->dispatch('templates-changed');
        $this->dispatch('notify', 'Plantilla importada');
    }

    private function readFileRows(): array
    {
        $ext = strtolower($this->importFile->getClientOriginalExtension());
        $path = $this->importFile->getRealPath();

        // Fila no vacía = tiene al menos una celda con contenido (no filtramos por
        // la primera columna, que ahora es `group` y puede ir vacía). parseRows()
        // ya descarta las filas sin `name`.
        $notEmpty = fn ($r) => count(array_filter((array) $r, fn ($c) => trim((string) $c) !== '')) > 0;

        if ($ext === 'xlsx' || $ext === 'xls') {
            $spreadsheet = IOFactory::load($path);
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray(null, true, true, false);
            array_shift($rows);

            return array_values(array_filter($rows, $notEmpty));
        }

        $rows = [];
        $handle = fopen($path, 'r');
        $bom = fread($handle, 3);
        if ($bom !== "\xEF\xBB\xBF") {
            rewind($handle);
        }
        fgetcsv($handle);
        while (($row = fgetcsv($handle)) !== false) {
            if ($notEmpty($row)) {
                $rows[] = $row;
            }
        }
        fclose($handle);

        return $rows;
    }

    private function parseRows(array $rows): array
    {
        // Orden de columnas:
        // group, name, label, question, type, required, options, min, max, step, help
        $fields = [];
        foreach ($rows as $row) {
            $row = array_values((array) $row);
            $rawName = trim($row[1] ?? '');
            if ($rawName === '') {
                continue;
            }

            $fields[] = [
                'group' => trim($row[0] ?? ''),
                'name' => $this->slugify($rawName),
                'label' => trim($row[2] ?? '') ?: $rawName,
                'question' => trim($row[3] ?? ''),
                'type' => $this->normalizeType($row[4] ?? 'text'),
                'required' => in_array(strtolower(trim($row[5] ?? '0')), ['1', 'si', 'sí', 'yes', 'true']),
                'options' => trim($row[6] ?? ''),
                'min' => ($row[7] ?? '') !== '' ? $row[7] : null,
                'max' => ($row[8] ?? '') !== '' ? $row[8] : null,
                'step' => ($row[9] ?? '') !== '' ? $row[9] : null,
                'help' => trim($row[10] ?? ''),
            ];
        }

        return $fields;
    }

    private function slugify(string $str): string
    {
        $str = mb_strtolower(trim($str));
        $str = preg_replace('/\s+/', '_', $str);
        $str = preg_replace('/[^a-z0-9_]/i', '', $str);

        return trim($str, '_') ?: 'campo';
    }

    private function normalizeType(string $type): string
    {
        $map = [
            'texto' => 'text', 'text' => 'text', 'string' => 'text', 'corto' => 'text',
            'textarea' => 'textarea', 'largo' => 'textarea', 'parrafo' => 'textarea',
            'integer' => 'integer', 'entero' => 'integer', 'int' => 'integer', 'numero' => 'integer',
            'decimal' => 'decimal', 'float' => 'decimal', 'number' => 'decimal', 'numerico' => 'decimal',
            'percentage' => 'percentage', 'porcentaje' => 'percentage', 'pct' => 'percentage', '%' => 'percentage',
            'boolean' => 'boolean', 'bool' => 'boolean', 'checkbox' => 'boolean', 'sino' => 'boolean', 'si/no' => 'boolean',
            'date' => 'date', 'fecha' => 'date',
            'select' => 'select', 'lista' => 'select', 'dropdown' => 'select', 'opciones' => 'select',
        ];

        return $map[strtolower(trim($type))] ?? 'text';
    }

    public function render()
    {
        return view('livewire.inspections.global-template-manager');
    }
}
