<?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;

class LiabilityInstallment extends Model
{
    use HasFactory, SoftDeletes;

    /**
     * Status da parcela
     */
    public const STATUS_PENDING = 'pending';
    public const STATUS_PAID = 'paid';
    public const STATUS_PARTIAL = 'partial';
    public const STATUS_OVERDUE = 'overdue';
    public const STATUS_CANCELLED = 'cancelled';

    public const STATUSES = [
        self::STATUS_PENDING => 'Pendente',
        self::STATUS_PAID => 'Pago',
        self::STATUS_PARTIAL => 'Parcial',
        self::STATUS_OVERDUE => 'Atrasado',
        self::STATUS_CANCELLED => 'Cancelado',
    ];

    protected $fillable = [
        'liability_account_id',
        'installment_number',
        'due_date',
        'installment_amount',
        'principal_amount',
        'interest_amount',
        'fee_amount',
        'paid_amount',
        'paid_date',
        'status',
        'reconciled_transaction_id',
        'payment_account_id',
        'notes',
    ];

    protected $casts = [
        'due_date' => 'date',
        'paid_date' => 'date',
        'installment_amount' => 'decimal:2',
        'principal_amount' => 'decimal:2',
        'interest_amount' => 'decimal:2',
        'fee_amount' => 'decimal:2',
        'paid_amount' => 'decimal:2',
    ];

    protected $appends = ['is_overdue', 'days_until_due'];

    /**
     * Relação com o contrato passivo
     */
    public function liabilityAccount(): BelongsTo
    {
        return $this->belongsTo(LiabilityAccount::class);
    }

    /**
     * Relação com a conta usada para pagamento
     */
    public function paymentAccount(): BelongsTo
    {
        return $this->belongsTo(Account::class, 'payment_account_id');
    }

    /**
     * Verificar se está atrasado
     */
    public function getIsOverdueAttribute(): bool
    {
        if ($this->status === self::STATUS_PAID) {
            return false;
        }
        return $this->due_date->isPast();
    }

    /**
     * Dias até o vencimento (negativo se atrasado)
     */
    public function getDaysUntilDueAttribute(): int
    {
        return now()->startOfDay()->diffInDays($this->due_date, false);
    }

    /**
     * Marcar como pago
     */
    public function markAsPaid(?float $amount = null, ?\DateTime $paidDate = null, ?int $paymentAccountId = null): void
    {
        $this->paid_amount = $amount ?? $this->installment_amount;
        $this->paid_date = $paidDate ?? now();
        $this->payment_account_id = $paymentAccountId;
        $this->status = self::STATUS_PAID;
        $this->save();

        // Recalcular totais do contrato
        $this->liabilityAccount->recalculateTotals();
    }

    /**
     * Atualizar status baseado na data de vencimento
     */
    public function updateOverdueStatus(): void
    {
        if ($this->status === self::STATUS_PENDING && $this->is_overdue) {
            $this->status = self::STATUS_OVERDUE;
            $this->save();
        }
    }

    /**
     * Scope para parcelas pendentes
     */
    public function scopePending($query)
    {
        return $query->where('status', self::STATUS_PENDING);
    }

    /**
     * Scope para parcelas pagas
     */
    public function scopePaid($query)
    {
        return $query->where('status', self::STATUS_PAID);
    }

    /**
     * Scope para parcelas atrasadas
     */
    public function scopeOverdue($query)
    {
        return $query->where('status', self::STATUS_OVERDUE)
            ->orWhere(function ($q) {
                $q->where('status', self::STATUS_PENDING)
                    ->where('due_date', '<', now()->startOfDay());
            });
    }
}
