<?php

namespace App\Services\Payments\Providers;

use App\Enums\PaymentStatus;
use App\Models\Payment;
use App\Services\Payments\PaymentGatewayInterface;
use App\Services\Payments\PaymentInitialization;
use App\Services\Payments\PaymentVerification;
use App\Services\Payments\WebhookResult;
use Illuminate\Http\Request;

/**
 * Bank deposit / cash payments reconciled by a Finance Officer.
 *
 * This is the provider KCU can run on from day one: the applicant is given a
 * reference to quote, and the payment only becomes `paid` when a member of
 * staff with `payments.verify` confirms it against a bank statement. There is
 * no external API to trust, so nothing here can be spoofed by an applicant.
 */
class ManualProvider implements PaymentGatewayInterface
{
    public function name(): string
    {
        return 'manual';
    }

    public function label(): string
    {
        return 'Bank Deposit / Cash';
    }

    public function initializePayment(Payment $payment, array $context = []): PaymentInitialization
    {
        $bank = setting('bank_name', 'Stanbic Bank Uganda');
        $account = setting('bank_account_number', '—');
        $branch = setting('bank_branch', 'Kampala');

        $instructions = implode("\n", [
            "Deposit {$payment->formattedAmount()} to:",
            "Bank: {$bank}",
            'Account name: '.setting('university_name', 'King Ceasor University'),
            "Account number: {$account}",
            "Branch: {$branch}",
            "Quote payment reference: {$payment->reference}",
            'Then upload your deposit slip. Finance will confirm within 1-2 working days.',
        ]);

        return PaymentInitialization::inline($instructions, $payment->reference);
    }

    /**
     * Nothing to ask an API: a manual payment is settled only by staff
     * verification, so report whatever the record already says.
     */
    public function verifyPayment(Payment $payment): PaymentVerification
    {
        return new PaymentVerification(
            status: $payment->status,
            providerReference: $payment->provider_reference,
            amount: (float) $payment->amount,
            currency: $payment->currency,
            message: $payment->status === PaymentStatus::Paid
                ? 'Confirmed by Finance.'
                : 'Awaiting confirmation by Finance.',
        );
    }

    public function handleWebhook(Request $request): WebhookResult
    {
        return WebhookResult::invalid('The manual provider does not accept webhooks.');
    }

    public function refundPayment(Payment $payment, ?float $amount = null): bool
    {
        // Refunds are executed at the bank; the record is updated by Finance.
        return false;
    }
}
