<?php

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

use App\Http\Controllers\Controller;
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;
use Illuminate\Support\Facades\DB;

class ReportSalesByMonthController 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:sales'
        ]);

        $dateStart = new DateStart($request->input('DateStart'));
        $dateEnd = new DateEnd($request->input('DateEnd'));
        $dateStart = $dateStart->value() . ' 00:00:00';
        $dateEnd = $dateEnd->value() . ' 23:59:59';

        // 1 month interval
        $dateInterval = new DateInterval('P1M');

        // months between date start and date end
        $datePeriod = new \DatePeriod(new \DateTime($dateStart), $dateInterval, new \DateTime($dateEnd));

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

        $data = [
            $generic[$type]($generic2(" AND `ReservaWeb`"), 'RESERVA WEB'),
            $generic[$type]($generic2(" AND NOT(`ReservaWeb`)"), 'SALKANTAY'),
            $generic[$type]($generic2(""), "TOTAL"),
        ];

        $cols = [];
        $monthNames = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
        foreach ($datePeriod as $date) {
            $month = $date->format('m');
            $year = $date->format('Y');
            $cols = array_merge($cols, array_map(fn($callback) => $callback($month, $year, $monthNames[$month - 1]), $data));
        }
        $cols = $this->generateSelectQuery($cols);

        $select = "SELECT COUNT(`aux`.`Id_Booking`) AS `Amount`,
    $cols
FROM
(
    SELECT  `b`.`Id_Booking`,
            `bt`.`Id_BookingTour`,
            `bt`.`Id_Package`,
            COUNT(DISTINCT `btp`.`Id_Passenger`) AS `Passenger_Amount`,
            `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_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 '$dateStart' AND '$dateEnd'
    AND   `b`.`Booking_Status` IN (2, 3)
    GROUP BY `b`.`Id_Booking`
    ORDER BY `b`.`Booking_DateConfirm`
) `aux`";

        echo $select;
        dd([]);
    }

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