<?php

namespace App\Livewire\Financial;

use App\Domain\Financial\Models\Invoice;
use App\Domain\Financial\Models\PaymentPlan;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('components.layouts.app')]
class PaymentPlanCreate extends Component
{
    public ?int $invoiceId = null;
    public int $installmentCount = 3;
    public string $frequency = 'monthly';
    public string $startDate = '';
    public int $downPayment = 0;
    public array $installments = [];

    public function mount(?int $invoice = null): void
    {
        $this->authorize('invoices.create');
        $this->invoiceId = $invoice;
        $this->startDate = now()->addDays(7)->toDateString();
        $this->calculateInstallments();
    }

    public function updatedInstallmentCount(): void
    {
        $this->calculateInstallments();
    }

    public function updatedFrequency(): void
    {
        $this->calculateInstallments();
    }

    public function updatedStartDate(): void
    {
        $this->calculateInstallments();
    }

    public function updatedDownPayment(): void
    {
        $this->calculateInstallments();
    }

    private function calculateInstallments(): void
    {
        if (!$this->invoiceId) {
            $this->installments = [];
            return;
        }

        $invoice = Invoice::find($this->invoiceId);
        if (!$invoice) return;

        $remaining = $invoice->due_amount - ($this->downPayment * 100);
        if ($remaining <= 0 || $this->installmentCount < 1) {
            $this->installments = [];
            return;
        }

        $perInstallment = intdiv($remaining, $this->installmentCount);
        $lastExtra = $remaining - ($perInstallment * $this->installmentCount);
        $startDate = Carbon::parse($this->startDate);

        $this->installments = [];
        for ($i = 0; $i < $this->installmentCount; $i++) {
            $dueDate = match ($this->frequency) {
                'weekly' => $startDate->copy()->addWeeks($i),
                'biweekly' => $startDate->copy()->addWeeks($i * 2),
                'monthly' => $startDate->copy()->addMonths($i),
                default => $startDate->copy()->addMonths($i),
            };

            $amount = $perInstallment + ($i === $this->installmentCount - 1 ? $lastExtra : 0);
            $this->installments[] = [
                'number' => $i + 1,
                'due_date' => $dueDate->toDateString(),
                'amount' => $amount,
            ];
        }
    }

    public function save(): void
    {
        $this->authorize('invoices.create');

        $invoice = Invoice::findOrFail($this->invoiceId);

        DB::transaction(function () use ($invoice) {
            $plan = PaymentPlan::create([
                'academy_id' => $invoice->academy_id,
                'invoice_id' => $invoice->id,
                'total_installments' => $this->installmentCount,
                'paid_installments' => 0,
                'installment_amount' => $this->installments[0]['amount'] ?? 0,
                'frequency' => $this->frequency,
                'start_date' => $this->startDate,
                'next_due_date' => $this->installments[0]['due_date'] ?? $this->startDate,
                'status' => 'active',
            ]);

            foreach ($this->installments as $inst) {
                $plan->installments()->create([
                    'sequence' => $inst['number'],
                    'due_date' => $inst['due_date'],
                    'amount' => $inst['amount'],
                    'status' => 'pending',
                ]);
            }
        });

        session()->flash('success', __('تم إنشاء خطة الدفع بنجاح'));
        $this->redirect(route('invoices.show', $invoice));
    }

    public function render()
    {
        $invoice = $this->invoiceId ? Invoice::find($this->invoiceId) : null;
        $invoices = Invoice::whereIn('status', ['sent', 'partially_paid', 'overdue'])
            ->where('due_amount', '>', 0)
            ->orderByDesc('created_at')
            ->limit(50)
            ->get();

        return view('livewire.financial.payment-plan-create', [
            'invoice' => $invoice,
            'invoices' => $invoices,
        ]);
    }
}
