<?php

namespace App\Http\Controllers\Owner\Redistribution;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Owner\Passenger\PassengerUpdater;
use Illuminate\Http\Request;
use App\Http\Helpers\ResponseBuilder;
use App\Http\History\HistoryData;
use App\Http\History\HistoryTables;
use App\Modules\Admin\Domain\IdAdmin;
use App\Modules\CashMovement\Domain\IdCashMovement;
use App\Modules\CashMovementDetail\Domain\IdCashMovementDetail;
use App\Modules\Redistribution\Infraestructure\MysqlRedistributionCreateRepository;
use App\Modules\Invoice\Domain\IdInvoice;
use App\Modules\Redistribution\Application\RedistributionCreator;
use App\Modules\Redistribution\Domain\Amount;
use App\Modules\Redistribution\Domain\RedistributionAmount;
use App\Modules\Redistribution\Domain\RedistributionCurrency;
use App\Modules\Redistribution\Domain\RedistributionRemark;
use App\Modules\Redistribution\Domain\InvoiceData;
use App\Modules\Redistribution\Domain\InvoiceDataCollection;
use App\Modules\Redistribution\Domain\CreateRedistribution;
use App\Modules\Redistribution\Domain\RedistributionStatus;
use App\Modules\Redistribution\Infraestructure\Validators\RedistributionCreate;
use App\Modules\RedistributionDetail\Infraestructure\MysqlRedistributionDetailCreateRepository;
use App\Modules\Shared\Domain\Bus\Query\QueryBus;
use App\Modules\Shared\Validator\Infraestructure\LaravelValidator;
use Illuminate\Support\Facades\DB;

final class c_Create extends Controller
{
    private $oDomain;
    /** @var HistoryData */
    private $history;

    public function __construct(
        private QueryBus $queryBus,
        private PassengerUpdater $passengerUpdater
    ) {
        $this->history = new HistoryData(HistoryTables::REDISTRIBUTION);
        $this->oDomain = 'Redistribution';
    }

    public static function findBooking($idRedistributionDetail)
    {
        $found = DB::select('SELECT `fn_redistribution_detail_find_booking`(?) as Id_Booking', [$idRedistributionDetail]);
        return count($found) ? $found[0]->Id_Booking : null;
    }

    public function __invoke(Request $Request)
    {
        (new LaravelValidator)->validate($Request->all(), $this->oDomain, RedistributionCreate::BASIC);
        $invoices = ['Invoices' => json_decode($Request->input('Invoices'), true)];

        (new LaravelValidator)->validate($invoices, $this->oDomain, RedistributionCreate::INVOICES);
        $data = DB::select('call sp_admin_session_get(?,?)', [
            $Request->header('Token'),
            $Request->ip()
        ])[0];
        $invoices = array_map(fn ($id) => new InvoiceData(
            new Amount($id['Amount']),
            new IdCashMovementDetail($id['Id_CashMovementDetail']),
            new IdInvoice($id['Id_Invoice']),
            new IdCashMovement($id['Id_CashMovement']),
        ), $invoices['Invoices']);

        $response = (new RedistributionCreator(
            new MysqlRedistributionCreateRepository,
            new MysqlRedistributionDetailCreateRepository,
            $this->passengerUpdater,
            $this->queryBus
        ))->__invoke(
            new CreateRedistribution(
                new RedistributionAmount($Request->input('Redistribution_Amount')),
                new RedistributionCurrency($Request->input('Redistribution_Currency')),
                new RedistributionRemark($Request->input('Redistribution_Remark')),
                new RedistributionStatus($Request->input('Redistribution_Status')),
                new IdAdmin($data->Response_Id_Admin),
                new InvoiceDataCollection(...$invoices)
            )
        );

        $idBooking = 0;
        foreach ($response['redistributionDetail'] as $redistribution) {
            $idBooking = $this->findBooking($redistribution['Response_Data']['Id']);
            $this->history->insert(
                [$Request->all()],
                $Request,
                $idBooking
            );
            break;
        }

        return ResponseBuilder::Response($response['redistribution']);
    }
}
