<?php

namespace App\Domains\Billing\Providers;

use App\Domains\Billing\Contracts\PaymentProviderDriver;
use App\Domains\Billing\Models\PaymentProvider;
use App\Domains\Billing\Models\PaymentRequest;
use App\Support\PlatformSettings;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Str;

class WhishPayProvider implements PaymentProviderDriver
{
    public function key(): string
    {
        return 'whish';
    }

    public function createPaymentRequest(PaymentProvider $provider, PaymentRequest $request): array
    {
        $externalReference = 'WHP-'.Str::upper(Str::random(10));
        $checkoutUrl = $this->getCheckoutUrl($provider, $request);

        return [
            'external_reference' => $externalReference,
            'checkout_url' => $checkoutUrl,
            'status' => 'initiated',
        ];
    }

    public function getCheckoutUrl(PaymentProvider $provider, PaymentRequest $request): ?string
    {
        $base = $provider->checkout_base_url
            ?: PlatformSettings::get('WHISH_CHECKOUT_BASE_URL', config('payments.providers.whish.checkout_base_url'));

        if (! $base) {
            return null;
        }

        return rtrim($base, '/').'/'.urlencode($request->id);
    }

    public function verifyCallback(PaymentProvider $provider, array $payload): bool
    {
        $provided = $payload['signature'] ?? null;
        $expected = $this->decryptIfNeeded(
            $provider->webhook_secret
                ?: PlatformSettings::get('WHISH_WEBHOOK_SECRET', config('payments.providers.whish.webhook_secret'))
        );

        if (! $expected) {
            return true;
        }

        return hash_equals((string) $expected, (string) $provided);
    }

    public function parseWebhook(PaymentProvider $provider, array $payload): array
    {
        return [
            'external_reference' => $payload['external_reference'] ?? null,
            'provider_reference' => $payload['provider_reference'] ?? null,
            'status' => $payload['status'] ?? 'pending',
            'amount' => $payload['amount'] ?? null,
            'currency_code' => $payload['currency_code'] ?? 'USD',
            'payload' => $payload,
        ];
    }

    public function reconcileTransaction(PaymentProvider $provider, PaymentRequest $request, array $payload): array
    {
        $status = $payload['status'] ?? 'pending';

        return [
            'payment_request_status' => match ($status) {
                'paid', 'succeeded', 'success' => 'succeeded',
                'failed' => 'failed',
                'cancelled' => 'cancelled',
                default => 'pending',
            },
            'order_payment_status' => match ($status) {
                'paid', 'succeeded', 'success' => 'paid',
                'failed' => 'failed',
                'cancelled' => 'cancelled',
                default => 'pending',
            },
        ];
    }

    protected function decryptIfNeeded(?string $value): ?string
    {
        if ($value === null || $value === '') {
            return $value;
        }

        try {
            return Crypt::decryptString($value);
        } catch (\Throwable) {
            return $value;
        }
    }
}
