<?php

namespace App\Http\Controllers\Api\V1;

use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Models\Payment;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ReceiptController extends Controller
{
    public function invoiceDetail(string $invoiceUuid, Request $request): JsonResponse
    {
        $user = $request->user();

        $invoice = Invoice::where('uuid', $invoiceUuid)
            ->whereNotIn('status', ['cancelled', 'draft'])
            ->with(['items', 'payments' => fn ($q) => $q->where('status', 'confirmed')])
            ->firstOrFail();

        // Authorization: user must be related to the billable participant
        if ($invoice->billable_type === 'App\\Domain\\Participant\\Models\\Participant') {
            $this->verifyAccess($user, $invoice->billable_id);
        }

        return response()->json([
            'data' => [
                'uuid' => $invoice->uuid,
                'number' => $invoice->number ?? '',
                'status' => $invoice->status,
                'issue_date' => $invoice->issue_date?->toDateString(),
                'due_date' => $invoice->due_date?->toDateString(),
                'subtotal' => $invoice->subtotal_amount,
                'discount_amount' => $invoice->discount_amount,
                'tax_amount' => $invoice->tax_amount,
                'total_amount' => $invoice->total_amount,
                'paid_amount' => $invoice->paid_amount,
                'balance_due' => $invoice->due_amount,
                'total_display' => number_format($invoice->total_amount / 100, 2) . ' ج.م',
                'balance_display' => number_format($invoice->due_amount / 100, 2) . ' ج.م',
                'notes' => $invoice->notes,
                'items' => $invoice->items->map(fn ($item) => [
                    'description' => $item->description_ar ?? $item->description ?? '',
                    'quantity' => $item->quantity,
                    'unit_price' => $item->unit_price,
                    'unit_price_display' => number_format($item->unit_price / 100, 2) . ' ج.م',
                    'line_total' => $item->line_total,
                    'line_total_display' => number_format($item->line_total / 100, 2) . ' ج.م',
                ]),
                'payments' => $invoice->payments->map(fn ($pay) => [
                    'reference' => $pay->reference,
                    'method' => $pay->method->value ?? $pay->method,
                    'amount' => $pay->amount,
                    'amount_display' => number_format($pay->amount / 100, 2) . ' ج.م',
                    'payment_date' => $pay->payment_date?->toDateString(),
                    'confirmed_at' => $pay->confirmed_at?->toIso8601String(),
                ]),
                'can_pay_online' => $invoice->due_amount > 0,
            ],
        ]);
    }

    public function paymentReceipt(string $paymentUuid, Request $request): JsonResponse
    {
        $user = $request->user();

        $payment = Payment::withoutGlobalScope('academy')
            ->where('uuid', $paymentUuid)
            ->where('status', 'confirmed')
            ->with('invoice:id,uuid,number,total_amount')
            ->firstOrFail();

        if ($payment->invoice && $payment->invoice->billable_type === 'App\\Domain\\Participant\\Models\\Participant') {
            $this->verifyAccess($user, $payment->invoice->billable_id);
        }

        return response()->json([
            'data' => [
                'uuid' => $payment->uuid,
                'reference' => $payment->reference,
                'method' => $payment->method->value ?? $payment->method,
                'amount' => $payment->amount,
                'amount_display' => number_format($payment->amount / 100, 2) . ' ج.م',
                'currency' => $payment->currency ?? 'EGP',
                'payment_date' => $payment->payment_date?->toDateString(),
                'confirmed_at' => $payment->confirmed_at?->toIso8601String(),
                'invoice_uuid' => $payment->invoice?->uuid,
                'invoice_number' => $payment->invoice?->number ?? '',
            ],
        ]);
    }

    private function verifyAccess($user, int $participantId): void
    {
        $personId = $user->person_id;
        if (!$personId) {
            abort(403, 'غير مصرح');
        }

        $participant = \App\Domain\Participant\Models\Participant::find($participantId);
        if (!$participant) {
            abort(404);
        }

        if ($participant->person_id === $personId) {
            return;
        }

        $guardian = \App\Domain\Identity\Models\Guardian::where('person_id', $personId)->first();
        if ($guardian && $guardian->participants()->where('participants.id', $participantId)->exists()) {
            return;
        }

        abort(403, 'غير مصرح لك بالوصول لهذه الفاتورة');
    }
}
