<?php

namespace App\Domains\CostUnit\Controllers;

use App\Enumerations\UserRole;
use App\Models\SepaPaymentElement;
use App\Models\Tenant;
use App\Providers\AuthCheckProvider;
use App\Providers\FileWriteProvider;
use App\Providers\PainFileProvider;
use App\Scopes\CommonController;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class GlobalSepaExportController extends CommonController {

    private function checkAuthorization(): void
    {
        $authCheck = new AuthCheckProvider();
        $role = $authCheck->getUserRole();
        if (!in_array($role, [UserRole::USER_ROLE_ADMIN, UserRole::USER_ROLE_GROUP_LEADER], true)) {
            abort(403);
        }
    }

    public function getGlobalActions()
    {
        $this->checkAuthorization();

        $pendingElements = SepaPaymentElement::where('exported', false)->get();
        $pendingCount = $pendingElements->count();
        $pendingAmount = number_format($pendingElements->sum('amount'), 2, ',', '.');

        return response()->json([
            'pending_count' => $pendingCount,
            'pending_amount' => $pendingAmount,
        ]);
    }

    public function exportSepaFile()
    {
        $this->checkAuthorization();

        return DB::transaction(function () {
            $elements = SepaPaymentElement::where('exported', false)->lockForUpdate()->get();

            if ($elements->isEmpty()) {
                return response()->json([
                    'message' => 'Es gibt keine ausstehenden SEPA-Überweisungen.'
                ], 404);
            }

            $painFileProvider = new PainFileProvider(
                $this->tenant->account_iban,
                $this->tenant->account_name,
                $this->tenant->account_bic,
                $elements->all()
            );

            $painContent = $painFileProvider->createPainFileContent();

            $filePrefix = Tenant::getTempDirectory();
            $fileName = $filePrefix . 'sepa-pain-' . date('Y-m-d_H-i') . '.xml';

            $fileWriteProvider = new FileWriteProvider($fileName, $painContent);
            $fileWriteProvider->writeToFile();

            $elements->each(function (SepaPaymentElement $element) {
                $element->update([
                    'exported' => true,
                    'exported_at' => now(),
                ]);
            });

            $filePath = storage_path('app/private/' . $fileName);

            return response()->download($filePath, basename($fileName), [
                'Content-Type' => 'application/xml',
            ])->deleteFileAfterSend(true);
        });
    }
}
