<?php

namespace App\Providers\ExcelTrainsReport;

use App\Http\Helpers\DateTime;

class TrainsCells
{

    private function titleMerge($text)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'border'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'bold'],
            ['action' => 'merge', 'lines' => 1],
            ['action' => 'border'],
        ];
    }
    private function title($text)
    {
        return [['action' => 'wrap'], ['action' => 'border'], ['action' => 'print', 'text' => $text], ['action' => 'bold']];
    }
    private function titleNoBorders($text)
    {
        return [['action' => 'wrap'], ['action' => 'print', 'text' => $text], ['action' => 'bold'], ['action' => 'merge', 'lines' => 1],];
    }
    private function column($text)
    {
        return [['action' => 'wrap'], ['action' => 'border'], ['action' => 'print', 'text' => $text]];
    }
    private function columnMerge($text)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'border'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'merge', 'lines' => 1],
            ['action' => 'border'],
        ];
    }



    private function emptyCell()
    {
        return [['action' => 'print', 'text' => '']];
    }

    private function blankRow()
    {
        return array_fill(0, 24, $this->emptyCell());
    }

    private function columnVMerge($text, $lines)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'border'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'vmerge', 'lines' => $lines],
            ['action' => 'border'],
        ];
    }

    private function createUpgrades(array $upgrades)
    {
        $rows = [
            [
                $this->title('N°'),
                $this->title('BOOKING CODE'),
                $this->title('PASAJEROS'),
                $this->title('TIPO DOC.'),
                $this->title('DOCUMENTO'),
                $this->title('NACIONALIDAD'),
                $this->title('INGRESO'),
                $this->title('RETORNO'),
                $this->title('PRECIO'),
                $this->title('CÓDIGO'),

                $this->title('ESTADO'),
                $this->title('FECHA DE PAGO'),
                $this->title('RESERVA'),
                $this->title('FECHA DE RESERVA'),
                $this->title('COMPAÑÍA'),
                $this->title('VENDEDOR'),
                $this->title('RESPONSABLE'),
                $this->title('NUMERO DE SERIE/FACTURA'),
                $this->title('CÓDIGO RESERVA'),
                $this->title('TIPO FACTURA'),
                $this->title('MONTO SIN IGV'),
                $this->title('MONTO CON IGV'),
                $this->title('OBSERVACIONES'),
                $this->title('OBSERVACIÓN BOOKING'),
            ]
        ];

        // Pre-calcular filas consecutivas por grupo de Booking_Code
        $groupSizes = [];
        $prevCode = null;
        $groupIdx = -1;
        foreach ($upgrades as $idx => $curr) {
            $code = $curr->Booking_Code ?? '';
            if ($code !== $prevCode) {
                $groupIdx++;
                $groupSizes[$groupIdx] = 0;
            }
            $groupSizes[$groupIdx]++;
            $prevCode = $code;
        }

        $counter = 0;
        $lastBookingCode = null;
        $currentGroupIdx = -1;

        foreach ($upgrades as $curr) {
            $bookingCode = $curr->Booking_Code ?? '';
            $isNewBooking = ($lastBookingCode !== $bookingCode);

            if ($isNewBooking) {
                $currentGroupIdx++;
            }

            // Fila en blanco entre bookings diferentes
            if ($lastBookingCode !== null && $isNewBooking) {
                $rows[] = $this->blankRow();
            }
            $lastBookingCode = $bookingCode;
            $counter++;

            // Observación Booking: merge vertical por grupo de booking
            $groupSize = $groupSizes[$currentGroupIdx];
            if ($isNewBooking && $groupSize > 1) {
                $observationCell = $this->columnVMerge($curr->Booking_Observation ?? '', $groupSize - 1);
            } elseif ($isNewBooking) {
                $observationCell = $this->column($curr->Booking_Observation ?? '');
            } else {
                $observationCell = $this->column('');
            }

            $rows[] = [
                $this->column($counter),
                $this->column($curr->Booking_Code ?? ''),
                $this->column("$curr->Passenger_Name $curr->Passenger_LastName"),
                $this->column($curr->TypeDocument_Name),
                $this->column($curr->Passenger_NoDocument),
                $this->column($curr->UserCountry_Name ?? ''),
                $this->column(
                    (self::purchased($curr) && self::onlyReturn($curr)) ?
                        DateTime::dateTimeTransform($curr->BookingUpgradePassenger_DateEntry) :
                        ''
                ),
                $this->column(
                    self::purchased($curr) ?
                        DateTime::dateTimeTransform($curr->BookingUpgradePassenger_Datereturn) :
                        '-'
                ),
                $this->column($curr->BookingUpgradePassenger_Amount),
                $this->column($curr->BookingUpgradePassenger_Code),
                $this->column(self::status($curr)),
                $this->column(
                    self::purchased($curr) ?
                        $curr->BookingUpgradePassenger_DatePurchase :
                        '-'
                ),
                $this->column($curr->BookingTour_TourName),
                $this->column($curr->BookingTour_DateStart),
                $this->column($curr->BookingUpgradePassenger_Carrier),
                $this->column($curr->Seller_Name),
                $this->column($curr->Id_Admin != NULL ? "$curr->Admin_Name $curr->Admin_LastName" : ''),
                $this->column($curr->CommercialInvoice_NumberSerie ?? ''),
                $this->column($curr->CommercialInvoice_CodeReservation ?? ''),
                $this->column(self::commercialInvoiceType($curr)),
                $this->column($curr->CommercialInvoice_AmountWithoutIgv ?? ''),
                $this->column($curr->CommercialInvoice_AmountWithIgv ?? ''),
                $this->column($curr->BookingUpgradePassenger_Remark),
                $observationCell,
            ];
        }

        return $rows;
    }

    public static function status($bup)
    {
        switch ($bup->BookingUpgradePassenger_Status) {
            case 2:
                return 'COMPRADO';
            case 1:
                if ($bup->BookingUpgradePassenger_Mask == 2) {
                    return 'RESERVADO';
                }
                return 'PENDIENTE';
            default:
                return 'ANULADO';
        }
    }

    public static function purchased($bup)
    {
        return $bup->BookingUpgradePassenger_Status == 2;
    }

    public static function commercialInvoiceType($bup)
    {
        $type = $bup->CommercialInvoice_Type ?? null;
        switch ($type) {
            case 1:
                return 'FACTURA FINAL';
            case 2:
                return 'ANTICIPO';
            default:
                return '';
        }
    }

    public static function onlyReturn($bup)
    {
        return $bup->BookingUpgradePassenger_OnlyReturn == 2;
    }

    public function run($data, $oMetadata)
    {
        return $this->createUpgrades($data->Upgrade);
    }
}
