<?php

namespace App\Models;

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

class Budget extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'category_id',
        'name',
        'amount',
        'currency',
        'year',
        'month',
        'period_type',
        'is_active',
        'notes',
    ];

    protected $casts = [
        'amount' => 'decimal:2',
        'is_active' => 'boolean',
    ];

    protected $appends = [
        'spent_amount',
        'remaining_amount',
        'usage_percentage',
        'is_exceeded',
        'period_label',
    ];

    // ============================================
    // Relaciones
    // ============================================

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

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

    // ============================================
    // Accessors
    // ============================================

    public function getSpentAmountAttribute()
    {
        // Calcular el gasto real de las transacciones
        $query = Transaction::where('user_id', $this->user_id)
            ->where('type', 'debit')
            ->whereYear('effective_date', $this->year);
        
        if ($this->period_type === 'monthly' && $this->month) {
            $query->whereMonth('effective_date', $this->month);
        }
        
        if ($this->category_id) {
            // Incluir subcategorías
            $categoryIds = [$this->category_id];
            $subcategories = Category::where('parent_id', $this->category_id)->pluck('id')->toArray();
            $categoryIds = array_merge($categoryIds, $subcategories);
            
            $query->whereIn('category_id', $categoryIds);
        }
        
        return abs($query->sum('amount'));
    }

    public function getRemainingAmountAttribute()
    {
        return $this->amount - $this->spent_amount;
    }

    public function getUsagePercentageAttribute()
    {
        if ($this->amount <= 0) return 0;
        return round(($this->spent_amount / $this->amount) * 100, 1);
    }

    public function getIsExceededAttribute()
    {
        return $this->spent_amount > $this->amount;
    }

    public function getPeriodLabelAttribute()
    {
        if ($this->period_type === 'yearly') {
            return $this->year;
        }
        
        $months = [
            1 => 'Enero', 2 => 'Febrero', 3 => 'Marzo', 4 => 'Abril',
            5 => 'Mayo', 6 => 'Junio', 7 => 'Julio', 8 => 'Agosto',
            9 => 'Septiembre', 10 => 'Octubre', 11 => 'Noviembre', 12 => 'Diciembre'
        ];
        
        return ($months[$this->month] ?? '') . ' ' . $this->year;
    }

    // ============================================
    // Methods
    // ============================================

    public static function copyToNextMonth($userId, $fromYear, $fromMonth)
    {
        $nextMonth = $fromMonth === 12 ? 1 : $fromMonth + 1;
        $nextYear = $fromMonth === 12 ? $fromYear + 1 : $fromYear;
        
        $budgets = self::where('user_id', $userId)
            ->where('year', $fromYear)
            ->where('month', $fromMonth)
            ->where('is_active', true)
            ->get();
        
        foreach ($budgets as $budget) {
            self::firstOrCreate([
                'user_id' => $userId,
                'category_id' => $budget->category_id,
                'year' => $nextYear,
                'month' => $nextMonth,
            ], [
                'name' => $budget->name,
                'amount' => $budget->amount,
                'currency' => $budget->currency,
                'period_type' => 'monthly',
                'is_active' => true,
            ]);
        }
    }

    // ============================================
    // Scopes
    // ============================================

    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeForPeriod($query, $year, $month = null)
    {
        $query->where('year', $year);
        if ($month) {
            $query->where('month', $month);
        }
        return $query;
    }

    public function scopeForUser($query, $userId)
    {
        return $query->where('user_id', $userId);
    }
}
