<?php

namespace App\EventPaymentModules\Modules;

use App\EventPaymentModules\AbstractEventPaymentModule;
use App\EventPaymentModules\DTO\CreateInvoiceRequest;
use App\EventPaymentModules\DTO\RegistrationRenderContext;
use App\EventPaymentModules\DTO\RegistrationSummaryRequest;
use App\EventPaymentModules\DTO\RegistrationSummaryResponse;
use App\EventPaymentModules\ProvidesGiroCode;
use App\Models\EventParticipant;
use App\Models\PaymentMethod;
use App\Providers\GiroCodeProvider;

/**
 * Überweisung auf das Veranstaltungskonto -- die Zahlung erfolgt manuell durch die teilnehmende Person.
 */
class AccountTransferPaymentModule extends AbstractEventPaymentModule implements ProvidesGiroCode
{
    public static function slug(): string
    {
        return PaymentMethod::PAYMENT_ACCOUNT_TRANSACTION;
    }

    public function defaultName(): string
    {
        return 'Überweisung auf Veranstaltungskonto';
    }

    public function defaultConfiguration(): array
    {
        return ['icon' => 'building-columns'];
    }

    public function getOptions(): array
    {
        return [
            ['name' => 'account_owner', 'label' => 'Kontoinhaber', 'type' => 'string', 'required' => true],
            ['name' => 'iban', 'label' => 'IBAN', 'type' => 'string', 'required' => true],
            ['name' => 'bic', 'label' => 'BIC', 'type' => 'string', 'required' => false],
            ['name' => 'summary_confirmation_text', 'label' => 'Bestätigung durch Teilnehmende (Zusammenfassung, {amount} als Platzhalter)', 'type' => 'string', 'required' => false],
            ['name' => 'icon', 'label' => 'Symbol', 'type' => 'icon', 'required' => false],
        ];
    }

    public function registrationSummary(RegistrationSummaryRequest $request): RegistrationSummaryResponse
    {
        $participant = $request->participant;
        $config = $request->configuration;

        $amountLeft = clone $participant->amount;
        if ($participant->amount_paid !== null) {
            $amountLeft->subtractAmount($participant->amount_paid);
        }

        $hasPaymentInformation = $amountLeft->getAmount() > 0;

        // GiroCode nur bei offenem Betrag; Bildquelle je Render-Kontext (Web-Endpoint vs. Mail-CID).
        $giroCodeSrc = null;
        if ($hasPaymentInformation) {
            $giroCodeSrc = $request->context === RegistrationRenderContext::Mail
                ? 'cid:girocode.png'
                : '/print-girocode/' . $participant->identifier;
        }

        // Medien-gerechtes Template je Render-Kontext (Web: SPA-Klassen, Mail: E-Mail-tauglich).
        $view = $request->context === RegistrationRenderContext::Mail
            ? 'payment-modules.account-transfer.mail'
            : 'payment-modules.account-transfer.web';

        $response = new RegistrationSummaryResponse();
        $response->hasPaymentInformation = $hasPaymentInformation;
        $response->html = view($view, [
            'accountOwner' => (string)($config['account_owner'] ?? ''),
            'iban' => (string)($config['iban'] ?? ''),
            'paymentPurpose' => (string)$participant->payment_purpose,
            'amount' => $amountLeft->toString(),
            'giroCodeSrc' => $giroCodeSrc,
            'reminderUrl' => url('/api/v1/event/participant/' . $participant->identifier . '/ical-payment'),
            'paymentDeadline' => $participant->event?->registration_final_end?->format('d.m.Y'),
        ])->render();

        return $response;
    }

    public function giroCode(EventParticipant $participant, array $configuration): ?string
    {
        $amountLeft = clone $participant->amount;
        if ($participant->amount_paid !== null) {
            $amountLeft->subtractAmount($participant->amount_paid);
        }

        if ($amountLeft->getAmount() <= 0) {
            return null;
        }

        $provider = new GiroCodeProvider(
            (string)($configuration['account_owner'] ?? ''),
            (string)($configuration['iban'] ?? ''),
            $amountLeft->getAmount(),
            (string)$participant->payment_purpose,
        );

        return (string)$provider->create();
    }

    protected function invoiceClosingStatement(CreateInvoiceRequest $request): string
    {
        // TODO: In einer Folge-Iteration ausformulieren (z.B. "Bitte überweise bis zum ... auf IBAN ...").
        return '';
    }
}
