<?php

namespace App\Modules\BookingEquipmentPassenger\Domain;

use App\Modules\Shared\Domain\QueryBuilder\Operator\OperatorAnd;
use App\Modules\Shared\Domain\QueryBuilder\Operator\OperatorIn;
use App\Modules\Shared\Domain\QueryBuilder\Operator\OperatorNotEqual;
use App\Modules\Shared\Domain\Storage\Criteria\StorageCriteria;
use Illuminate\Support\Facades\DB;

class CriteriaListBookingEquipmentPassenger implements StorageCriteria
{

    public function __construct(
        private ?array $ids,
        private ?array $idBookingEquipments,
        private ?array $idBookingTourPassengers
    ) {}

    public function run()
    {
        return $this->analize($this->query());
    }

    protected function query()
    {
        $select = BookingEquipmentPassenger::select('`bep`');

        $where = [];
        if (isset($this->ids)) {
            $where[] = new OperatorIn('`bep`.`Id_BookingEquipmentPassenger`', $this->ids);
        }
        if (isset($this->idBookingEquipments)) {
            $where[] = new OperatorIn('`bep`.`Id_BookingEquipment`', $this->idBookingEquipments);
        }
        if (isset($this->idBookingTourPassengers)) {
            $where[] = new OperatorIn('`bep`.`Id_BookingTourPassenger`', $this->idBookingTourPassengers);
        }

        $operator = new OperatorAnd(
            new OperatorNotEqual('`bep`.`BookingEquipmentPassenger_Status`', 0),
            ...$where
        );

        return DB::select(
            "SELECT $select,
                `p`.`Id_Passenger`,
                `p`.`Passenger_Gender`,
                `p`.`Passenger_Name`,
                `p`.`Passenger_LastName`,

                `bt`.`Id_BookingTour`,
                `bt`.`BookingTour_TourName`,
                `bt`.`BookingTour_DateStart`,
                `bt`.`BookingTour_TourDuration`,

                `b`.`Id_Booking`,
                `b`.`Booking_Code`,
                `b`.`Booking_InternalRemark`,
                `b`.`Booking_Observation`,

                `uc`.`Id_UserCountry`,
                `uc`.`UserCountry_Name`,
                `uc`.`UserCountry_Img`

            FROM `t_booking_equipment_passenger` `bep`
            INNER JOIN `t_booking_equipment` `be` ON `be`.`Id_BookingEquipment` = `bep`.`Id_BookingEquipment`
            INNER JOIN `t_booking_tour` `bt` ON `bt`.`Id_BookingTour` = `be`.`Id_BookingTour`
            INNER JOIN `t_booking` `b` ON `b`.`Id_Booking` = `bt`.`Id_Booking`
            INNER JOIN `t_booking_tour_passenger` `btp` ON `btp`.`Id_BookingTourPassenger` = `bep`.`Id_BookingTourPassenger`
            INNER JOIN `t_passenger` `p` ON `p`.`Id_Passenger` = `btp`.`Id_Passenger`
            INNER JOIN `t_user_country` `uc` ON `uc`.`Id_UserCountry` = `p`.`Id_UserCountry`
            WHERE " . (isset($operator) ? $operator->query() : '1 = 1 LIMIT 10000'),
            (isset($operator) ? $operator->values() : [])
        );
    }

    protected function analize($data)
    {
        return array_map(fn($bep) => ListBookingEquipmentPassenger::fromDTO($bep), $data);
    }
}
