<?php
/**
 * Controlador de Letras
 * CRUD de letras con registro en lote
 */
class LetraController
{
    private Letra $letraModel;
    private Empresa $empresaModel;
    private GrupoLetra $grupoModel;

    public function __construct()
    {
        $this->letraModel   = new Letra();
        $this->empresaModel = new Empresa();
        $this->grupoModel   = new GrupoLetra();
    }

    /**
     * Listado de letras
     */
    public function index(): void
    {
        $filtroEstado = $_GET['estado'] ?? '';
        $empresaId    = isset($_GET['empresa_id']) ? (int)$_GET['empresa_id'] : 0;
        $fechaDesde   = $_GET['fecha_desde'] ?? '';
        $fechaHasta   = $_GET['fecha_hasta'] ?? '';
        $fechaEmisionFactura = $_GET['fecha_emision_factura'] ?? '';
        $numeroLetra  = $_GET['numero_letra'] ?? '';

        // Si no se ha enviado empresa, no cargamos las letras por defecto para no saturar.
        // Solo cargamos si hay un filtro de empresa válido.
        if ($empresaId > 0 || !empty($fechaDesde) || !empty($fechaHasta) || !empty($fechaEmisionFactura) || !empty($numeroLetra) || !empty($filtroEstado)) {
            $letras = $this->letraModel->getAll($filtroEstado, $empresaId, $fechaDesde, $fechaHasta, $fechaEmisionFactura, $numeroLetra);
        } else {
            $letras = [];
        }

        $empresas = $this->empresaModel->getAll();

        // Alertas
        $alertas   = $this->letraModel->getAlertasVencimiento();
        $excedidas = $this->letraModel->getLetrasExcedidas();

        $pageTitle   = 'Letras';
        $currentPage = 'letras';

        loadView('layout/header', compact('pageTitle', 'currentPage'));
        loadView('layout/sidebar', compact('currentPage'));
        loadView('letras/index', compact('letras', 'empresas', 'filtroEstado', 'empresaId', 'fechaDesde', 'fechaHasta', 'fechaEmisionFactura', 'numeroLetra'));
        loadView('layout/footer', compact('currentPage', 'alertas', 'excedidas'));
    }

    /**
     * Formulario de registro de letras en lote
     */
    public function crear(): void
    {
        $empresas = $this->empresaModel->getAll();

        // Alertas
        $alertas   = $this->letraModel->getAlertasVencimiento();
        $excedidas = $this->letraModel->getLetrasExcedidas();

        $pageTitle   = 'Registrar Letras';
        $currentPage = 'letras';

        loadView('layout/header', compact('pageTitle', 'currentPage'));
        loadView('layout/sidebar', compact('currentPage'));
        loadView('letras/crear', compact('empresas'));
        loadView('layout/footer', compact('currentPage', 'alertas', 'excedidas'));
    }

    /**
     * Procesar formulario de registro en lote (POST)
     */
    public function guardar(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            redirect('?c=letras&a=crear');
            return;
        }

        try {
            // Datos del grupo
            $grupoData = [
                'empresa_id'           => (int)$_POST['empresa_id'],
                'serie'                => trim($_POST['serie'] ?? '001'),
                'documento_sunat'      => trim($_POST['documento_sunat'] ?? ''),
                'fecha_emision_factura' => $_POST['fecha_emision_factura'] ?? null,
                'moneda'               => $_POST['moneda'] ?? 'USD',
                'importe_factura'      => (float)($_POST['importe_factura'] ?? 0),
                'total_letras'         => 0,
                'observaciones'        => trim($_POST['observaciones_grupo'] ?? ''),
            ];

            // Datos de las letras
            $letrasData = [];
            $totalLetras = 0;
            $cantidadLetras = (int)($_POST['cantidad_letras'] ?? 0);

            for ($i = 0; $i < $cantidadLetras; $i++) {
                if (empty($_POST['numero_letra'][$i]) || empty($_POST['fecha_vencimiento'][$i])) {
                    continue;
                }

                $importe = (float)$_POST['importe'][$i];
                $totalLetras += $importe;

                $letrasData[] = [
                    'numero_letra'      => trim($_POST['numero_letra'][$i]),
                    'renovacion'        => (int)($_POST['renovacion'][$i] ?? 0),
                    'tipo_letra'        => $_POST['tipo_letra'][$i] ?? 'ORI',
                    'moneda'            => $_POST['moneda_letra'][$i] ?? $grupoData['moneda'],
                    'fecha_emision'     => $_POST['fecha_emision'][$i],
                    'plazo_dias'        => (int)$_POST['plazo_dias'][$i],
                    'fecha_vencimiento' => $_POST['fecha_vencimiento'][$i],
                    'importe'           => $importe,
                    'banco'             => trim($_POST['banco'][$i] ?? ''),
                    'referencia_unica'  => trim($_POST['referencia_unica'][$i] ?? ''),
                    'observaciones'     => trim($_POST['observaciones'][$i] ?? ''),
                ];
            }

            if (empty($letrasData)) {
                setFlash('error', 'Debe ingresar al menos una letra válida.');
                redirect('?c=letras&a=crear');
                return;
            }

            $grupoData['total_letras'] = $totalLetras;

            // Crear grupo con letras
            $grupoId = $this->grupoModel->crearConLetras($grupoData, $letrasData);

            setFlash('success', "Se registraron " . count($letrasData) . " letras correctamente (Grupo #{$grupoId}).");
            redirect('?c=letras');

        } catch (\Exception $e) {
            setFlash('error', 'Error al registrar: ' . $e->getMessage());
            redirect('?c=letras&a=crear');
        }
    }

    /**
     * Checklist de letras pendientes para acciones masivas
     */
    public function checklist(): void
    {
        $empresaId = isset($_GET['empresa_id']) ? (int)$_GET['empresa_id'] : 0;
        $fechaEmisionFactura = $_GET['fecha_emision_factura'] ?? '';
        $numeroLetra = $_GET['numero_letra'] ?? '';

        // Solo cargar "pendientes"
        $letras = $this->letraModel->getAll('pendiente', $empresaId, '', '', $fechaEmisionFactura, $numeroLetra);
        $empresas = $this->empresaModel->getAll();

        $pageTitle = 'Checklist Pendientes';
        $currentPage = 'letras';

        loadView('layout/header', compact('pageTitle', 'currentPage'));
        loadView('layout/sidebar', compact('currentPage'));
        loadView('letras/checklist', compact('letras', 'empresas', 'empresaId', 'fechaEmisionFactura', 'numeroLetra'));
        loadView('layout/footer', compact('currentPage'));
    }

    /**
     * Procesar actualización masiva a estado Pagada (POST)
     */
    public function marcarPagadasMasivo(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            echo json_encode(['error' => true, 'mensaje' => 'Método no permitido']);
            return;
        }

        $ids = $_POST['letras_ids'] ?? [];
        if (empty($ids) || !is_array($ids)) {
            echo json_encode(['error' => true, 'mensaje' => 'No se seleccionaron letras']);
            return;
        }

        $ids = array_map('intval', $ids);
        
        if ($this->letraModel->marcarPagadasMasivo($ids)) {
            echo json_encode(['error' => false, 'mensaje' => 'Letras marcadas como pagadas correctamente']);
        } else {
            echo json_encode(['error' => true, 'mensaje' => 'Error al actualizar letras']);
        }
    }



    /**
     * Formulario para renovar letra
     */
    public function renovar(): void
    {
        $id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
        $letra = $this->letraModel->getById($id);

        if (!$letra || !in_array($letra['estado'], ['pendiente', 'vencida'])) {
            setFlash('error', 'Esta letra no se puede renovar o no existe.');
            redirect('?c=letras');
            return;
        }

        $alertas   = $this->letraModel->getAlertasVencimiento();
        $excedidas = $this->letraModel->getLetrasExcedidas();

        $pageTitle   = 'Renovar Letra';
        $currentPage = 'letras';

        loadView('layout/header', compact('pageTitle', 'currentPage'));
        loadView('layout/sidebar', compact('currentPage'));
        loadView('letras/renovar', compact('letra'));
        loadView('layout/footer', compact('currentPage', 'alertas', 'excedidas'));
    }

    /**
     * Procesar renovación de letra (POST)
     */
    public function guardarRenovacion(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            redirect('?c=letras');
            return;
        }

        $id = (int)$_POST['id'];
        $letraOriginal = $this->letraModel->getById($id);

        if (!$letraOriginal) {
            setFlash('error', 'Letra no encontrada.');
            redirect('?c=letras');
            return;
        }

        $porcentajeAbono = (float)$_POST['porcentaje_abono'];
        $nuevoPlazo = (int)$_POST['nuevo_plazo'];
        
        if ($porcentajeAbono < 0 || $porcentajeAbono >= 100) {
            setFlash('error', 'Porcentaje de abono inválido. Debe ser menor a 100%.');
            redirect('?c=letras');
            return;
        }

        if (!in_array($nuevoPlazo, [7, 15, 30, 45, 60])) {
            setFlash('error', 'Plazo de renovación inválido.');
            redirect('?c=letras');
            return;
        }

        $importeAbonado = ($letraOriginal['importe'] * $porcentajeAbono) / 100;
        $nuevoImporte = $letraOriginal['importe'] - $importeAbonado;
        
        $fechaEmisionNueva = date('Y-m-d');
        $fechaVencimientoNueva = date('Y-m-d', strtotime($fechaEmisionNueva . " + $nuevoPlazo days"));

        $numeroRenovacion = $letraOriginal['renovacion'] + 1;
        
        // Formar el nuevo número (-R1, -R2, etc)
        $baseNumero = preg_replace('/-R\d+$/', '', $letraOriginal['numero_letra']);
        $nuevoNumero = $baseNumero . '-R' . $numeroRenovacion;

        $obsOriginal = $letraOriginal['observaciones'] . "\nRenovada el " . date('d/m/Y') . " con abono de {$letraOriginal['moneda']} " . number_format($importeAbonado, 2) . " ($porcentajeAbono%).";

        $nuevaLetra = [
            'grupo_id'          => $letraOriginal['grupo_id'],
            'empresa_id'        => $letraOriginal['empresa_id'],
            'numero_letra'      => $nuevoNumero,
            'numero_en_grupo'   => $letraOriginal['numero_en_grupo'],
            'renovacion'        => $numeroRenovacion,
            'tipo_letra'        => 'REN',
            'moneda'            => $letraOriginal['moneda'],
            'fecha_emision'     => $fechaEmisionNueva,
            'plazo_dias'        => $nuevoPlazo,
            'fecha_vencimiento' => $fechaVencimientoNueva,
            'importe'           => $nuevoImporte,
            'banco'             => $letraOriginal['banco'],
            'estado'            => 'pendiente',
            'referencia_unica'  => $letraOriginal['referencia_unica'],
            'observaciones'     => "Renovación de la letra {$letraOriginal['numero_letra']}."
        ];

        try {
            $this->letraModel->renovarLetra($id, $nuevaLetra, trim($obsOriginal));
            setFlash('success', 'La letra fue renovada correctamente. Se generó la letra ' . $nuevoNumero);
        } catch (\Exception $e) {
            setFlash('error', 'Error al renovar la letra: ' . $e->getMessage());
        }

        redirect('?c=letras');
    }

    /**
     * Formulario de edición de letra individual
     */
    public function editar(): void
    {
        $id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
        $letra = $this->letraModel->getById($id);

        if (!$letra) {
            setFlash('error', 'Letra no encontrada.');
            redirect('?c=letras');
            return;
        }

        $empresas = $this->empresaModel->getAll();

        // Alertas
        $alertas   = $this->letraModel->getAlertasVencimiento();
        $excedidas = $this->letraModel->getLetrasExcedidas();

        $pageTitle   = 'Editar Letra';
        $currentPage = 'letras';

        loadView('layout/header', compact('pageTitle', 'currentPage'));
        loadView('layout/sidebar', compact('currentPage'));
        loadView('letras/editar', compact('letra', 'empresas'));
        loadView('layout/footer', compact('currentPage', 'alertas', 'excedidas'));
    }

    /**
     * Actualizar letra (POST)
     */
    public function actualizar(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            redirect('?c=letras');
            return;
        }

        $id = (int)$_POST['id'];

        try {
            $data = [
                'numero_letra'      => trim($_POST['numero_letra']),
                'renovacion'        => (int)($_POST['renovacion'] ?? 0),
                'tipo_letra'        => $_POST['tipo_letra'] ?? 'ORI',
                'moneda'            => $_POST['moneda'] ?? 'USD',
                'fecha_emision'     => $_POST['fecha_emision'],
                'plazo_dias'        => (int)$_POST['plazo_dias'],
                'fecha_vencimiento' => $_POST['fecha_vencimiento'],
                'importe'           => (float)$_POST['importe'],
                'banco'             => trim($_POST['banco'] ?? ''),
                'estado'            => $_POST['estado'] ?? 'pendiente',
                'referencia_unica'  => trim($_POST['referencia_unica'] ?? ''),
                'observaciones'     => trim($_POST['observaciones'] ?? ''),
            ];

            $this->letraModel->update($id, $data);
            setFlash('success', 'Letra actualizada correctamente.');
        } catch (\Exception $e) {
            setFlash('error', 'Error al actualizar: ' . $e->getMessage());
        }

        redirect('?c=letras');
    }

    /**
     * Eliminar letra (POST)
     */
    public function eliminar(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            redirect('?c=letras');
            return;
        }

        $id = (int)$_POST['id'];

        try {
            $this->letraModel->delete($id);
            setFlash('success', 'Letra eliminada correctamente.');
        } catch (\Exception $e) {
            setFlash('error', 'Error al eliminar: ' . $e->getMessage());
        }

        redirect('?c=letras');
    }

    /**
     * Cambiar estado de letra (AJAX)
     */
    public function cambiarestado(): void
    {
        header('Content-Type: application/json');

        $id     = (int)($_POST['id'] ?? 0);
        $estado = $_POST['estado'] ?? '';

        $estadosValidos = ['pendiente', 'pagada', 'vencida', 'renovada', 'protestada'];
        
        if (!in_array($estado, $estadosValidos)) {
            echo json_encode(['error' => true, 'mensaje' => 'Estado no válido']);
            exit;
        }

        try {
            $this->letraModel->cambiarEstado($id, $estado);
            echo json_encode(['error' => false, 'mensaje' => 'Estado actualizado']);
        } catch (\Exception $e) {
            echo json_encode(['error' => true, 'mensaje' => $e->getMessage()]);
        }
        exit;
    }
}
