<?php

declare(strict_types=1);

namespace App\Controller;

use Dompdf\Dompdf;
use Dompdf\Options;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

class VistaReporteProductosController extends AppController
{
    private $VistaReporteProductos;

    public function initialize(): void
    {
        parent::initialize();
        $this->VistaReporteProductos = $this->fetchTable('VistaReporteProductos');
    }

    public function index()
    {
        $roles = [1]; // Roles permitidos
        if (!in_array($this->request->getAttribute('identity')->rol, $roles)) {
            $this->Flash->error(__('Acceso no autorizado.'));
            return $this->redirect($this->referer());
        }

        // Cargar la lista de proveedores y tipos de transacción
        $proveedoresTable = $this->fetchTable('Proveedores');
        $proveedores = $proveedoresTable->find('list', keyField: 'id', valueField: 'nombre')->toArray();
        $tiposTransaccionTable = $this->fetchTable('Transacciones');
        $tiposTransaccion = $tiposTransaccionTable->find()
            ->select(['tipo_transaccion'])
            ->distinct(['tipo_transaccion'])
            ->order(['tipo_transaccion' => 'ASC'])
            ->all()
            ->combine('tipo_transaccion', 'tipo_transaccion')
            ->toArray();

        // Filtrado de la vista con los parámetros pasados desde la vista
        $proveedorId = $this->request->getQuery('proveedor_id');
        $tipoTransaccion = $this->request->getQuery('tipo_transaccion');
        $startDate = $this->request->getQuery('start_date');
        $endDate = $this->request->getQuery('end_date');

        $query = $this->VistaReporteProductos->find();

        // Filtrar por fecha
        if (!empty($startDate) && !empty($endDate)) {
            try {
                $fechaInicio = new \DateTime($startDate, new \DateTimeZone('America/Lima'));
                $fechaFin = new \DateTime($endDate, new \DateTimeZone('America/Lima'));
                $fechaFin->modify('+1 day -1 second');

                $query->where([
                    't.fecha_transaccion >=' => $fechaInicio->format('Y-m-d H:i:s'),
                    't.fecha_transaccion <=' => $fechaFin->format('Y-m-d H:i:s'),
                ]);
            } catch (\Exception $e) {
                $this->Flash->error('Formato de fechas inválido.');
                return $this->redirect($this->referer());
            }
        }

        // Filtrar por proveedor
        if (!empty($proveedorId)) {
            $query->where(['proveedor_id' => $proveedorId]);
        }

        // Filtrar por tipo de transacción
        if (!empty($tipoTransaccion)) {
            $query->where(['VistaReporteProductos.tipo_transaccion' => $tipoTransaccion]);
        }

        // Ejecutar la consulta y obtener los resultados paginados
        $reportes = $this->paginate($query);

        // Pasar las variables necesarias a la vista
        $this->set(compact('reportes', 'proveedores', 'tiposTransaccion', 'proveedorId', 'tipoTransaccion', 'startDate', 'endDate'));
    }

    public function exportarPdf()
    {
        $proveedorId = $this->request->getQuery('proveedor_id');
        $tipoTransaccion = $this->request->getQuery('tipo_transaccion');
        $startDate = $this->request->getQuery('start_date');
        $endDate = $this->request->getQuery('end_date');

        if (empty($startDate) || empty($endDate)) {
            $this->Flash->error('Por favor, ingrese ambas fechas.');
            return $this->redirect(['action' => 'index']);
        }

        try {
            $fechaInicio = new \DateTime($startDate, new \DateTimeZone('America/Lima'));
            $fechaFin = new \DateTime($endDate, new \DateTimeZone('America/Lima'));
            $fechaFin->modify('+1 day -1 second');
        } catch (\Exception $e) {
            $this->Flash->error('Formato de fechas inválido.');
            return $this->redirect(['action' => 'index']);
        }

        $query = $this->VistaReporteProductos->find()
            ->where([
                'VistaReporteProductos.fecha_transaccion >=' => $fechaInicio->format('Y-m-d H:i:s'),
                'VistaReporteProductos.fecha_transaccion <=' => $fechaFin->format('Y-m-d H:i:s'),
            ]);

        if (!empty($proveedorId)) {
            $query->where(['proveedor_id' => $proveedorId]);
        }

        if (!empty($tipoTransaccion)) {
            $query->where(['tipo_transaccion' => $tipoTransaccion]);
        }

        $reportes = $query->toArray();

        $productosQuery = $this->VistaReporteProductos->find()
            ->select([
                'producto_id',
                'nombre_producto',
                'stock_actual'
            ])
            ->distinct(['producto_id'])
            ->order(['nombre_producto' => 'ASC']);

        $productos = $productosQuery->toArray();

        $this->viewBuilder()->disableAutoLayout();
        $this->set(compact('reportes', 'startDate', 'endDate', 'productos'));
        $html = $this->render('export_pdf')->getBody()->__toString();

        $options = new Options();
        $options->set('defaultFont', 'DejaVu Sans');
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        return $this->response
            ->withType('application/pdf')
            ->withStringBody($dompdf->output());
    }

    public function exportarExcel()
    {
        $this->autoRender = false;

        $proveedorId = $this->request->getQuery('proveedor_id');
        $contacto = $this->request->getQuery('contacto');
        $tipoTransaccion = $this->request->getQuery('tipo_transaccion');
        $startDate = $this->request->getQuery('start_date');
        $endDate = $this->request->getQuery('end_date');

        if (empty($startDate) || empty($endDate)) {
            $this->Flash->error('Por favor, ingrese ambas fechas.');
            return $this->redirect(['action' => 'index']);
        }

        if ($startDate > $endDate) {
            $this->Flash->error('La Fecha de Inicio no puede ser mayor que la Fecha Fin.');
            return $this->redirect(['action' => 'index']);
        }

        try {
            $fechaInicio = new \DateTime($startDate, new \DateTimeZone('America/Lima'));
            $fechaFin = new \DateTime($endDate, new \DateTimeZone('America/Lima'));
            $fechaFin->modify('+1 day -1 second');
        } catch (\Exception $e) {
            $this->Flash->error('Formato de fechas inválido.');
            return $this->redirect(['action' => 'index']);
        }

        $query = $this->VistaReporteProductos->find()
            ->where([
                'VistaReporteProductos.fecha_transaccion >=' => $fechaInicio->format('Y-m-d H:i:s'),
                'VistaReporteProductos.fecha_transaccion <=' => $fechaFin->format('Y-m-d H:i:s'),
            ]);

        if (!empty($proveedorId)) {
            $query->where(['proveedor_id' => $proveedorId]);
        }

        if (!empty($contacto)) {
            $query->where(['contacto_nombre LIKE' => '%' . $contacto . '%']);
        }

        if (!empty($tipoTransaccion)) {
            $query->where(['tipo_transaccion' => $tipoTransaccion]);
        }

        $reportes = $query->toArray();

        if (empty($reportes)) {
            $this->Flash->error('No se encontraron registros para exportar.');
            return null;
        }

        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        $sheet->setTitle('Reporte de Productos');

        $headers = ['Producto', 'Proveedor', 'Contacto', 'Tipo Transacción', 'Cantidad', 'Precio', 'Fecha', 'Stock Actual'];
        $sheet->fromArray($headers, null, 'A1');
        $sheet->getStyle('A1:G1')->getFont()->setBold(true);

        $row = 2;
        foreach ($reportes as $reporte) {
            $sheet->setCellValue("A$row", $reporte->nombre_producto);
            $sheet->setCellValue("B$row", $reporte->proveedor_nombre);
            $sheet->setCellValue("C$row", $reporte->contacto_nombre);
            $sheet->setCellValue("D$row", $reporte->tipo_transaccion);
            $sheet->setCellValue("E$row", $reporte->cantidad_transaccion);
            $sheet->setCellValue("F$row", $reporte->precio);
            $sheet->setCellValue("G$row", $reporte->fecha_transaccion);
            $sheet->setCellValue("H$row", $reporte->stock_actual);
            $row++;
        }

        foreach (range('A', 'G') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        $fileName = 'Reporte_Productos.xlsx';
        $tempFile = TMP . $fileName;

        $writer = new Xlsx($spreadsheet);
        $writer->save($tempFile);

        return $this->response
            ->withType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            ->withHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"')
            ->withFile($tempFile, ['download' => true, 'delete' => true]);
    }
}
