<?php

namespace App\Providers\ExcelGroupResumeReport;

use App\Http\Helpers\DateTime;
use App\Providers\ExcelReport\Utils;

class EntrancesCells
{

    private function titleMerge($text, $cols)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'center'],
            ['action' => 'bold'],
            ['action' => 'mergeborder', 'lines' => $cols],
        ];
    }

    private function subtitleMerge($text, $cols)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'bold'],
            ['action' => 'mergeborder', 'lines' => $cols],
        ];
    }

    private function valuesubtitleMerge($text, $cols)
    {
        return [
            ['action' => 'wrap'],
            ['action' => 'print', 'text' => $text],
            ['action' => 'top'],
            ['action' => 'mergeborder', 'lines' => $cols]
        ];
    }

    private function borders()
    {
        return [['action' => 'wrap'], ['action' => 'border'], ['action' => 'print', 'text' => ""]];
    }

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

    private function titleNoBorders($text)
    {
        return Utils::compose(
            [Utils::class, 'wrap'],
            [Utils::class, 'bold'],
            [Utils::class, 'wrap'],
            Utils::merge(1),
            Utils::print($text),
            [Utils::class, 'cell']
        )('');
    }

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

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

    private function createresume($group)
    {
        return array_merge(
            [[$this->titleMerge('ORDEN DE SALIDA ' . DateTime::dateTransform($group->Group_DateStart), 15)]
            ],
            [
                [
                    $this->subtitleMerge('TOUR:', 2),
                    $this->valuesubtitleMerge($group->Service_Name, 4),
                    $this->subtitleMerge('NRO DE PAX:', 2),
                    $this->valuesubtitleMerge(count($group->Passenger), 4),
                ]
            ],
            [
                [
                    $this->subtitleMerge('F. ACTUALIZACIÓN:', 2),
                    $this->valuesubtitleMerge(DateTime::dateTimeTransformNS($group->Group_Date), 4),
                    $this->subtitleMerge('F. GENERADO:', 2),
                    $this->valuesubtitleMerge(DateTime::dateTimeTransformNS(date('Y-m-d H:i:s')), 4),
                ]
            ],
            $this->flyesorAlcances($group),
            $this->providers($group->ProvidersResume),
            [
                [
                    $this->titleMerge('VIP PASSENGERS', 7),
                    $this->titleMerge('IMPORTANT INFORMATION PASSENGERS', 7),
                ]
            ],
            $this->passenger($group->Passenger, $group->Group_DateEnd),
            [
                [
                    $this->titleNoBorders(''),
                ]
            ],
            [
                [
                    $this->titleMerge('OBSERVACIONES', 1),
                    $this->columnMerge($group->Group_Remark, 13)
                ]
            ]
        );
    }

    public function flyesorAlcances($group)
    {
        if ($group->Group_ServiceType == 2) {
            return array_merge(
                [
                    [
                        $this->subtitleMerge('ORIGEN:', 2),
                        $this->valuesubtitleMerge($group->Group_Origin, 4),
                        $this->subtitleMerge('DESTINO:', 2),
                        $this->valuesubtitleMerge($group->Group_Destination, 4),
                    ]
                ],
                [
                    [
                        $this->subtitleMerge('FECHA DE RECOJO:', 2),
                        $this->valuesubtitleMerge(DateTime::dateTransform($group->Group_DateStart) . ' ' . $group->Group_Hour, 4),
                        $this->subtitleMerge('', 2),
                        $this->valuesubtitleMerge('', 4),
                    ]
                ]
            );
        }
        if ($group->Group_ServiceType > 2) {
            return array_merge(
                [
                    [
                        $this->subtitleMerge('VUELO:', 2),
                        $this->valuesubtitleMerge($group->Fligth[4], 4),
                        $this->subtitleMerge('NUMERO DE VUELO:', 2),
                        $this->valuesubtitleMerge($group->Fligth[3], 4),
                    ]
                ],
                [
                    [
                        $this->subtitleMerge('ORIGEN:', 2),
                        $this->valuesubtitleMerge($group->Fligth[1], 4),
                        $this->subtitleMerge('DESTINO', 2),
                        $this->valuesubtitleMerge($group->Fligth[2], 4),
                    ]
                ],
                [
                    [
                        $this->subtitleMerge('FECHA Y HORA DE RECOJO:', 2),
                        $this->valuesubtitleMerge(DateTime::dateTimeTransformNS($group->Fligth[0]), 4),
                        $this->subtitleMerge('OBSERVACIONES DE VUELO', 2),
                        $this->valuesubtitleMerge($group->Fligth[5], 4),
                    ]
                ]
            );
        }
        return [];
    }
    public function providers($prov)
    {
        $cant = count($prov);
        $cantidad = ceil($cant / 2);
        $arraynew = array();
        $result = [];
        for ($i = 0; $i < $cantidad; $i++) {
            $srrayprov = [
                $this->subtitleMerge($prov[$i * 2]->NameType, 2),
                $this->valuesubtitleMerge($prov[$i * 2]->Provider, 4),
            ];
            if (($i + 1) * 2 <= $cant) {
                $arraynew = [
                    $this->subtitleMerge($prov[$i * 2 + 1]->NameType, 2),
                    $this->valuesubtitleMerge($prov[$i * 2 + 1]->Provider, 4),
                ];
            } else {
                $arraynew = [
                    $this->subtitleMerge("", 2),
                    $this->valuesubtitleMerge("", 4),
                ];
            }

            $result[] = array_merge($srrayprov, $arraynew);
        }
        return  $result;
    }

    public function passenger($pax, $datend)
    {
        return array_merge(
            [
                [
                    $this->title('N°'),
                    $this->title('NOMBRES'),
                    $this->title('TELEFONO'),
                    $this->title('M/F'),
                    $this->title('AGE'),
                    $this->title('PASS'),
                    $this->title('COUNTRY'),
                    $this->title('HTL-CUZ'),
                    $this->subtitleMerge('HTL-AC', 1),
                    $this->title('RET'),
                    $this->title('TRAIN'),
                    $this->title('INGRESOS'),
                    $this->title('EQUIPAMENTOS'),
                    $this->subtitleMerge('OBSERVACIONES / RESTRICCIONES /EXTRAS', 1),
                ]
            ],
            array_map(
                function ($px, $key) use ($datend) {
                    return [
                        $this->column($key + 1),                                               // 10
                        $this->column(
                            $px->Passenger_Name . ' ' . $px->Passenger_LastName . ($px->User_Type == 2 ? '(' . $px->User_Name . ')' : '') .
                                ($px->Group_MasterType == 1 ? '(' . $px->Tour_Code . ')' . DateTime::dateTransform($px->Group_DateStart) : ''),
                        ),              // 20
                        $this->column($px->Passenger_Phone),
                        $this->column($px->Passenger_Gender == 1 ? 'M' : 'F'),      // 30                
                        $this->column($px->Passenger_Age),                            // 14
                        $this->column($px->Passenger_NoDocument),
                        $this->column($px->UserCountry_Name),
                        $this->column($px->Booking_Hotel),
                        isset($px->Current_TypeRoom) ?
                            [
                                ['action' => 'vmerge', 'lines' => $px->Current_Count],
                                ['action' => 'print', 'text' => $px->TypeRoom_Abrv],
                                ['action' => 'border'],
                                ['action' => 'wrap'],
                                ['action' => 'top']
                            ] :
                            $this->column(''),
                        $this->column($px->Passenger_Hotel_resume),
                        $this->column(DateTime::dateTransform($px->Group_DateEnd)),
                        $this->column($px->Passenger_Train_Remark1_resume),
                        $this->column($px->Passenger_Entrance_Resume),
                        $this->column($this->mapEquipments($px->Equipments)),
                        $this->valuesubtitleMerge('OBSERVACIONES :' . $px->BookingTourPassenger_Remark . "\n" . ' RESTRICCIONES :' . $px->Passenger_Restriction . "\n" . ' EXTRAS :' . $px->Passenger_Extras, 1),
                    ];
                },
                $pax,
                array_keys($pax)
            )
        );
    }

    private function mapEquipments($equipments)
    {
        return implode('\n', array_map(function ($eq) {
            return $eq->Item_Name . ': ' . $eq->Quantity;
        }, $equipments));
    }

    public function purchased($bep)
    {
        return $bep->BookingExtraPassenger_Status == 2;
    }

    public function run($data, $oMetadata)
    {
        $data->Groups = array_map([$this, 'richPassengers'], $data->Groups);
        return array_merge(...array_map(fn($group) => $this->createresume($group), $data->Groups));
    }

    protected function richPassengers($row)
    {
        $row->Passenger = $this->markTypeRoomColspan($row->Passenger);
        return $row;
    }

    protected function markTypeRoomColspan($passengers)
    {
        return array_reduce($passengers, function ($carry, $passenger) {

            $found = $this->findTypeRoomCarry($carry, $passenger->Id_Room, $passenger->Id_Group, $passenger->BookingTourPassenger_Status);

            if (count($found)) {
                $found[0]->Current_Count++;
                $carry[] = $passenger;
            } else {
                $carry[] = $this->convertToRoomCarry($passenger);
            }
            return $carry;
        }, []);
    }

    protected function convertToRoomCarry($passenger)
    {
        $passenger->Current_TypeRoom = $passenger->Id_Room;
        $passenger->Current_Count = 0;
        return $passenger;
    }

    protected function findGroupCarry($target, $id): array
    {
        return array_values(array_filter($target, function ($ele) use ($id) {
            return $ele->Id_Group == $id;
        }));
    }

    protected function findTypeRoomCarry($target, $id, $Id_Group, $status): array
    {
        return array_values(array_filter($target, function ($ele) use ($id, $Id_Group, $status) {
            return isset($ele->Current_TypeRoom) && $ele->Current_TypeRoom == $id && $ele->Id_Group == $Id_Group && $ele->BookingTourPassenger_Status == $status;
        }));
    }
}
