<?php
// app/Models/JournalEntry.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;

class JournalEntry extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'branch_id',
        'entry_number',
        'transaction_date',
        'reference',
        'description',
        'status',
        'transaction_type',
        'total_debit',
        'total_credit',
        'created_by',
        'approved_by',
        'reversal_of'
    ];

    protected $casts = [
        'transaction_date' => 'date'
    ];

    // Relationships
    public function branch()
    {
        return $this->belongsTo(Branch::class);
    }

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

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

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

    public function originalEntry()
    {
        return $this->belongsTo(JournalEntry::class, 'reversal_of');
    }

    public function reversal()
    {
        return $this->hasOne(JournalEntry::class, 'reversal_of');
    }

    // Scopes
    public function scopePosted($query)
    {
        return $query->where('status', 'posted');
    }

    public function scopeByBranch($query, $branchId)
    {
        return $query->where('branch_id', $branchId);
    }

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

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

    // Methods
    public function isBalanced()
    {
        return $this->total_debit == $this->total_credit;
    }

    public function post()
    {
        if ($this->isBalanced() && $this->status === 'draft') {
            $this->update(['status' => 'posted']);

            // Log the posting
            FinancialAuditTrail::create([
                'action' => 'journal_entry_posted',
                'table_name' => 'journal_entries',
                'record_id' => $this->id,
                'old_values' => ['status' => 'draft'],
                'new_values' => ['status' => 'posted'],
                'changed_by' => auth()->id(),
                'ip_address' => request()->ip()
            ]);

            return true;
        }
        return false;
    }

    public function reverse($reason = null)
    {
        if ($this->status === 'posted') {
            DB::transaction(function () use ($reason) {
                // Create reversal entry
                $reversalEntry = JournalEntry::create([
                    'branch_id' => $this->branch_id,
                    'entry_number' => 'JE-REV-' . $this->entry_number,
                    'transaction_date' => now(),
                    'reference' => $this->reference,
                    'description' => 'Reversal: ' . $this->description . ($reason ? ' - ' . $reason : ''),
                    'status' => 'posted',
                    'transaction_type' => 'adjustment',
                    'total_debit' => $this->total_credit, // Swap debit/credit
                    'total_credit' => $this->total_debit,
                    'created_by' => auth()->id(),
                    'reversal_of' => $this->id
                ]);

                // Create reversal items
                foreach ($this->items as $item) {
                    $reversalEntry->items()->create([
                        'account_id' => $item->account_id,
                        'client_id' => $item->client_id,
                        'loan_id' => $item->loan_id,
                        'savings_id' => $item->savings_id,
                        'debit' => $item->credit, // Swap debit/credit
                        'credit' => $item->debit,
                        'description' => 'Reversal: ' . $item->description
                    ]);
                }

                $this->update(['status' => 'reversed']);
            });

            return true;
        }
        return false;
    }
}
