<?php

namespace App\Domains\Invoice\Actions\CreateInvoice;

use App\Enumerations\InvoiceStatus;
use App\Mail\InvoiceMails\InvoiceMailsNewInvoiceMail;
use App\Mail\InvoiceMails\InvoiceMailsSubmittedConfirmationMail;
use App\Mail\ParticipantParticipationMails\EventSignUpSuccessfullMail;
use App\Models\Invoice;
use Illuminate\Support\Facades\Mail;

class CreateInvoiceCommand {
    private CreateInvoiceRequest $request;

    public function __construct(CreateInvoiceRequest $request) {
        $this->request = $request;
    }

    public function execute() : CreateInvoiceResponse {
        $response = new CreateInvoiceResponse();

        if ($this->request->accountIban === 'undefined') {
            $this->request->accountIban = null;
        }

        $invoice = Invoice::create([
            'tenant' => app('tenant')->slug,
            'cost_unit_id' => $this->request->costUnit->id,
            'invoice_number' => $this->generateInvoiceNumber(),
            'status' => InvoiceStatus::INVOICE_STATUS_NEW,
            'type' => $this->request->invoiceType,
            'type_other' => $this->request->invoiceTypeExtended,
            'donation' => $this->request->isDonation,
            'user_id' => $this->request->paymentPurpose === null ? $this->request->userId : null,
            'contact_name' => $this->request->contactName,
            'contact_email' => $this->request->contactEmail,
            'contact_phone' => $this->request->contactPhone,
            'contact_bank_owner' => $this->request->accountOwner,
            'contact_bank_iban' => $this->request->accountIban,
            'amount' => $this->request->totalAmount,
            'distance' => $this->request->distance,
            'travel_direction' => $this->request->travelRoute,
            'travel_reason' => $this->request->travelReason,
            'passengers' => $this->request->passengers,
            'transportation' => $this->request->transportations,
            'payment_purpose' => $this->request->paymentPurpose,
            'comment' => $this->request->notices,
            'document_filename' => $this->request->receiptFile !== null ? $this->request->receiptFile->fullPath : null,
        ]);

        if ($invoice !== null) {
            $response->success = true;
            $response->invoice = $invoice;

            if ($invoice->contact_email !== null) {
                Mail::to($invoice->contact_email)->send(new InvoiceMailsSubmittedConfirmationMail(
                    invoice: $invoice,
                    costUnit: $this->request->costUnit,
                ));
            }
        }

        if ($this->request->costUnit->mail_on_new) {
            $recipients = [app('tenant')->email_finance];

            foreach ($this->request->costUnit->treasurers()->get() as $treasurer) {
                if (!in_array($treasurer->email, $recipients)) {
                    $recipients[] = $treasurer->email;
                }
            }

            foreach ($recipients as $recipient) {
                Mail::to($recipient)->send(new InvoiceMailsNewInvoiceMail(
                    invoice: $invoice,
                    costUnit: $this->request->costUnit,
                ));
            }
        }

        return $response;
    }


    private function generateInvoiceNumber() : string {
        $lastInvoiceNumber = Invoice::query()
            ->where('tenant', app('tenant')->slug)
            ->whereYear('created_at', date('Y'))
            ->count();

        $invoiceNumber = $lastInvoiceNumber + 1;
        $invoiceNumber = str_pad($invoiceNumber, 4, '0', STR_PAD_LEFT);
        return sprintf('%1$s-%2$s', date('Y'), $invoiceNumber);
    }
}
