<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class LiabilityAccount extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * Status do contrato
     */
    public const STATUS_ACTIVE = 'active';
    public const STATUS_PAID_OFF = 'paid_off';
    public const STATUS_DEFAULTED = 'defaulted';
    public const STATUS_RENEGOTIATED = 'renegotiated';

    public const STATUSES = [
        self::STATUS_ACTIVE => 'Ativo',
        self::STATUS_PAID_OFF => 'Quitado',
        self::STATUS_DEFAULTED => 'Inadimplente',
        self::STATUS_RENEGOTIATED => 'Renegociado',
    ];

    protected $fillable = [
        'user_id',
        'account_id',
        'name',
        'contract_number',
        'creditor',
        'description',
        'principal_amount',
        'total_interest',
        'total_fees',
        'total_contract_value',
        'total_paid',
        'total_pending',
        'principal_paid',
        'interest_paid',
        'fees_paid',
        'monthly_interest_rate',
        'annual_interest_rate',
        'total_interest_rate',
        'total_installments',
        'paid_installments',
        'pending_installments',
        'start_date',
        'end_date',
        'first_due_date',
        'currency',
        'color',
        'icon',
        'status',
        'is_active',
    ];

    protected $casts = [
        'principal_amount' => 'decimal:2',
        'total_interest' => 'decimal:2',
        'total_fees' => 'decimal:2',
        'total_contract_value' => 'decimal:2',
        'total_paid' => 'decimal:2',
        'total_pending' => 'decimal:2',
        'principal_paid' => 'decimal:2',
        'interest_paid' => 'decimal:2',
        'fees_paid' => 'decimal:2',
        'monthly_interest_rate' => 'decimal:4',
        'annual_interest_rate' => 'decimal:4',
        'total_interest_rate' => 'decimal:4',
        'start_date' => 'date',
        'end_date' => 'date',
        'first_due_date' => 'date',
        'is_active' => 'boolean',
    ];

    protected $appends = ['progress_percentage', 'remaining_balance'];

    /**
     * Relação com o usuário
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Relação com a conta geral (opcional)
     */
    public function account(): BelongsTo
    {
        return $this->belongsTo(Account::class);
    }

    /**
     * Parcelas do contrato
     */
    public function installments(): HasMany
    {
        return $this->hasMany(LiabilityInstallment::class)->orderBy('installment_number');
    }

    /**
     * Parcelas pagas
     */
    public function paidInstallments(): HasMany
    {
        return $this->hasMany(LiabilityInstallment::class)->where('status', 'paid');
    }

    /**
     * Parcelas pendentes
     */
    public function pendingInstallments(): HasMany
    {
        return $this->hasMany(LiabilityInstallment::class)->where('status', 'pending');
    }

    /**
     * Próxima parcela a vencer
     */
    public function nextInstallment()
    {
        return $this->installments()
            ->where('status', 'pending')
            ->orderBy('due_date')
            ->first();
    }

    /**
     * Percentual de progresso (quanto já foi pago do principal)
     */
    public function getProgressPercentageAttribute(): float
    {
        if ($this->principal_amount <= 0) {
            return 0;
        }
        return round(($this->principal_paid / $this->principal_amount) * 100, 2);
    }

    /**
     * Saldo restante do principal
     */
    public function getRemainingBalanceAttribute(): float
    {
        return $this->principal_amount - $this->principal_paid;
    }

    /**
     * Recalcular totais baseado nas parcelas
     */
    public function recalculateTotals(): void
    {
        $installments = $this->installments()->get();
        
        $this->total_installments = $installments->count();
        $this->paid_installments = $installments->where('status', 'paid')->count();
        $this->pending_installments = $installments->where('status', 'pending')->count();
        
        // Totais do contrato
        $this->total_interest = $installments->sum('interest_amount');
        $this->total_fees = $installments->sum('fee_amount');
        $this->principal_amount = $installments->sum('principal_amount');
        $this->total_contract_value = $installments->sum('installment_amount');
        
        // Valores pagos
        $paidInstallments = $installments->where('status', 'paid');
        $this->total_paid = $paidInstallments->sum('installment_amount');
        $this->principal_paid = $paidInstallments->sum('principal_amount');
        $this->interest_paid = $paidInstallments->sum('interest_amount');
        $this->fees_paid = $paidInstallments->sum('fee_amount');
        
        // Valores pendentes
        $pendingInstallments = $installments->where('status', 'pending');
        $this->total_pending = $pendingInstallments->sum('installment_amount');
        
        // Calcular taxas de juros
        $this->calculateInterestRates();
        
        // Datas
        $firstInstallment = $installments->sortBy('due_date')->first();
        $lastInstallment = $installments->sortBy('due_date')->last();
        
        if ($firstInstallment) {
            $this->first_due_date = $firstInstallment->due_date;
            $this->start_date = $firstInstallment->due_date;
        }
        if ($lastInstallment) {
            $this->end_date = $lastInstallment->due_date;
        }
        
        // Atualizar status
        if ($this->pending_installments === 0 && $this->paid_installments > 0) {
            $this->status = self::STATUS_PAID_OFF;
        }
        
        $this->save();
    }

    /**
     * Calcular taxas de juros baseado nos dados
     */
    protected function calculateInterestRates(): void
    {
        if ($this->principal_amount <= 0) {
            return;
        }

        // Taxa total do contrato
        $this->total_interest_rate = round(($this->total_interest / $this->principal_amount) * 100, 4);

        // Taxa mensal média
        if ($this->total_installments > 0) {
            $this->monthly_interest_rate = round($this->total_interest_rate / $this->total_installments, 4);
            $this->annual_interest_rate = round($this->monthly_interest_rate * 12, 4);
        }
    }

    /**
     * Scope para contas ativas
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope para um status específico
     */
    public function scopeOfStatus($query, string $status)
    {
        return $query->where('status', $status);
    }
}
