<?php

namespace App\Http\Controllers\Owner\Report\Booking;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Owner\Report\Booking\ReportSalesByPackageByMonth\Schedule;
use Illuminate\Http\Request;
use App\Modules\Shared\Validator\Infraestructure\LaravelValidator;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Domain\DateEnd;
use App\Modules\Shared\Domain\DateStart;
use App\Modules\Shared\Domain\Transaction;
use DateInterval;

class ReportSalesByPackageByMonthController extends Controller
{
    private $domain;

    public function __construct(
        private QueryBus $queryBus,
        private Transaction $transaction
    ) {
        $this->domain = "ReportBooking";
    }

    public function __invoke(Request $request)
    {
        (new LaravelValidator())->validate($request->all(), $this->domain, [
            'DateStart' => 'required|string|date',
            'DateEnd' => 'required|string|date',
            'Type' => 'required|in:tour,package'
        ]);

        $schedule = new Schedule($request->input('DateStart'), $request->input('DateEnd'), 'month');


        $type = $request->input('Type');
        $generic = [];
        // $generic['package'] = fn(callable $callable, string $title) => fn(int $month, int $year, string $monthName) => "COUNT(IF(" . $callable($month, $year) . ", `aux`.`Id_Booking`, NULL)) AS `$title $monthName`";
        $generic['package'] = fn(callable $callable, string $title) => fn(int $month, int $year, string $monthName) => "SUM(IF(" . $callable($month, $year) . ", `aux`.`Passenger_Amount`, NULL)) AS `$title $monthName`";
        $generic['tour'] = fn(callable $callable, string $title) => fn(int $month, int $year, string $monthName) => "SUM(IF(" . $callable($month, $year) . ", `Passengers`, NULL)) AS `$title $monthName`";
        // $generic['package'] = fn(callable $callable, string $title) => fn(int $month, int $year, string $monthName) => "SUM(IF(" . $callable($month, $year) . ", `aux`.`Price`, NULL)) AS `$title $monthName`";
        $generic2 = fn(string $apply) => fn(string $month, string $year) => "`Month` = $month AND `Year` = $year$apply";


        $data = [
            'month' => [$generic[$type]($generic2(""), "")],
            'day' => [$generic[$type]($generic2(""), "")],
        ];

        $cols = [];
        foreach ($schedule->getPeriod() as $period) {
            $cols = array_merge($cols, array_map(fn($callback) => $callback($period->month, $period->year, $period->name), $data['month']));
        }
        $cols = $this->generateSelectQuery($cols);

        $select = "SELECT SUM(`aux`.`Passenger_Amount`) AS `Amount`,
    `aux_pk`.`Tour_Name`,
    $cols
FROM `t_tour` `aux_pk`
LEFT JOIN
(
    SELECT  `b`.`Id_Booking`,
            `bt`.`Id_BookingTour`,
            `bt`.`Id_Package`,
            `p`.`Package_Name`,
            `t`.`Id_Tour`,
            `t`.`Tour_Name`,
            COUNT(DISTINCT `btp`.`Id_BookingTourPassenger`) AS `Passenger_Amount`,
            SUM(`btp`.`BookingTourPassenger_Price`) AS `Price`,
            `b`.`Booking_DateConfirm`,
            YEAR(`b`.`Booking_DateConfirm`) AS `Year`,
            MONTH(`b`.`Booking_DateConfirm`) AS `Month`,
            DAY(`b`.`Booking_DateConfirm`) AS `Day`,
            IF(`u`.`User_Type` = 1 AND `b`.`Booking_Type` = 1, 1, 0) AS `ReservaWeb`,
            IF(`u`.`User_Type` = 1 AND `b`.`Booking_Type` = 1, 0, 1) AS `NotReservaWeb`,
            IF(`u`.`User_Type` = 2, 0, IF(`b`.`Booking_InPerson` = 1, `b`.`Booking_Type`, 8)) AS `Type`
    FROM `t_booking_tour` `bt`
    INNER JOIN `t_booking` `b` ON `b`.`Id_Booking` = `bt`.`Id_Booking`
    INNER JOIN `t_user` `u` ON `u`.`Id_User` = `b`.`Id_User`
    INNER JOIN `t_package` `p` ON `p`.`Id_Package` = `bt`.`Id_Package`
    INNER JOIN `t_tour` `t` ON `t`.`Id_Tour` = `bt`.`Id_Tour`
    INNER JOIN `t_passenger` `ps` ON `ps`.`Id_Booking` = `b`.`Id_Booking`
    INNER JOIN `t_booking_tour_passenger` `btp` ON `btp`.`Id_Passenger` = `ps`.`Id_Passenger`
    WHERE `b`.`Booking_DateConfirm` BETWEEN '" . $request->input('DateStart') . "' AND '" . $request->input('DateEnd') . "'
    AND   `b`.`Booking_Status` IN (2, 3)
    GROUP BY `b`.`Id_Booking`, `p`.`Id_Package`
    ORDER BY `b`.`Booking_DateConfirm`
) `aux` ON `aux_pk`.`Id_Tour` = `aux`.`Id_Tour`
GROUP BY `aux_pk`.`Id_Tour`
ORDER BY `Amount` DESC, `aux_pk`.`Tour_Name` ASC";

        echo $select;
        die(0);
    }

    private function generateSelectQuery(array $selectColumns)
    {
        return implode(",\n\t", $selectColumns);
    }
}
