<?php

namespace App\Exports;

use Carbon\Carbon;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;

class AccountReceivableExport implements FromCollection, WithHeadings, WithStyles, WithEvents
{
    protected $data;

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

    /**
     * Colección de datos para el Excel
     */
    public function collection()
    {
        # Retornamos una colección vacía porque cargaremos manualmente los datos en AfterSheet
        return collect([]);
    }

    /**
     * Encabezados para el Excel
     */
    public function headings(): array
    {
        return [
            ['', 'Vencidas', 'No vencidas', 'Total'],
            [
                'N° Facturas',
                (string) ($this->data['summary']['accounts_receivable_expired'] ?? 0),
                (string) ($this->data['summary']['accounts_receivable_not_expired'] ?? 0),
                (string) ($this->data['summary']['accounts_receivable'] ?? 0)
            ],
            [
                'Monto',
                $this->data['summary']['amount_receivable_expired'] ?? 0,
                $this->data['summary']['amount_receivable_not_expired'] ?? 0,
                $this->data['summary']['amount_receivable'] ?? 0
            ],
            [],
        ];
    }


    /**
     * Estilos y Totales en el Excel
     */
    public function styles(Worksheet $sheet)
    {
        # Estilo para encabezado superior
        $sheet->getStyle('B1:D1')->applyFromArray([
            'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
            'fill' => [
                'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                'color' => ['rgb' => '69ABC3']
            ]
        ]);

        # Estilo para encabezado izquierdo
        $sheet->getStyle('A1:A3')->applyFromArray([
            'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
            'fill' => [
                'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                'color' => ['rgb' => '69ABC3']
            ],
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
            ]
        ]);

        # Bordes para la tabla de dos entradas
        $sheet->getStyle('A1:D3')->applyFromArray([
            'borders' => [
                'allBorders' => [
                    'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                    'color' => ['argb' => '000000'],
                ],
            ],
        ]);

        # Ajuste de tamaño automático de columnas
        foreach (range('A', 'G') as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }
    }

    /**
     * Evento AfterSheet para cargar datos manualmente y ajustar la posición
     */
    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function (AfterSheet $event) {
                $sheet = $event->sheet;

                # Insertar una fila al inicio para el título
                $sheet->insertNewRowBefore(1, 1);

                # Fusionar celdas para el título y centrarlo
                $sheet->setCellValue('A1', $this->data['name_rz'] . ' - ' . $this->data['rut']);
                $sheet->mergeCells('A1:G1');
                $sheet->getStyle('A1')->applyFromArray([
                    'font' => [
                        'bold' => true,
                        'size' => 14,
                    ],
                    'alignment' => [
                        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                        'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
                    ],
                ]);

                # Formato de moneda chilena para el resumen de montos
                $sheet->getStyle("B3:D3")
                    ->getNumberFormat()
                    ->setFormatCode('"$" #,##0');

                # Fila inicial para la tabla de detalles
                $startRow = 6;

                # Encabezado de tabla de detalles
                $sheet->setCellValue("A{$startRow}", 'Folio');
                $sheet->setCellValue("B{$startRow}", 'Forma de pago');
                $sheet->setCellValue("C{$startRow}", 'Emisión');
                $sheet->setCellValue("D{$startRow}", 'Vencimiento');
                $sheet->setCellValue("E{$startRow}", 'Total Factura');
                $sheet->setCellValue("F{$startRow}", 'Monto Pagado');
                $sheet->setCellValue("G{$startRow}", 'Saldo Pendiente');

                # Estilo para encabezado de tabla de detalles
                $sheet->getStyle("A{$startRow}:G{$startRow}")->applyFromArray([
                    'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                    'fill' => [
                        'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                        'color' => ['rgb' => '69ABC3']
                    ],
                    'alignment' => [
                        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                        'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
                    ]
                ]);

                # Insertar datos de cuentas por cobrar
                $currentRow = $startRow + 1;
                foreach ($this->data['accounts'] as $index => $account) {
                    $sheet->setCellValue("A{$currentRow}", $account['ticket']['folio'] ?? '-');
                    $sheet->setCellValue("B{$currentRow}", $account['ticket']['wayToPay']['name'] ?? '-');
                    $sheet->setCellValue("C{$currentRow}", $account['ticket']['created_at'] ?? '-');
                    $sheet->setCellValue("D{$currentRow}", $account['deadline'] ?? 'N/A');
                    $sheet->setCellValue("E{$currentRow}", $account['total']);
                    $sheet->setCellValue("F{$currentRow}", $account['amount_paid'] ?? '0');
                    $sheet->setCellValue("G{$currentRow}", $account['debt']);

                    if ($account['deadline'] < Carbon::now()->toDateString()) {
                        $sheet->getStyle("A{$currentRow}:G{$currentRow}")->applyFromArray([
                            'fill' => [
                                'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                                'color' => [
                                    'rgb' => 'FFDAB9'
                                ]
                            ]
                        ]);
                    }

                    $sheet->setCellValue("C{$currentRow}", \PhpOffice\PhpSpreadsheet\Shared\Date::stringToExcel(Carbon::parse($account['ticket']['created_at'])->format('Y-m-d H:i')));
                    $sheet->getStyle("C{$currentRow}")
                        ->getNumberFormat()
                        ->setFormatCode('dd/mm/yyyy hh:mm');

                    $sheet->setCellValue("D{$currentRow}", \PhpOffice\PhpSpreadsheet\Shared\Date::stringToExcel(Carbon::parse($account['deadline'])->format('Y-m-d')));
                    $sheet->getStyle("D{$currentRow}")
                        ->getNumberFormat()
                        ->setFormatCode('dd/mm/yyyy');

                    $currentRow++;
                }

                # Formato de moneda chilena para las columnas de montos
                $sheet->getStyle("B4:D4")
                    ->getNumberFormat()
                    ->setFormatCode('"$" #,##0');

                $sheet->getStyle("E" . ($startRow + 1) . ":G" . ($currentRow - 1))
                    ->getNumberFormat()
                    ->setFormatCode('"$" #,##0');

                # Bordes para tabla de detalles
                $sheet->getStyle("A{$startRow}:G" . ($currentRow - 1))->applyFromArray([
                    'borders' => [
                        'allBorders' => [
                            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                            'color' => ['argb' => '000000'],
                        ],
                    ],
                ]);

                # Fila para los totales
                $totalRow = $currentRow;

                # Colocar el texto Total en la primera celda de la fila de totales y centrarlo
                $sheet->setCellValue("A{$totalRow}", 'Total');
                $sheet->mergeCells("A{$totalRow}:D{$totalRow}");
                # Estilo para la celda 'Total' en A y el merge de A a D
                $sheet->getStyle("A{$totalRow}:D{$totalRow}")->applyFromArray([
                    'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                    'fill' => [
                        'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                        'color' => ['rgb' => '69ABC3']
                    ],
                    'alignment' => [
                        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                        'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
                    ],
                    'borders' => [
                        'allBorders' => [
                            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                            'color' => ['argb' => '000000'],
                        ],
                    ],
                ]);

                # Calcular sumatorias para Total Factura, Monto Pagado y Saldo Pendiente
                $sheet->setCellValue("E{$totalRow}", "=SUM(E" . ($startRow + 1) . ":E" . ($currentRow - 1) . ")");
                $sheet->setCellValue("F{$totalRow}", "=SUM(F" . ($startRow + 1) . ":F" . ($currentRow - 1) . ")");
                $sheet->setCellValue("G{$totalRow}", "=SUM(G" . ($startRow + 1) . ":G" . ($currentRow - 1) . ")");

                # Aplicar formato de moneda chilena a la fila de totales
                $sheet->getStyle("E{$totalRow}:G{$totalRow}")
                    ->getNumberFormat()
                    ->setFormatCode('"$" #,##0');

                # Estilo para las celdas de totales
                $sheet->getStyle("E{$totalRow}:G{$totalRow}")->applyFromArray([
                    'font' => ['bold' => true],
                    'fill' => [
                        'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
                        'color' => ['rgb' => '69ABC3']
                    ],
                    'alignment' => [
                        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
                        'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
                    ],
                    'borders' => [
                        'allBorders' => [
                            'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
                            'color' => ['argb' => '000000'],
                        ],
                    ],
                ]);
            }
        ];
    }
}
