<?php

namespace App\Models;

use App\Traits\Auditable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

class Transaction extends Model
{
    use HasFactory, Auditable, SoftDeletes;

    protected $fillable = [
        'organization_id',
        'account_id',
        'category_id',
        'amount',
        'type',
        'reference',
        'description',
        'date',
        'recorded_by',
        'status',
        'approved_by',
        'approved_at',
        'rejection_reason',
    ];

    protected function casts(): array
    {
        return [
            'amount' => 'decimal:2',
            'date' => 'date',
            'approved_at' => 'datetime',
        ];
    }

    /**
     * Boot method to handle balance updates.
     * Only adjusts balance for approved transactions.
     */
    protected static function booted(): void
    {
        static::created(function (Transaction $transaction) {
            // Only adjust balance if already approved (Credit transactions)
            if ($transaction->status === 'Approved') {
                $transaction->account->adjustBalance($transaction->amount, $transaction->type);
            }
        });

        static::deleted(function (Transaction $transaction) {
            // Only reverse if it was approved
            if ($transaction->status === 'Approved') {
                $reverseType = $transaction->type === 'Credit' ? 'Debit' : 'Credit';
                $transaction->account->adjustBalance($transaction->amount, $reverseType);
            }
        });
    }

    /**
     * Approve a pending transaction.
     */
    public function approve(User $approver): bool
    {
        if ($this->status !== 'Pending') {
            return false;
        }

        // Cannot approve own transaction
        if ($approver->id === $this->recorded_by) {
            return false;
        }

        // Check permission
        if (!$approver->can('finance.approve')) {
            return false;
        }

        $this->update([
            'status' => 'Approved',
            'approved_by' => $approver->id,
            'approved_at' => now(),
        ]);

        // Now adjust the balance
        $this->account->adjustBalance($this->amount, $this->type);

        return true;
    }

    /**
     * Reject a pending transaction.
     */
    public function reject(User $rejector, string $reason): bool
    {
        if ($this->status !== 'Pending') {
            return false;
        }

        $this->update([
            'status' => 'Rejected',
            'approved_by' => $rejector->id,
            'approved_at' => now(),
            'rejection_reason' => $reason,
        ]);

        return true;
    }

    /**
     * Check if transaction requires approval.
     */
    public function requiresApproval(): bool
    {
        return $this->type === 'Debit';
    }

    public function organization(): BelongsTo
    {
        return $this->belongsTo(Organization::class);
    }

    public function account(): BelongsTo
    {
        return $this->belongsTo(Account::class);
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(TransactionCategory::class, 'category_id');
    }

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

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

