<?php

namespace App\Domain\Financial\Models;

use App\Domain\Financial\Enums\InvoiceStatus;
use App\Domain\Shared\Traits\Auditable;
use App\Domain\Shared\Traits\BelongsToAcademy;
use App\Domain\Shared\Traits\HasUuid;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Domain\Shared\Traits\BelongsToBranch;

class Invoice extends Model
{
    use HasUuid, BelongsToAcademy, SoftDeletes, Auditable, BelongsToBranch;

    protected $fillable = [
        'academy_id',
        'branch_id',
        'number',
        'type',
        'status',
        'billable_type',
        'billable_id',
        'contact_name',
        'contact_phone',
        'contact_email',
        'subtotal_amount',
        'discount_amount',
        'tax_amount',
        'service_fee_amount',
        'total_amount',
        'paid_amount',
        'due_amount',
        'currency',
        'issue_date',
        'due_date',
        'paid_at',
        'cancelled_at',
        'notes',
        'metadata',
        'print_count',
        'last_printed_at',
        'created_by',
        'approved_by',
        'collected_by',
    ];

    protected function casts(): array
    {
        return [
            'status' => InvoiceStatus::class,
            'subtotal_amount' => 'integer',
            'discount_amount' => 'integer',
            'tax_amount' => 'integer',
            'service_fee_amount' => 'integer',
            'total_amount' => 'integer',
            'paid_amount' => 'integer',
            'due_amount' => 'integer',
            'issue_date' => 'date',
            'due_date' => 'date',
            'paid_at' => 'datetime',
            'cancelled_at' => 'datetime',
            'metadata' => 'array',
            'last_printed_at' => 'datetime',
        ];
    }

    public function billable(): MorphTo
    {
        return $this->morphTo();
    }

    public function items(): HasMany
    {
        return $this->hasMany(InvoiceItem::class);
    }

    public function payments(): HasMany
    {
        return $this->hasMany(Payment::class);
    }

    public function paymentPlan(): HasOne
    {
        return $this->hasOne(PaymentPlan::class);
    }

    public function transactions(): HasMany
    {
        return $this->hasMany(Transaction::class);
    }

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by');
    }

    public function collector(): BelongsTo
    {
        return $this->belongsTo(User::class, 'collected_by');
    }

    public function enrollments(): HasMany
    {
        return $this->hasMany(\App\Domain\Training\Models\Enrollment::class);
    }

    public function posTransaction(): HasOne
    {
        return $this->hasOne(\App\Domain\POS\Models\POSTransaction::class);
    }

    public function recalculateTotals(): void
    {
        $this->subtotal_amount = $this->items()->sum('total_amount');
        $this->total_amount = $this->subtotal_amount - $this->discount_amount + $this->tax_amount + ($this->service_fee_amount ?? 0);
        $this->due_amount = $this->total_amount - $this->paid_amount;
        $this->save();
    }

    public function isFinancialAudit(): bool
    {
        return true;
    }
}
