<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use App\Services\NumberGenerationService;

class AccountTransaction extends Model
{
    use LogsActivity;

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($transaction) {
            // Auto-generate transaction number if not provided
            if (empty($transaction->transaction_number)) {
                $numberService = app(NumberGenerationService::class);
                $transaction->transaction_number = $numberService->generateTransactionNumber();
            }
        });

        static::created(function ($transaction) {
            $transaction->updateAccountBalance();
        });

        static::updated(function ($transaction) {
            $transaction->updateAccountBalance();
        });

        static::deleted(function ($transaction) {
            $transaction->updateAccountBalance();
        });
    }

    protected $table = 'account_transactions';

    protected $fillable = [
        'transaction_number',
        'account_id',
        'chart_of_account_id',
        'amount',
        'transaction_type',
        'reference_id',
        'reference_type',
        'remarks',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
    ];

    // Relationships
    public function account(): BelongsTo
    {
        return $this->belongsTo(Account::class);
    }
    public function purchaseOrder(): BelongsTo
    {
        return $this->belongsTo(PurchaseOrder::class,'reference_id');
    }
    public function factoryInvoice(): BelongsTo
    {
        return $this->belongsTo(FactoryInvoice::class,'reference_id');
    }
    public function chartOfAccount(): BelongsTo
    {
        return $this->belongsTo(ChartOfAccount::class);
    }

    public function reference(): BelongsTo
    {
        return $this->morphTo();
    }

    // Scopes
    public function scopeDebits($query)
    {
        return $query->where('transaction_type', 'debit');
    }

    public function scopeCredits($query)
    {
        return $query->where('transaction_type', 'credit');
    }

    public function scopeForAccount($query, $accountId)
    {
        return $query->where('account_id', $accountId);
    }

    public function scopeForChartOfAccount($query, $chartOfAccountId)
    {
        return $query->where('chart_of_account_id', $chartOfAccountId);
    }

    public function scopeByReference($query, $referenceType, $referenceId)
    {
        return $query->where('reference_type', $referenceType)
                    ->where('reference_id', $referenceId);
    }

    public function scopeByDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    // Helper methods
    public function getFormattedAmountAttribute()
    {
        return format_currency($this->amount);
    }

    public function getTransactionTypeLabelAttribute()
    {
        return ucfirst($this->transaction_type);
    }

    public function getTransactionTypeBadgeAttribute()
    {
        $class = $this->transaction_type === 'debit' ? 'danger' : 'success';
        return '<span class="badge bg-' . $class . '">' . ucfirst($this->transaction_type) . '</span>';
    }

    public function getReferenceNameAttribute()
    {
        if (!$this->reference_type || !$this->reference_id) {
            return '-';
        }

        $referenceClass = $this->reference_type;
        if (class_exists($referenceClass)) {
            $reference = $referenceClass::find($this->reference_id);
            if ($reference) {
                // Special handling for FactoryInvoice - show invoice number
                if ($reference instanceof \App\Models\FactoryInvoice) {
                    return $reference->invoice_number;
                }
                // Default behavior for other models
                return $reference->name ?? $reference->id;
            }
        }

        return 'Unknown';
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->useLogName('account_transaction')
            ->logFillable()
            ->logOnlyDirty()
            ->dontSubmitEmptyLogs();
    }

    protected function updateAccountBalance()
    {
        if ($this->account) {
            $this->account->update([
                'balance' => $this->account->fresh()->balance
            ]);
        }
    }
}
