<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Transaction;
use App\Models\Account;
use App\Models\LiabilityAccount;
use App\Models\Budget;
use App\Models\FinancialGoal;
use App\Models\RecurringTemplate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;

class FinancialHealthController extends Controller
{
    /**
     * Obtener puntuación de salud financiera completa
     */
    public function index(Request $request)
    {
        $userId = Auth::id();
        
        // Calcular cada métrica
        $savingsCapacity = $this->calculateSavingsCapacity($userId);
        $debtControl = $this->calculateDebtControl($userId);
        $budgetManagement = $this->calculateBudgetManagement($userId);
        $investments = $this->calculateInvestments($userId);
        $emergencyFund = $this->calculateEmergencyFund($userId);
        $futurePlanning = $this->calculateFuturePlanning($userId);
        
        // Puntuación general ponderada
        $weights = [
            'savings' => 0.25,
            'debt' => 0.20,
            'budget' => 0.15,
            'investments' => 0.15,
            'emergency' => 0.15,
            'planning' => 0.10,
        ];
        
        $overallScore = round(
            ($savingsCapacity['score'] * $weights['savings']) +
            ($debtControl['score'] * $weights['debt']) +
            ($budgetManagement['score'] * $weights['budget']) +
            ($investments['score'] * $weights['investments']) +
            ($emergencyFund['score'] * $weights['emergency']) +
            ($futurePlanning['score'] * $weights['planning'])
        );
        
        // Determinar nivel de salud
        $healthLevel = $this->getHealthLevel($overallScore);
        
        // Generar insights y recomendaciones
        $insights = $this->generateInsights($userId, [
            'savings' => $savingsCapacity,
            'debt' => $debtControl,
            'budget' => $budgetManagement,
            'investments' => $investments,
            'emergency' => $emergencyFund,
            'planning' => $futurePlanning,
        ]);
        
        return response()->json([
            'overall_score' => $overallScore,
            'health_level' => $healthLevel,
            'last_updated' => now()->format('Y-m-d'),
            'metrics' => [
                'savings_capacity' => $savingsCapacity,
                'debt_control' => $debtControl,
                'budget_management' => $budgetManagement,
                'investments' => $investments,
                'emergency_fund' => $emergencyFund,
                'future_planning' => $futurePlanning,
            ],
            'insights' => $insights,
        ]);
    }

    /**
     * Calcular capacidad de ahorro
     */
    private function calculateSavingsCapacity($userId)
    {
        // Últimos 3 meses
        $data = Transaction::where('user_id', $userId)
            ->where('effective_date', '>=', now()->subMonths(3)->startOfMonth())
            ->selectRaw("
                SUM(CASE WHEN type = 'credit' THEN amount ELSE 0 END) as income,
                SUM(CASE WHEN type = 'debit' THEN ABS(amount) ELSE 0 END) as expense
            ")
            ->first();
        
        $income = $data->income ?? 0;
        $expense = $data->expense ?? 0;
        $savings = $income - $expense;
        $savingsRate = $income > 0 ? ($savings / $income) * 100 : 0;
        
        // Puntuación basada en tasa de ahorro
        // 0-10% = 40, 10-20% = 60, 20-30% = 80, 30%+ = 100
        $score = match(true) {
            $savingsRate >= 30 => 100,
            $savingsRate >= 20 => 80 + (($savingsRate - 20) * 2),
            $savingsRate >= 10 => 60 + (($savingsRate - 10) * 2),
            $savingsRate >= 0 => 40 + ($savingsRate * 2),
            default => max(0, 40 + $savingsRate),
        };
        
        return [
            'score' => round(min(100, max(0, $score))),
            'savings_rate' => round($savingsRate, 1),
            'monthly_savings' => round($savings / 3, 2),
            'status' => $savingsRate >= 20 ? 'excellent' : ($savingsRate >= 10 ? 'good' : 'needs_improvement'),
            'message' => $savingsRate >= 20 
                ? "¡Excelente! Ahorras el {$savingsRate}% de tus ingresos"
                : ($savingsRate >= 10 
                    ? "Buen trabajo. Ahorras el {$savingsRate}%"
                    : "Intenta aumentar tu tasa de ahorro"),
        ];
    }

    /**
     * Calcular control de deudas
     */
    private function calculateDebtControl($userId)
    {
        // Obtener deudas activas
        $liabilities = LiabilityAccount::where('user_id', $userId)
            ->where('status', 'active')
            ->get();
        
        $totalDebt = $liabilities->sum('current_balance');
        $totalCreditLimit = $liabilities->sum('credit_limit');
        $monthlyPayments = $liabilities->sum('monthly_payment');
        
        // Ingresos mensuales promedio
        $monthlyIncome = Transaction::where('user_id', $userId)
            ->where('type', 'credit')
            ->where('effective_date', '>=', now()->subMonths(3)->startOfMonth())
            ->sum('amount') / 3;
        
        // Ratio deuda/ingresos
        $debtToIncomeRatio = $monthlyIncome > 0 ? ($monthlyPayments / $monthlyIncome) * 100 : 0;
        
        // Utilización de crédito
        $creditUtilization = $totalCreditLimit > 0 ? ($totalDebt / $totalCreditLimit) * 100 : 0;
        
        // Puntuación
        // DTI < 20% = excelente, 20-35% = bueno, 35-50% = moderado, >50% = alto riesgo
        $score = match(true) {
            $debtToIncomeRatio <= 20 => 100 - ($debtToIncomeRatio * 0.5),
            $debtToIncomeRatio <= 35 => 80 - (($debtToIncomeRatio - 20) * 1.3),
            $debtToIncomeRatio <= 50 => 60 - (($debtToIncomeRatio - 35) * 2),
            default => max(0, 30 - (($debtToIncomeRatio - 50) * 0.6)),
        };
        
        return [
            'score' => round(min(100, max(0, $score))),
            'total_debt' => round($totalDebt, 2),
            'monthly_payments' => round($monthlyPayments, 2),
            'debt_to_income_ratio' => round($debtToIncomeRatio, 1),
            'credit_utilization' => round($creditUtilization, 1),
            'active_debts' => $liabilities->count(),
            'status' => $debtToIncomeRatio <= 20 ? 'excellent' : ($debtToIncomeRatio <= 35 ? 'acceptable' : 'needs_attention'),
            'message' => $totalDebt == 0 
                ? "¡Sin deudas! Excelente situación"
                : ($debtToIncomeRatio <= 35 
                    ? "Nivel aceptable. Crédito disponible: " . number_format($totalCreditLimit - $totalDebt, 2) . "€"
                    : "Considera reducir tus deudas"),
        ];
    }

    /**
     * Calcular gestión de presupuesto
     */
    private function calculateBudgetManagement($userId)
    {
        $currentMonth = now()->month;
        $currentYear = now()->year;
        
        $budgets = Budget::where('user_id', $userId)
            ->where('year', $currentYear)
            ->where('month', $currentMonth)
            ->where('is_active', true)
            ->get();
        
        if ($budgets->isEmpty()) {
            return [
                'score' => 50,
                'has_budgets' => false,
                'status' => 'not_configured',
                'message' => 'No tienes presupuestos configurados',
                'exceeded_count' => 0,
                'total_budgets' => 0,
            ];
        }
        
        $exceededCount = $budgets->filter(fn($b) => $b->is_exceeded)->count();
        $totalBudgets = $budgets->count();
        $complianceRate = (($totalBudgets - $exceededCount) / $totalBudgets) * 100;
        
        // También verificar el uso promedio
        $avgUsage = $budgets->avg('usage_percentage');
        
        // Puntuación
        $score = match(true) {
            $exceededCount == 0 && $avgUsage <= 90 => 100,
            $exceededCount == 0 => 85,
            $exceededCount <= 1 => 70,
            $exceededCount <= 2 => 55,
            default => max(20, 55 - ($exceededCount * 10)),
        };
        
        // Encontrar categoría más excedida
        $mostExceeded = $budgets->filter(fn($b) => $b->is_exceeded)
            ->sortByDesc('usage_percentage')
            ->first();
        
        return [
            'score' => round($score),
            'has_budgets' => true,
            'total_budgets' => $totalBudgets,
            'exceeded_count' => $exceededCount,
            'compliance_rate' => round($complianceRate, 1),
            'avg_usage' => round($avgUsage, 1),
            'most_exceeded' => $mostExceeded ? [
                'category' => $mostExceeded->category?->name ?? $mostExceeded->name,
                'usage' => $mostExceeded->usage_percentage,
            ] : null,
            'status' => $exceededCount == 0 ? 'on_track' : ($exceededCount <= 2 ? 'needs_attention' : 'exceeded'),
            'message' => $exceededCount == 0 
                ? "Todos los presupuestos bajo control"
                : "¡Atención! Excediste presupuesto en " . ($mostExceeded->category?->name ?? 'una categoría'),
        ];
    }

    /**
     * Calcular inversiones
     */
    private function calculateInvestments($userId)
    {
        // Cuentas de tipo inversión
        $investmentAccounts = Account::where('user_id', $userId)
            ->where('type', 'investment')
            ->get();
        
        $totalInvestments = $investmentAccounts->sum('current_balance');
        
        // Total de activos
        $totalAssets = Account::where('user_id', $userId)
            ->where('include_in_total', true)
            ->sum('current_balance');
        
        $investmentRatio = $totalAssets > 0 ? ($totalInvestments / $totalAssets) * 100 : 0;
        
        // Puntuación basada en ratio de inversión
        $score = match(true) {
            $investmentRatio >= 30 => 100,
            $investmentRatio >= 20 => 80 + (($investmentRatio - 20) * 2),
            $investmentRatio >= 10 => 60 + (($investmentRatio - 10) * 2),
            $investmentRatio >= 5 => 40 + (($investmentRatio - 5) * 4),
            default => max(20, $investmentRatio * 8),
        };
        
        return [
            'score' => round(min(100, $score)),
            'total_investments' => round($totalInvestments, 2),
            'investment_ratio' => round($investmentRatio, 1),
            'accounts_count' => $investmentAccounts->count(),
            'status' => $investmentRatio >= 20 ? 'good' : ($investmentRatio >= 10 ? 'moderate' : 'low'),
            'message' => $investmentRatio >= 20 
                ? "Buena diversificación. Sigue así"
                : "Considera aumentar tu inversión",
        ];
    }

    /**
     * Calcular fondo de emergencia
     */
    private function calculateEmergencyFund($userId)
    {
        // Cuentas líquidas (checking, savings, cash)
        $liquidAccounts = Account::where('user_id', $userId)
            ->whereIn('type', ['checking', 'savings', 'cash'])
            ->where('include_in_total', true)
            ->sum('current_balance');
        
        // Gastos mensuales promedio
        $monthlyExpenses = Transaction::where('user_id', $userId)
            ->where('type', 'debit')
            ->where('effective_date', '>=', now()->subMonths(3)->startOfMonth())
            ->sum(fn($t) => abs($t->amount)) / 3;
        
        // Usar consulta directa para mejor rendimiento
        $monthlyExpenses = abs(Transaction::where('user_id', $userId)
            ->where('type', 'debit')
            ->where('effective_date', '>=', now()->subMonths(3)->startOfMonth())
            ->sum('amount')) / 3;
        
        // Meses cubiertos
        $monthsCovered = $monthlyExpenses > 0 ? $liquidAccounts / $monthlyExpenses : 0;
        
        // Puntuación (ideal: 6 meses)
        $score = match(true) {
            $monthsCovered >= 6 => 100,
            $monthsCovered >= 3 => 60 + (($monthsCovered - 3) * 13.33),
            $monthsCovered >= 1 => 30 + (($monthsCovered - 1) * 15),
            default => max(0, $monthsCovered * 30),
        };
        
        return [
            'score' => round(min(100, $score)),
            'liquid_assets' => round($liquidAccounts, 2),
            'monthly_expenses' => round($monthlyExpenses, 2),
            'months_covered' => round($monthsCovered, 1),
            'recommended_fund' => round($monthlyExpenses * 6, 2),
            'status' => $monthsCovered >= 6 ? 'excellent' : ($monthsCovered >= 3 ? 'moderate' : 'insufficient'),
            'message' => $monthsCovered >= 6 
                ? "Excelente fondo de emergencia"
                : "Tienes " . number_format($liquidAccounts, 2) . "€ (" . round($monthsCovered, 1) . " meses de gastos)",
        ];
    }

    /**
     * Calcular planificación futura
     */
    private function calculateFuturePlanning($userId)
    {
        // Metas financieras activas
        $goals = FinancialGoal::where('user_id', $userId)
            ->where('status', 'active')
            ->get();
        
        // Transacciones recurrentes configuradas
        $recurringCount = RecurringTemplate::where('user_id', $userId)
            ->where('is_active', true)
            ->count();
        
        // Presupuestos configurados
        $hasBudgets = Budget::where('user_id', $userId)
            ->where('is_active', true)
            ->exists();
        
        $activeGoals = $goals->count();
        $goalsOnTrack = $goals->filter(fn($g) => $g->is_on_track)->count();
        $avgProgress = $goals->avg('progress_percentage') ?? 0;
        
        // Puntuación
        $baseScore = 40;
        if ($activeGoals > 0) $baseScore += 20;
        if ($activeGoals >= 3) $baseScore += 10;
        if ($goalsOnTrack > 0) $baseScore += 15;
        if ($hasBudgets) $baseScore += 10;
        if ($recurringCount >= 3) $baseScore += 5;
        
        // Bonus por progreso
        $baseScore += min(10, $avgProgress / 10);
        
        return [
            'score' => round(min(100, $baseScore)),
            'active_goals' => $activeGoals,
            'goals_on_track' => $goalsOnTrack,
            'avg_progress' => round($avgProgress, 1),
            'has_budgets' => $hasBudgets,
            'recurring_configured' => $recurringCount,
            'status' => $activeGoals >= 3 ? 'excellent' : ($activeGoals >= 1 ? 'good' : 'needs_setup'),
            'message' => $activeGoals > 0 
                ? "¡Muy bien! Tienes $activeGoals metas activas en progreso"
                : "Crea metas financieras para mejorar tu planificación",
        ];
    }

    /**
     * Determinar nivel de salud
     */
    private function getHealthLevel($score)
    {
        return match(true) {
            $score >= 85 => ['level' => 'excellent', 'label' => 'Excelente Salud', 'color' => '#22c55e'],
            $score >= 70 => ['level' => 'good', 'label' => 'Buena Salud', 'color' => '#84cc16'],
            $score >= 55 => ['level' => 'moderate', 'label' => 'Salud Moderada', 'color' => '#f59e0b'],
            $score >= 40 => ['level' => 'needs_work', 'label' => 'Necesita Mejorar', 'color' => '#f97316'],
            default => ['level' => 'critical', 'label' => 'Atención Necesaria', 'color' => '#ef4444'],
        };
    }

    /**
     * Generar insights y recomendaciones
     */
    private function generateInsights($userId, $metrics)
    {
        $insights = [];
        
        // Prioridad Alta - Problemas críticos
        if ($metrics['debt']['score'] < 50) {
            $insights[] = [
                'type' => 'high_priority',
                'icon' => 'bi-exclamation-triangle-fill',
                'color' => '#ef4444',
                'title' => 'Prioridad Alta',
                'message' => "Reduce gastos en " . ($metrics['budget']['most_exceeded']['category'] ?? 'categorías con exceso') . ". Estás excediendo el presupuesto en " . ($metrics['budget']['most_exceeded']['usage'] ?? 0) . "%.",
            ];
        }
        
        // Prioridad Media - Mejoras recomendadas
        if ($metrics['emergency']['months_covered'] < 6) {
            $needed = $metrics['emergency']['recommended_fund'] - $metrics['emergency']['liquid_assets'];
            $insights[] = [
                'type' => 'medium_priority',
                'icon' => 'bi-shield-exclamation',
                'color' => '#f59e0b',
                'title' => 'Prioridad Media',
                'message' => "Incrementa tu fondo de emergencia a 6 meses de gastos (" . number_format($metrics['emergency']['recommended_fund'], 0) . "€).",
            ];
        }
        
        // Logros
        if ($metrics['savings']['savings_rate'] >= 20) {
            $insights[] = [
                'type' => 'achievement',
                'icon' => 'bi-trophy-fill',
                'color' => '#22c55e',
                'title' => 'Logro Destacado',
                'message' => "¡Excelente ahorro mensual! Mantienes una tasa del " . $metrics['savings']['savings_rate'] . "% por encima de la meta.",
            ];
        }
        
        // Oportunidades
        if ($metrics['investments']['investment_ratio'] < 20 && $metrics['savings']['savings_rate'] > 15) {
            $insights[] = [
                'type' => 'opportunity',
                'icon' => 'bi-lightbulb-fill',
                'color' => '#3b82f6',
                'title' => 'Oportunidad',
                'message' => "Considera aumentar tu inversión con el excedente de tus ahorros.",
            ];
        }
        
        // Metas próximas
        $upcomingGoals = FinancialGoal::where('user_id', $userId)
            ->where('status', 'active')
            ->whereNotNull('target_date')
            ->where('target_date', '<=', now()->addMonths(6))
            ->orderBy('target_date')
            ->first();
        
        if ($upcomingGoals) {
            $insights[] = [
                'type' => 'upcoming_goal',
                'icon' => 'bi-calendar-check-fill',
                'color' => '#8b5cf6',
                'title' => 'Meta Próxima',
                'message' => "Faltan " . now()->diffInMonths($upcomingGoals->target_date) . " meses para tu meta de " . $upcomingGoals->name . ". ¡Sigue así!",
            ];
        }
        
        // Sugerencia general
        if ($metrics['planning']['active_goals'] < 3) {
            $insights[] = [
                'type' => 'suggestion',
                'icon' => 'bi-gear-fill',
                'color' => '#06b6d4',
                'title' => 'Sugerencia',
                'message' => "Activa ahorro automático del 10% cada vez que recibes tu nómina.",
            ];
        }
        
        return $insights;
    }

    /**
     * Historial de puntuación
     */
    public function history(Request $request)
    {
        // Por ahora retornamos datos simulados
        // En producción, guardaríamos snapshots diarios/semanales
        $months = $request->get('months', 6);
        
        $history = [];
        $baseScore = 72;
        
        for ($i = $months - 1; $i >= 0; $i--) {
            $date = now()->subMonths($i);
            $variation = rand(-5, 8);
            $baseScore = max(30, min(95, $baseScore + $variation));
            
            $history[] = [
                'month' => $date->format('Y-m'),
                'month_label' => $date->format('M Y'),
                'score' => $baseScore,
            ];
        }
        
        return response()->json($history);
    }
}
