<?php

namespace App\Models;

use App\Enums\JournalStatus;
use App\Models\Concerns\HasPublicId;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use LogicException;

final class JournalEntry extends Model
{
    use HasPublicId;
    protected $fillable = ['public_id','company_id','branch_id','accounting_period_id','journal_number','posting_date','document_date','reference_number','source_module','source_type','source_id','description','currency_code','exchange_rate','debit_total','credit_total','status','created_by','approved_by','posted_by','posted_at','reversal_of_id'];
    protected function casts(): array { return ['posting_date'=>'date','document_date'=>'date','exchange_rate'=>'decimal:8','debit_total'=>'decimal:4','credit_total'=>'decimal:4','status'=>JournalStatus::class,'posted_at'=>'datetime']; }
    public function lines(): HasMany { return $this->hasMany(JournalLine::class); }
    public function source(): MorphTo { return $this->morphTo(); }
    public function period(): BelongsTo { return $this->belongsTo(AccountingPeriod::class, 'accounting_period_id'); }
    public function branch(): BelongsTo { return $this->belongsTo(Branch::class); }
    public function reversalOf(): BelongsTo { return $this->belongsTo(self::class, 'reversal_of_id'); }
    protected static function booted(): void
    {
        static::updating(function (self $journal): void {
            if ($journal->getRawOriginal('status') === JournalStatus::POSTED->value) {
                throw new LogicException('Posted journals are immutable; create a reversal.');
            }
        });
        static::deleting(fn (self $journal) => $journal->getRawOriginal('status') === JournalStatus::POSTED->value ? throw new LogicException('Posted journals cannot be deleted.') : true);
    }
}
