<?php

namespace App\Http\Controllers;

use App\Models\Configuracion;
use App\Models\OrdenTrabajo;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Carbon;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Shared\Converter;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\Style\Cell;

class InformeController extends Controller
{
    /**
     * Datos comunes para PDF y Word.
     */
    protected function datos(OrdenTrabajo $orden): array
    {
        $orden->load(['equipo.area','area','sistema','estado','responsable','items','fotos','costos','logs.usuario']);

        $dirigidoA = (string) Configuracion::obtener('informe_dirigido_a', '');
        $lineas = array_values(array_filter(array_map('trim', explode("\n", $dirigidoA))));

        $elaboradoNombre = trim((string) Configuracion::obtener('informe_elaborado_por_default', ''));
        $elaboradoCargo = trim((string) Configuracion::obtener('informe_elaborado_cargo_default', ''));
        if (auth()->check() && empty($elaboradoNombre)) {
            $elaboradoNombre = auth()->user()->nombre_completo ?: auth()->user()->usuario;
            $elaboradoCargo = auth()->user()->cargo ?: $elaboradoCargo;
        }

        return [
            'orden' => $orden,
            'cab' => [
                'tipo_documento' => Configuracion::obtener('informe_tipo_documento', 'Informe Interno'),
                'empresa_larga' => Configuracion::obtener('informe_empresa_larga', 'MEDSURSA'),
                'direccion' => Configuracion::obtener('informe_direccion', ''),
                'codigo_formato' => Configuracion::obtener('informe_codigo_formato', ''),
                'fecha_codigo' => Configuracion::obtener('informe_fecha_codigo', ''),
                'version' => Configuracion::obtener('informe_version', '01'),
                'sufijo' => Configuracion::obtener('informe_sufijo_codigo', ''),
                'logo' => public_path(Configuracion::obtener('logo_cuadrado', 'img/logo_cuadrado.png')),
                'fecha' => Carbon::now()->format('d/m/Y'),
            ],
            'numero_informe' => $this->formatearNumero($orden),
            'asunto' => $this->generarAsunto($orden),
            'destinatarios' => $lineas,
            'elaborado_nombre' => $elaboradoNombre,
            'elaborado_cargo' => $elaboradoCargo,
            'objetivo' => $orden->descripcion ?: '— (sin descripción)',
        ];
    }

    protected function formatearNumero(OrdenTrabajo $orden): string
    {
        $sufijo = Configuracion::obtener('informe_sufijo_codigo', '');
        return $orden->codigo . ($sufijo ? '-' . $sufijo : '');
    }

    protected function generarAsunto(OrdenTrabajo $orden): string
    {
        $clase = ucfirst($orden->clase);
        $equipo = optional($orden->equipo)->nombre ?? 'equipo';
        return "Mantenimiento {$clase} — {$equipo}";
    }

    public function pdf(OrdenTrabajo $orden)
    {
        $data = $this->datos($orden);
        $pdf = Pdf::loadView('informes.orden', $data)->setPaper('a4');
        return $pdf->stream("Informe_{$orden->codigo}.pdf");
    }

    public function word(OrdenTrabajo $orden)
    {
        $data = $this->datos($orden);
        $phpWord = new PhpWord();
        $phpWord->setDefaultFontName('Arial');
        $phpWord->setDefaultFontSize(10);

        $section = $phpWord->addSection([
            'marginLeft' => Converter::cmToTwip(2),
            'marginRight' => Converter::cmToTwip(2),
            'marginTop' => Converter::cmToTwip(1.5),
            'marginBottom' => Converter::cmToTwip(1.5),
        ]);

        $this->cabeceraWord($section, $data);
        $section->addTextBreak(1);

        // Título centrado
        $section->addText('INFORME INTERNO',
            ['bold' => true, 'size' => 14],
            ['alignment' => Jc::CENTER, 'spaceAfter' => 150]);

        // Bloque de información
        $this->bloqueInfoWord($section, $data);

        // Objetivo
        $section->addTextBreak(1);
        $section->addText('OBJETIVO', ['bold' => true, 'size' => 11, 'color' => '0D47A1']);
        $section->addText($data['objetivo'], ['size' => 10], ['alignment' => Jc::BOTH]);

        // Checklist
        if ($orden->items->count() > 0) {
            $section->addTextBreak(1);
            $section->addText('CHECKLIST DEL MANTENIMIENTO',
                ['bold' => true, 'size' => 11, 'color' => '0D47A1']);
            $this->tablaChecklistWord($section, $orden);
        }

        // Costos
        if ($orden->costos->count() > 0) {
            $section->addTextBreak(1);
            $section->addText('COSTOS', ['bold' => true, 'size' => 11, 'color' => '0D47A1']);
            $this->tablaCostosWord($section, $orden);
        }

        // Comentarios
        if ($orden->observaciones || $orden->observaciones_cierre) {
            $section->addTextBreak(1);
            $section->addText('COMENTARIOS', ['bold' => true, 'size' => 11, 'color' => '0D47A1']);
            if ($orden->observaciones) {
                $section->addText('Observaciones: ' . $orden->observaciones);
            }
            if ($orden->observaciones_cierre) {
                $section->addText('Observaciones de cierre: ' . $orden->observaciones_cierre);
            }
        }

        // Firmas al final
        $section->addTextBreak(3);
        $tableFirmas = $section->addTable(['width' => 100 * 50, 'unit' => 'pct', 'alignment' => Jc::CENTER]);
        $tableFirmas->addRow();
        foreach (['Responsable', 'Supervisor'] as $rol) {
            $cell = $tableFirmas->addCell(4500, ['borderTopSize' => 6, 'borderTopColor' => '000000']);
            $cell->addText('_____________________________', ['size' => 10], ['alignment' => Jc::CENTER]);
            $cell->addText($rol, ['bold' => true, 'size' => 10], ['alignment' => Jc::CENTER]);
        }

        // Stream
        $filename = "Informe_{$orden->codigo}.docx";
        $tempFile = tempnam(sys_get_temp_dir(), 'phpword') . '.docx';
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $objWriter->save($tempFile);

        return response()->download($tempFile, $filename, [
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        ])->deleteFileAfterSend(true);
    }

    private function cabeceraWord(Section $section, array $data): void
    {
        $cab = $data['cab'];
        $table = $section->addTable([
            'borderSize' => 6, 'borderColor' => '666666',
            'cellMargin' => 60, 'width' => 100 * 50, 'unit' => 'pct',
        ]);
        $table->addRow();

        // Celda 1: logo
        $cellLogo = $table->addCell(2200, ['valign' => 'center']);
        if (file_exists($cab['logo'])) {
            $cellLogo->addImage($cab['logo'], [
                'width' => 65, 'height' => 65, 'alignment' => Jc::CENTER,
            ]);
        }

        // Celda 2: tipo doc + empresa + direccion
        $cellEmpresa = $table->addCell(6000, ['valign' => 'center']);
        $cellEmpresa->addText('Tipo de Documento: ' . $cab['tipo_documento'],
            ['size' => 9], ['alignment' => Jc::CENTER, 'spaceAfter' => 60]);
        $cellEmpresa->addText($cab['empresa_larga'],
            ['bold' => true, 'size' => 10], ['alignment' => Jc::CENTER, 'spaceAfter' => 40]);
        $cellEmpresa->addText($cab['direccion'],
            ['size' => 8], ['alignment' => Jc::CENTER]);

        // Celda 3: código + versión
        $cellCodigo = $table->addCell(2800, ['valign' => 'center']);
        $cellCodigo->addText('Código de Formato:',
            ['size' => 9], ['alignment' => Jc::CENTER]);
        $cellCodigo->addText($cab['codigo_formato'] . ' / ' . $cab['fecha_codigo'],
            ['size' => 9, 'underline' => 'single'], ['alignment' => Jc::CENTER, 'spaceAfter' => 40]);
        $cellCodigo->addText('Versión: ' . $cab['version'],
            ['size' => 9], ['alignment' => Jc::CENTER]);
    }

    private function bloqueInfoWord(Section $section, array $data): void
    {
        // Encabezado azul + datos
        $azul = '1565C0';
        $blanco = 'FFFFFF';

        $tbl = $section->addTable([
            'borderSize' => 6, 'borderColor' => '666666',
            'cellMargin' => 80, 'width' => 100 * 50, 'unit' => 'pct',
        ]);

        // Fila 1: N° INFORME | Fecha
        $tbl->addRow();
        $c1 = $tbl->addCell(8000, ['bgColor' => $azul, 'valign' => 'center']);
        $c1->addText('INFORME N° ' . $data['numero_informe'],
            ['bold' => true, 'size' => 10, 'color' => $blanco]);
        $c2 = $tbl->addCell(3000, ['bgColor' => $azul, 'valign' => 'center']);
        $c2->addText('Fecha: ' . $data['cab']['fecha'],
            ['bold' => true, 'size' => 10, 'color' => $blanco]);

        // Fila 2: Asunto
        $tbl->addRow();
        $tbl->addCell(2500, ['bgColor' => $azul, 'valign' => 'center'])
            ->addText('Asunto:', ['bold' => true, 'size' => 10, 'color' => $blanco]);
        $tbl->addCell(8500, ['valign' => 'center'])
            ->addText($data['asunto'], ['size' => 10]);

        // Fila 3: Dirigido a
        $tbl->addRow();
        $cellDirAcc = $tbl->addCell(2500, ['valign' => 'top']);
        $cellDirAcc->addText('Dirigido a:', ['bold' => true, 'size' => 10]);
        $cellDir = $tbl->addCell(8500, ['valign' => 'top']);
        foreach ($data['destinatarios'] as $i => $linea) {
            // Cargos (las líneas pares en el patrón Nombre/Cargo) suelen ser cargos en negrita
            $esCargo = $this->parecesCargo($linea);
            $cellDir->addText($linea, [
                'bold' => $esCargo, 'size' => 10,
            ], ['spaceAfter' => 20]);
        }

        // Fila 4: Elaborado por
        $tbl->addRow();
        $tbl->addCell(2500, ['valign' => 'center'])
            ->addText('Elaborado por:', ['bold' => true, 'size' => 10]);
        $cellElab = $tbl->addCell(8500, ['valign' => 'center']);
        $textRun = $cellElab->addTextRun();
        $textRun->addText($data['elaborado_nombre'] . '   ', ['size' => 10]);
        if ($data['elaborado_cargo']) {
            $textRun->addText($data['elaborado_cargo'], ['bold' => true, 'size' => 10]);
        }
    }

    /**
     * Heurística: las líneas que empiezan con un sustantivo que típicamente es cargo
     * (Gerente, Encargado, Super Intendente, etc.) o las posiciones pares de la lista
     * se asumen como cargos.
     */
    private function parecesCargo(string $linea): bool
    {
        $cargos = ['Gerente','Encargado','Super Intendente','Superintendente','Jefe','Director','Coordinador','Supervisor'];
        foreach ($cargos as $c) {
            if (stripos($linea, $c) !== false) return true;
        }
        return false;
    }

    private function tablaChecklistWord(Section $section, OrdenTrabajo $orden): void
    {
        $tbl = $section->addTable([
            'borderSize' => 6, 'borderColor' => '666666',
            'cellMargin' => 60, 'width' => 100 * 50, 'unit' => 'pct',
        ]);
        $headerStyle = ['bold' => true, 'size' => 9, 'color' => 'FFFFFF'];
        $headerCell = ['bgColor' => '1565C0', 'valign' => 'center'];
        $tbl->addRow();
        foreach ([['#',500],['Descripción',5000],['L',400],['I',400],['Lu',400],['A',400],['Estado',1500],['Observaciones',2200]] as [$h,$w]) {
            $tbl->addCell($w, $headerCell)->addText($h, $headerStyle, ['alignment' => Jc::CENTER]);
        }
        foreach ($orden->items as $it) {
            $tbl->addRow();
            $tbl->addCell(500, ['valign'=>'center'])->addText((string)$it->numero_item, ['size'=>9], ['alignment'=>Jc::CENTER]);
            $tbl->addCell(5000, ['valign'=>'center'])->addText($it->descripcion, ['size'=>9]);
            foreach (['lila_l_limpieza','lila_i_inspeccion','lila_l_lubricacion','lila_a_ajuste'] as $f) {
                $tbl->addCell(400, ['valign'=>'center'])->addText($it->$f ? 'X' : '', ['size'=>9], ['alignment'=>Jc::CENTER]);
            }
            $tbl->addCell(1500, ['valign'=>'center'])->addText(str_replace('_',' ',$it->estado_item), ['size'=>9]);
            $tbl->addCell(2200, ['valign'=>'center'])->addText((string)$it->observaciones, ['size'=>9]);
        }
    }

    private function tablaCostosWord(Section $section, OrdenTrabajo $orden): void
    {
        $tbl = $section->addTable([
            'borderSize' => 6, 'borderColor' => '666666',
            'cellMargin' => 60, 'width' => 100 * 50, 'unit' => 'pct',
        ]);
        $headerStyle = ['bold' => true, 'size' => 9, 'color' => 'FFFFFF'];
        $headerCell = ['bgColor' => '1565C0', 'valign' => 'center'];
        $tbl->addRow();
        foreach ([['Concepto',5000],['Tipo',1500],['Cant.',1200],['C. unit.',1200],['Total',1500]] as [$h,$w]) {
            $tbl->addCell($w, $headerCell)->addText($h, $headerStyle, ['alignment' => Jc::CENTER]);
        }
        foreach ($orden->costos as $c) {
            $tbl->addRow();
            $tbl->addCell(5000)->addText($c->concepto, ['size'=>9]);
            $tbl->addCell(1500)->addText(str_replace('_',' ',$c->tipo), ['size'=>9]);
            $tbl->addCell(1200)->addText(rtrim(rtrim(number_format($c->cantidad,3),'0'),'.'), ['size'=>9], ['alignment'=>Jc::RIGHT]);
            $tbl->addCell(1200)->addText(number_format($c->costo_unitario,2), ['size'=>9], ['alignment'=>Jc::RIGHT]);
            $tbl->addCell(1500)->addText(number_format($c->costo_total,2), ['size'=>9], ['alignment'=>Jc::RIGHT]);
        }
        $tbl->addRow();
        $totalCell = $tbl->addCell(8900, ['bgColor' => 'EEEEFF', 'gridSpan' => 4]);
        $totalCell->addText('TOTAL', ['bold'=>true,'size'=>10], ['alignment'=>Jc::RIGHT]);
        $tbl->addCell(1500, ['bgColor' => 'EEEEFF'])
            ->addText(number_format($orden->costo_total,2), ['bold'=>true,'size'=>10], ['alignment'=>Jc::RIGHT]);
    }
}
