<?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 RecurringTemplate extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'user_id',
        'source_transaction_id',
        'name',
        'description',
        'frequency',
        'frequency_interval',
        'day_of_month',
        'day_of_week',
        'start_date',
        'end_date',
        'max_occurrences',
        'account_id',
        'category_id',
        'cost_center_id',
        'type',
        'planned_amount',
        'transaction_description',
        'notes',
        'is_active',
        'last_generated_date',
        'occurrences_generated',
    ];

    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'last_generated_date' => 'date',
        'planned_amount' => 'decimal:2',
        'is_active' => 'boolean',
        'frequency_interval' => 'integer',
        'day_of_month' => 'integer',
        'day_of_week' => 'integer',
        'max_occurrences' => 'integer',
        'occurrences_generated' => 'integer',
    ];

    /**
     * Frequências disponíveis
     */
    public const FREQUENCIES = [
        'daily' => ['label' => 'Diária', 'days' => 1],
        'weekly' => ['label' => 'Semanal', 'days' => 7],
        'biweekly' => ['label' => 'Quinzenal', 'days' => 14],
        'monthly' => ['label' => 'Mensal', 'months' => 1],
        'bimonthly' => ['label' => 'Bimestral', 'months' => 2],
        'quarterly' => ['label' => 'Trimestral', 'months' => 3],
        'semiannual' => ['label' => 'Semestral', 'months' => 6],
        'annual' => ['label' => 'Anual', 'months' => 12],
    ];

    // ============================================
    // Relacionamentos
    // ============================================

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

    public function sourceTransaction(): BelongsTo
    {
        return $this->belongsTo(Transaction::class, 'source_transaction_id');
    }

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

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

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

    public function instances(): HasMany
    {
        return $this->hasMany(RecurringInstance::class);
    }

    public function pendingInstances(): HasMany
    {
        return $this->hasMany(RecurringInstance::class)->where('status', 'pending');
    }

    public function paidInstances(): HasMany
    {
        return $this->hasMany(RecurringInstance::class)->where('status', 'paid');
    }

    // ============================================
    // Métodos de Negócio
    // ============================================

    /**
     * Verifica se pode gerar mais instâncias
     */
    public function canGenerateMore(): bool
    {
        if (!$this->is_active) {
            return false;
        }

        // Verificar limite de ocorrências
        if ($this->max_occurrences !== null && $this->occurrences_generated >= $this->max_occurrences) {
            return false;
        }

        // Verificar data fim
        if ($this->end_date !== null && now()->startOfDay()->gt($this->end_date)) {
            return false;
        }

        return true;
    }

    /**
     * Retorna a frequência formatada para exibição
     */
    public function getFrequencyLabelAttribute(): string
    {
        $freq = self::FREQUENCIES[$this->frequency] ?? null;
        if (!$freq) {
            return $this->frequency;
        }

        $label = $freq['label'];
        if ($this->frequency_interval > 1) {
            $label = "A cada {$this->frequency_interval} " . strtolower($label);
        }

        return $label;
    }

    /**
     * Retorna quantas instâncias pendentes existem
     */
    public function getPendingCountAttribute(): int
    {
        return $this->pendingInstances()->count();
    }

    /**
     * Retorna o total pago até agora
     */
    public function getTotalPaidAttribute(): float
    {
        return (float) $this->paidInstances()->sum('paid_amount');
    }
}
