<?php

namespace App\Domains\CostUnit\Controllers;

use App\Domains\Invoice\Actions\ChangeStatus\ChangeStatusCommand;
use App\Domains\Invoice\Actions\ChangeStatus\ChangeStatusRequest;
use App\Domains\Invoice\Actions\CreateInvoiceReceipt\CreateInvoiceReceiptCommand;
use App\Domains\Invoice\Actions\CreateInvoiceReceipt\CreateInvoiceReceiptRequest;
use App\Enumerations\InvoiceStatus;
use App\Models\SepaPaymentElement;
use App\Models\Tenant;
use App\Providers\FileWriteProvider;
use App\Providers\InvoiceCsvFileProvider;
use App\Providers\WebDavProvider;
use App\Providers\ZipArchiveFileProvider;
use App\Scopes\CommonController;
use Illuminate\Support\Facades\Storage;

class ExportController extends CommonController {
    public function __invoke(int $costUnitId) {
        $costUnit = $this->costUnits->getById($costUnitId);

        $invoicesForExport = $this->invoices->getByStatus($costUnit, InvoiceStatus::INVOICE_STATUS_APPROVED, false);

        $webdavProvider = new WebDavProvider(WebDavProvider::INVOICE_PREFIX . $this->tenant->url . '/' . $costUnit->name);

        $this->createSepaPaymentElements($invoicesForExport, $costUnit);
        $csvData = $this->csvData($invoicesForExport);

        $filePrefix = Tenant::getTempDirectory();

        $csvFileWriteProvider = new FileWriteProvider($filePrefix . 'abrechnungen-' . date('Y-m-d_H-i') . '.csv', $csvData);
        $csvFileWriteProvider->writeToFile();

        if ($this->tenant->upload_exports) {
            $webdavProvider->uploadFile($csvFileWriteProvider->fileName);
        }

        $downloadZipArchiveFiles = [
            $csvFileWriteProvider->fileName
        ];

        foreach ($invoicesForExport as $invoice) {
            $changeStatusRequest = new ChangeStatusRequest($invoice, InvoiceStatus::INVOICE_STATUS_EXPORTED);
            $changeStatusCommand = new ChangeStatusCommand($changeStatusRequest);
            $changeStatusCommand->execute();

            if ($this->tenant->download_exports) {
                $createInvoiceReceiptRequest = new CreateInvoiceReceiptRequest($invoice);
                $createInvoiceReceiptCommand = new CreateInvoiceReceiptCommand($createInvoiceReceiptRequest);
                $response = $createInvoiceReceiptCommand->execute();

                $downloadZipArchiveFiles[] = $response->fileName;
            }
        }

        if ($this->tenant->download_exports) {
            $zipFile = Tenant::getTempDirectory() . 'Abrechnungen-' . $costUnit->name . '.zip';
            $zipFileProvider = new ZipArchiveFileProvider($zipFile);
            foreach ($downloadZipArchiveFiles as $file) {
                $zipFileProvider->addFile($file);
            }

            $zipFileProvider->create();
            foreach ($downloadZipArchiveFiles as $file) {
                Storage::delete($file);
            }

            Storage::delete($csvFileWriteProvider->fileName);

            return response()->download(
                storage_path('app/private/' . $zipFile),
                basename($zipFile),
                ['Content-Type' => 'application/zip']
            );
        }

        Storage::delete($csvFileWriteProvider->fileName);
        return response()->json([
            'message' => 'Die Abrechnungen wurden exportiert.' . PHP_EOL . 'Die SEPA-Überweisungsdatei kann über den Tab "Globale Aktionen" in der Kostenstellenübersicht erzeugt werden.' . PHP_EOL . PHP_EOL . 'Die Belege werden asynchron auf dem Webdav-Server hinterlegt.' . PHP_EOL . 'Sollten diese in 15 Minuten nicht vollständig sein, kontaktiere den Administrator.'
        ]);

    }

    private function createSepaPaymentElements(array $invoices, $costUnit): void
    {
        foreach ($invoices as $invoice) {
            if ($invoice->contact_bank_owner !== null && $invoice->contact_bank_iban !== '' && !$invoice->donation) {
                SepaPaymentElement::create([
                    'tenant' => $this->tenant->slug,
                    'invoice_id' => $invoice->id,
                    'cost_unit_id' => $costUnit->id,
                    'amount' => $invoice->amount,
                    'recipient_name' => $invoice->contact_bank_owner,
                    'recipient_iban' => $invoice->contact_bank_iban,
                    'payment_purpose' => $invoice->payment_purpose ?? 'Auslagenerstattung Rechnungsnummer ' . $invoice->invoice_number,
                ]);
            }
        }
    }

    public function csvData(array $invoices) : string {
        $csvDateProvider = new InvoiceCsvFileProvider($invoices);
        return $csvDateProvider->createCsvFileContent();
    }
}
