<?php

namespace App\Domain\Subscription;

use App\Enums\PaymentProofStatus;
use App\Models\PaymentProofReview;
use App\Models\SubscriptionPayment;
use App\Models\ActivityLog;
use Illuminate\Support\Facades\DB;

/**
 * Manual payment-proof workflow (Zain Cash / SuperQi) with a full audit
 * trail. Every transition writes a payment_proof_reviews row recording who,
 * when, from→to, note, and IP.
 */
class PaymentApprovalService
{
    public function __construct(
        protected SubscriptionService $subscriptions,
        protected ActivityLogger $activity,
    ) {
    }

    public function submitted(SubscriptionPayment $payment, ?string $ip = null): void
    {
        $this->log($payment, null, 'submitted', null, PaymentProofStatus::Pending, null, $ip);
    }

    public function approve(SubscriptionPayment $payment, int $reviewerId, ?string $note = null, ?string $ip = null): void
    {
        abort_if($payment->status === PaymentProofStatus::Approved, 422, __('Already approved.'));

        DB::transaction(function () use ($payment, $reviewerId, $note, $ip) {
            $from = $payment->status;
            $payment->update(['status' => PaymentProofStatus::Approved]);
            $this->subscriptions->activateFromPayment($payment->fresh());
            $this->log($payment, $reviewerId, 'approved', $from, PaymentProofStatus::Approved, $note, $ip);
        });
    }

    public function reject(SubscriptionPayment $payment, int $reviewerId, string $note, ?string $ip = null): void
    {
        $from = $payment->status;
        $payment->update(['status' => PaymentProofStatus::Rejected]);
        $this->log($payment, $reviewerId, 'rejected', $from, PaymentProofStatus::Rejected, $note, $ip);
    }

    public function requestInfo(SubscriptionPayment $payment, int $reviewerId, string $note, ?string $ip = null): void
    {
        $from = $payment->status;
        $payment->update(['status' => PaymentProofStatus::InfoRequested]);
        $this->log($payment, $reviewerId, 'info_requested', $from, PaymentProofStatus::InfoRequested, $note, $ip);
    }

    protected function log(
        SubscriptionPayment $payment,
        ?int $reviewerId,
        string $action,
        ?PaymentProofStatus $from,
        ?PaymentProofStatus $to,
        ?string $note,
        ?string $ip,
    ): void {
        PaymentProofReview::create([
            'subscription_payment_id' => $payment->id,
            'reviewer_id' => $reviewerId,
            'action' => $action,
            'from_status' => $from?->value,
            'to_status' => $to?->value,
            'note' => $note,
            'ip' => $ip,
        ]);

        $this->activity->log(
            'payment.'.$action,
            __('Payment proof :action', ['action' => str_replace('_', ' ', $action)]),
            $payment, $payment->tenant_id, $reviewerId,
            ['gateway' => $payment->gateway->value, 'amount' => $payment->amount], $ip,
        );
    }
}
