<?php

namespace App\Domains\Invoice\Controllers;

use App\Domains\Invoice\Actions\CreateInvoice\CreateInvoiceCommand;
use App\Domains\Invoice\Actions\CreateInvoice\CreateInvoiceRequest;
use App\Enumerations\InvoiceType;
use App\Providers\FlashMessageProvider;
use App\Providers\UploadFileProvider;
use App\Scopes\CommonController;
use App\ValueObjects\Amount;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class SaveInvoiceController extends CommonController
{
    public function __invoke(Request $request, int $costUnitId, string $invoiceType) : JsonResponse {
        $costUnit = $this->costUnits->getById($costUnitId, true);
        $paymentPurpose = $request->input('paymentPurpose') ?? null;
        $notices = $request->input('notices') ?? null;
        if (null === $costUnit) {
            return response()->json([
                'status' => 'error',
                'message' => 'Beim Speichern ist ein Fehler aufgetreten. Bitte starte den Vorgang erneut.'
            ]);
        }

        $uploadedFile = null;
        if (null !== $request->file('receipt')) {
            $maxFileSize = env('MAX_INVOICE_FILE_SIZE', 16);
            $validation = sprintf('%1$s|%2$s|max:%3$s',
                'required',
                'mimes:pdf',
                $maxFileSize * 1024
            );

            $validator = Validator::make($request->all(), [
                'receipt' => $validation
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => sprintf(
                        'Der Beleg konnte nicht hochgeladen werden. Bitte beachte die Maximale Dateigröße von %1$s MB sowie die Tatsache, dass ausschließlich PDF-Dateien akzeptiert werden.',
                        $maxFileSize
                    )
                ]);
            }

            $uploadFileProvider = new UploadFileProvider($request->file('receipt'), $costUnit);
            $uploadedFile = $uploadFileProvider->saveUploadedFile();
        }

        switch ($invoiceType) {
            case InvoiceType::INVOICE_TYPE_TRAVELLING:

                if ($uploadedFile !== null) {
                    $amount = Amount::fromString($request->input('amount'))->getAmount();
                    $distance = null;
                } else {
                    $distance = Amount::fromString($request->input('amount'))->getRoundedAmount();
                    $amount = $distance  * $costUnit->distance_allowance;

                }

                $createInvoiceRequest = new CreateInvoiceRequest(
                    $costUnit,
                    $request->input('name'),
                    InvoiceType::INVOICE_TYPE_TRAVELLING,
                    $amount,
                    $uploadedFile,
                    'donation' === $request->input('decision') ? true : false,
                    $this->users->getCurrentUserDetails()['userId'],
                    $request->input('email'),
                    $request->input('telephone'),
                    $request->input('accountOwner'),
                    $request->input('accountIban'),
                    null,
                    $request->input('otherText'),
                    $distance,
                    $request->input('havePassengers'),
                    $request->input('materialTransportation'),
                    $request->input('travelReason'),
                    null,
                    $notices
                );

                break;

            default:
                $createInvoiceRequest = new CreateInvoiceRequest(
                    $costUnit,
                    $request->input('name'),
                    $invoiceType,
                    Amount::fromString($request->input('amount'))->getAmount(),
                    $uploadedFile,
                    'donation' === $request->input('decision') ? true : false,
                    $this->users->getCurrentUserDetails()['userId'],
                    $request->input('email'),
                    $request->input('telephone'),
                    $request->input('accountOwner'),
                    $request->input('accountIban'),
                    $request->input('otherText'),
                    null,
                    null,
                    $request->input('havePassengers'),
                    $request->input('materialTransportation'),
                    null,
                    $paymentPurpose,
                    $notices
                );

                break;
        }

        $command = new CreateInvoiceCommand($createInvoiceRequest);
        $response = $command->execute();
        if ($response->success) {
            new FlashMessageProvider(
                'Die Abrechnung wurde erfolgreich angelegt.' . PHP_EOL . PHP_EOL . 'Sollten wir Rückfragen haben, melden wir uns bei dir',
                'success'
            );

            return response()->json([
                'status' => 'success',
                'message' => 'Alright'
            ]);
        }
    }
}
