<?php

namespace App\Tasks;

use App\Domains\CostUnit\Actions\ChangeCostUnitDetails\ChangeCostUnitDetailsCommand;
use App\Domains\CostUnit\Actions\ChangeCostUnitDetails\ChangeCostUnitDetailsRequest;
use App\Domains\CostUnit\Actions\ChangeCostUnitState\ChangeCostUnitStateCommand;
use App\Domains\CostUnit\Actions\ChangeCostUnitState\ChangeCostUnitStateRequest;
use App\Mail\AdminMails\CostUnitInvalidBillingDeadlineMail;
use App\Models\CostUnit;
use App\Repositories\CostUnitRepository;
use App\ValueObjects\Amount;
use Illuminate\Support\Facades\Mail;

class CloseCostUnit implements CronTask {
    public function handle(): void
    {
        $now = now();
        $costUnitRepository = new CostUnitRepository();
        $now = now();
        $billingResetEnd = clone $now;
        $billingResetEnd->add(new \DateInterval('P6W'));
        /** @var CostUnit $costUnit */
        foreach ($costUnitRepository->getCurrentEvents(true) as $costUnit) {
            $billingEnd = $costUnit['billing_deadline'];

            if ($billingEnd === null) {
                $billingEnd = \DateTime::createFromFormat('Y-m-d H:i:s', $billingResetEnd)->format('Y-m-d H:i:s');
                new ChangeCostUnitDetailsCommand(new ChangeCostUnitDetailsRequest(
                    CostUnit::where('id', $costUnit['id'])->first(),
                    Amount::fromString($costUnit['distance_allowance']),
                    $costUnit['mail_on_new'],
                    $billingResetEnd
                ))->execute();
            }

            $billingEndTime = \DateTime::createFromFormat('Y-m-d H:i:s', $billingEnd);
            if (false === $billingEndTime) {
                $billingEndTime = \DateTime::createFromFormat('Y-m-d', $billingEnd);
            }

            if (false === $billingEndTime) {
                $recipients = config('app.admin_mail');
                if (null === $recipients) {
                    $recipients = CostUnit::where('id', $costUnit['id'])->first()
                        ?->treasurers()->pluck('email')->all() ?? [];
                }

                if (!empty($recipients)) {
                    Mail::to($recipients)->send(new CostUnitInvalidBillingDeadlineMail(
                        costUnitId: $costUnit['id'],
                        costUnitName: $costUnit['name'] ?? null,
                        invalidBillingDeadline: $billingEnd,
                    ));
                }

                continue;
            }
            $billingEndTime->setTime(0,0,0);
            $billingEndTime->add(new \DateInterval('P1D'));



            if ($billingEndTime < $now) {
                new ChangeCostUnitStateCommand(
                    new ChangeCostUnitStateRequest(
                        CostUnit::where('id', $costUnit['id'])->first(),false, false
                    )
                )->execute();
            }
        }
    }
}
