<?php

namespace App\Models;

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

class MealPlan extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'client_id',
        'name',
        'description',
        'notes',
        'goal_type',
        'goal_percentage',
        'target_calories',
        'target_proteins',
        'target_carbs',
        'target_fats',
        'is_active',
        'is_official',
    ];

    protected $casts = [
        'target_calories' => 'decimal:2',
        'target_proteins' => 'decimal:2',
        'target_carbs' => 'decimal:2',
        'target_fats' => 'decimal:2',
        'is_active' => 'boolean',
        'is_official' => 'boolean',
    ];

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

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

    /**
     * Get the diet plans for this meal plan.
     */
    public function dietPlans(): HasMany
    {
        return $this->hasMany(DietPlan::class)->orderBy('order');
    }

    /**
     * Get all meal items through diet plans.
     */
    public function mealItems(): HasManyThrough
    {
        return $this->hasManyThrough(MealItem::class, DietPlan::class);
    }

    /**
     * Alias for mealItems (backwards compatibility)
     */
    public function items(): HasManyThrough
    {
        return $this->mealItems();
    }

    /**
     * NOTA: Se eliminaron los appends automáticos para evitar N+1 queries
     * Los totales deben calcularse explícitamente cuando sean necesarios
     * usando el método calculateTotals()
     */
    // protected $appends = ['meals', 'total_calories', 'total_protein', 'total_carbs', 'total_fat'];

    /**
     * Accessor for meals (all meal items across all diet plans)
     * SOLO se ejecuta cuando se accede explícitamente
     */
    public function getMealsAttribute()
    {
        // Usar relación ya cargada si existe
        if ($this->relationLoaded('mealItems')) {
            return $this->getRelation('mealItems');
        }
        return $this->mealItems;
    }

    /**
     * Total calories - SOLO cuando se necesite explícitamente
     */
    public function getTotalCaloriesAttribute()
    {
        if ($this->relationLoaded('dietPlans')) {
            return $this->dietPlans->sum(function ($dp) {
                return $dp->relationLoaded('mealItems')
                    ? $dp->mealItems->sum('calories')
                    : $dp->total_calories;
            });
        }
        return $this->dietPlans->sum('total_calories');
    }

    /**
     * Total protein - SOLO cuando se necesite explícitamente
     */
    public function getTotalProteinAttribute()
    {
        if ($this->relationLoaded('dietPlans')) {
            return $this->dietPlans->sum(function ($dp) {
                return $dp->relationLoaded('mealItems')
                    ? $dp->mealItems->sum('proteins')
                    : $dp->total_protein;
            });
        }
        return $this->dietPlans->sum('total_protein');
    }

    /**
     * Total carbs - SOLO cuando se necesite explícitamente
     */
    public function getTotalCarbsAttribute()
    {
        if ($this->relationLoaded('dietPlans')) {
            return $this->dietPlans->sum(function ($dp) {
                return $dp->relationLoaded('mealItems')
                    ? $dp->mealItems->sum('carbs')
                    : $dp->total_carbs;
            });
        }
        return $this->dietPlans->sum('total_carbs');
    }

    /**
     * Total fat - SOLO cuando se necesite explícitamente
     */
    public function getTotalFatAttribute()
    {
        if ($this->relationLoaded('dietPlans')) {
            return $this->dietPlans->sum(function ($dp) {
                return $dp->relationLoaded('mealItems')
                    ? $dp->mealItems->sum('fats')
                    : $dp->total_fat;
            });
        }
        return $this->dietPlans->sum('total_fat');
    }

    /**
     * Calculate total macros from all diet plans.
     */
    public function calculateTotals(): array
    {
        $totals = [
            'proteins' => 0,
            'carbs' => 0,
            'fats' => 0,
            'calories' => 0,
        ];

        foreach ($this->dietPlans as $dietPlan) {
            $planTotals = $dietPlan->calculateTotals();
            $totals['proteins'] += $planTotals['proteins'];
            $totals['carbs'] += $planTotals['carbs'];
            $totals['fats'] += $planTotals['fats'];
            $totals['calories'] += $planTotals['calories'];
        }

        return $totals;
    }
}
