<?php

namespace App\Services\Payments\Gateways;

use App\Models\Payment;
use App\Services\Payments\PaymentGateway;
use App\Services\Payments\SessionResult;
use Stripe\StripeClient;

class StripeGateway implements PaymentGateway
{
    public function __construct(private array $cfg) {}

    private function client(): StripeClient
    {
        return new StripeClient($this->cfg['secret']);
    }

    public function createOneOffSession(Payment $p): SessionResult
    {
        $amount = (int) ($p->amount_cents ?? (isset($p->amount) ? round(((float)$p->amount)*100) : 0));
        if ($amount <= 0) throw new \RuntimeException('Amount must be > 0');

        $pi = $this->client()->paymentIntents->create([
            'amount'                     => $amount,
            'currency'                   => strtolower($p->currency ?? 'NZD'),
            'capture_method'             => 'automatic',
            'automatic_payment_methods'  => ['enabled' => true],
            'metadata' => [
                'payment_id' => (string)$p->id,
                'job_id'     => (string)($p->job_id ?? ''),
                'type'       => (string)($p->type ?? 'oneoff'),
                'reference'  => (string)($p->reference ?? ''),
            ],
        ]);

        $p->provider   = 'stripe';
        $p->provider_id = $pi->id;
        $p->stripe_payment_intent_id = $pi->id; // keep your existing column too
        $p->status = $p->status ?: 'pending';
        $p->save();

        return new SessionResult('stripe', clientSecret: $pi->client_secret);
    }

    public function authorizeHold(Payment $p): SessionResult
    {
        $amount = (int) ($p->amount_cents ?? 0);
        $pi = $this->client()->paymentIntents->create([
            'amount'    => $amount,
            'currency'  => strtolower($p->currency ?? 'NZD'),
            'capture_method' => 'manual',
            'automatic_payment_methods' => ['enabled' => true],
            'metadata' => ['payment_id' => (string)$p->id, 'type' => 'bond_hold'],
        ]);

        $p->provider = 'stripe';
        $p->provider_id = $pi->id;
        $p->stripe_payment_intent_id = $pi->id;
        $p->status = 'pending';
        $p->save();

        return new SessionResult('stripe', clientSecret: $pi->client_secret);
    }

    public function captureHold(Payment $p, ?int $amountCents = null): void
    {
        $this->client()->paymentIntents->capture($p->provider_id ?: $p->stripe_payment_intent_id, array_filter([
            'amount_to_capture' => $amountCents,
        ]));
    }

    public function cancelHold(Payment $p): void
    {
        $this->client()->paymentIntents->cancel($p->provider_id ?: $p->stripe_payment_intent_id);
    }

    public function refund(Payment $p, ?int $amountCents = null): void
    {
        $this->client()->refunds->create(array_filter([
            'payment_intent' => $p->provider_id ?: $p->stripe_payment_intent_id,
            'amount'         => $amountCents,
        ]));
    }
}
