<?php

namespace App\Livewire\Admin\Pembayaran;

use App\Enums\OrderStatus;
use App\Enums\PaymentStatus;
use App\Models\Payment;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
use Spatie\Activitylog\Models\Activity;

#[Layout('layouts.admin')]
#[Title('Detail Pembayaran')]
class Show extends Component
{
    public Payment $payment;

    public bool $showVerifyModal = false;

    public bool $showRejectModal = false;
    public string $rejectReason  = '';

    public function mount(int $id): void
    {
        $this->payment = Payment::with([
            'order.deliveryArea',
            'order.voucher',
            'verifiedBy',
        ])->findOrFail($id);
    }

    // ── Verifikasi ───────────────────────────────────────────────────────

    public function openVerifyModal(): void
    {
        if (! $this->payment->isPending()) {
            $this->dispatch('notify', type: 'error', message: 'Hanya pembayaran berstatus "Menunggu Verifikasi" yang dapat diproses.');
            return;
        }

        $this->showVerifyModal = true;
    }

    public function verifyPayment(): void
    {
        abort_unless(Auth::user()->can('payment.verify'), 403);

        if (! $this->payment->isPending()) {
            $this->showVerifyModal = false;
            $this->dispatch('notify', type: 'error', message: 'Pembayaran ini sudah diproses sebelumnya.');
            return;
        }

        $this->payment->update([
            'status'      => PaymentStatus::Verified->value,
            'verified_by' => Auth::id(),
            'verified_at' => now(),
        ]);

        // BFS v1.1 — Sinkronisasi satu arah: Payment Verified → Order Paid
        // Hanya dijalankan jika order masih pending (belum bergerak).
        // Untuk COD: saat verifikasi terjadi, order biasanya sudah di delivering,
        // sehingga kondisi ini tidak terpenuhi dan sinkronisasi tidak berjalan — benar.
        if ($this->payment->order->isPending()) {
            $this->payment->order->update(['status' => OrderStatus::Paid->value]);
        }

        $this->payment->refresh();
        $this->showVerifyModal = false;
        $this->dispatch('notify', type: 'success', message: 'Pembayaran berhasil diverifikasi.');
    }

    // ── Tolak ────────────────────────────────────────────────────────────

    public function openRejectModal(): void
    {
        if (! $this->payment->isPending()) {
            $this->dispatch('notify', type: 'error', message: 'Hanya pembayaran berstatus "Menunggu Verifikasi" yang dapat diproses.');
            return;
        }

        $this->rejectReason    = '';
        $this->showRejectModal = true;
    }

    public function rejectPayment(): void
    {
        abort_unless(Auth::user()->can('payment.reject'), 403);

        $this->validate([
            'rejectReason' => ['required', 'string', 'min:5'],
        ], [
            'rejectReason.required' => 'Alasan penolakan wajib diisi.',
            'rejectReason.min'      => 'Alasan penolakan minimal 5 karakter.',
        ]);

        if (! $this->payment->isPending()) {
            $this->showRejectModal = false;
            $this->dispatch('notify', type: 'error', message: 'Pembayaran ini sudah diproses sebelumnya.');
            return;
        }

        // BFS v1.1 — Validasi V-6: tidak boleh reject jika order sudah masuk operasional.
        // Secara bisnis: barang sudah diproses atau sedang dikirim, reject tidak relevan.
        $orderStatus = $this->payment->order->status;
        if (in_array($orderStatus, [OrderStatus::Processing, OrderStatus::Delivering, OrderStatus::Completed])) {
            $this->showRejectModal = false;
            $this->dispatch('notify', type: 'error', message: 'Pembayaran tidak dapat ditolak. Pesanan sudah masuk tahap operasional (' . $orderStatus->label() . ').');
            return;
        }

        $this->payment->update([
            'status'          => PaymentStatus::Rejected->value,
            'verified_by'     => Auth::id(),
            'verified_at'     => now(),
            'rejection_notes' => $this->rejectReason,
        ]);

        // BFS v1.1 — Sinkronisasi satu arah: Payment Rejected → Order kembali Pending
        // Hanya dijalankan jika order masih paid (belum operasional).
        if ($this->payment->order->status === OrderStatus::Paid) {
            $this->payment->order->update(['status' => OrderStatus::Pending->value]);
        }

        $this->payment->refresh();
        $this->showRejectModal = false;
        $this->dispatch('notify', type: 'success', message: 'Pembayaran berhasil ditolak.');
    }

    public function render()
    {
        $timeline = Activity::query()
            ->where('subject_type', Payment::class)
            ->where('subject_id', $this->payment->id)
            ->where('log_name', 'payment')
            ->with('causer')
            ->latest()
            ->get();

        return view('livewire.admin.pembayaran.show', compact('timeline'));
    }
}
