<?php

namespace App\Http\Controllers\Api\V1;

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

class InstallmentController extends Controller
{
    public function plans(string $participantUuid, Request $request): JsonResponse
    {
        $participant = $this->findAuthorized($participantUuid, $request->user());

        $invoiceIds = Invoice::where('billable_type', 'App\\Domain\\Participant\\Models\\Participant')
            ->where('billable_id', $participant->id)
            ->whereNotIn('status', ['cancelled', 'draft'])
            ->pluck('id');

        $plans = PaymentPlan::whereIn('invoice_id', $invoiceIds)
            ->with(['invoice:id,uuid,total_amount,paid_amount,due_amount,status', 'installments'])
            ->orderByDesc('created_at')
            ->get();

        return response()->json([
            'data' => $plans->map(fn ($plan) => [
                'id' => $plan->uuid,
                'invoice_uuid' => $plan->invoice?->uuid,
                'status' => $plan->status,
                'total_installments' => $plan->total_installments,
                'paid_installments' => $plan->paid_installments,
                'installment_amount' => $plan->installment_amount,
                'installment_amount_display' => number_format($plan->installment_amount / 100, 2) . ' ج.م',
                'frequency' => $plan->frequency,
                'next_due_date' => $plan->next_due_date?->toDateString(),
                'is_complete' => $plan->isComplete(),
                'progress_percent' => $plan->total_installments > 0
                    ? round($plan->paid_installments / $plan->total_installments * 100)
                    : 0,
                'installments' => $plan->installments->map(fn ($inst) => [
                    'sequence' => $inst->sequence,
                    'amount' => $inst->amount,
                    'amount_display' => number_format($inst->amount / 100, 2) . ' ج.م',
                    'due_date' => $inst->due_date?->toDateString(),
                    'status' => $inst->status,
                    'is_overdue' => $inst->isOverdue(),
                    'paid_at' => $inst->paid_at?->toIso8601String(),
                ]),
            ]),
        ]);
    }

    private function findAuthorized(string $uuid, $user): Participant
    {
        $participant = Participant::where('uuid', $uuid)->firstOrFail();
        $personId = $user->person_id;

        if (!$personId) {
            abort(403, 'غير مصرح لك بالوصول لهذا المشترك');
        }

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

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

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