<?php

namespace App\Models;

use App\Enums\DocumentStatus;
use App\Models\Concerns\HasPublicId;
use App\Models\Concerns\ImmutableWhenPosted;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;

final class CustomerInvoice extends Model
{
    use HasPublicId, ImmutableWhenPosted;

    protected $fillable = [
        'public_id','company_id','branch_id','party_id','transport_job_id','contract_id','invoice_number',
        'invoice_type','customer_po','pricing_mode','issue_date','supply_date','due_date','currency_code',
        'exchange_rate','subtotal','discount_total','taxable_total','vat_total','grand_total','paid_total',
        'allocated_total','receivable_account_id','income_account_id','output_vat_account_id','tax_code_id',
        'status','approved_by','approved_at','posted_at','created_by','notes','terms','einvoice_status',
        'pdf_hash','pdf_path',
    ];

    protected function casts(): array
    {
        return [
            'issue_date'=>'date','supply_date'=>'date','due_date'=>'date','exchange_rate'=>'decimal:8',
            'subtotal'=>'decimal:4','discount_total'=>'decimal:4','taxable_total'=>'decimal:4','vat_total'=>'decimal:4',
            'grand_total'=>'decimal:4','paid_total'=>'decimal:4','allocated_total'=>'decimal:4',
            'status'=>DocumentStatus::class,'approved_at'=>'datetime','posted_at'=>'datetime',
        ];
    }

    public function company(): BelongsTo { return $this->belongsTo(Company::class); }
    public function branch(): BelongsTo { return $this->belongsTo(Branch::class); }
    public function party(): BelongsTo { return $this->belongsTo(Party::class); }
    public function transportJob(): BelongsTo { return $this->belongsTo(TransportJob::class); }
    public function contract(): BelongsTo { return $this->belongsTo(Contract::class); }
    public function taxCode(): BelongsTo { return $this->belongsTo(TaxCode::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 items(): HasMany { return $this->hasMany(CustomerInvoiceItem::class); }
    public function allocations(): HasMany { return $this->hasMany(ReceiptAllocation::class); }
    public function journal(): MorphOne { return $this->morphOne(JournalEntry::class, 'source'); }
}
