<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Food;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class FoodController extends Controller
{
    /**
     * Display a listing of foods.
     */
    public function index(Request $request): Response
    {
        $query = Food::global(); // Only show global foods (not custom)

        // Filter by category
        if ($request->filled('category')) {
            $query->where('category', $request->category);
        }

        // Filter by meal type
        if ($request->filled('meal_type')) {
            $query->where('meal_type', $request->meal_type);
        }

        // Filter by active status
        if ($request->filled('is_active')) {
            $query->where('is_active', $request->is_active === 'true');
        }

        // Search
        if ($request->filled('search')) {
            $query->where('name', 'like', "%{$request->search}%");
        }

        $foods = $query->latest()->paginate(20)->withQueryString();

        // Get unique categories for filter
        $categories = Food::global()
            ->whereNotNull('category')
            ->distinct()
            ->pluck('category');

        return Inertia::render('Admin/Foods/Index', [
            'foods' => $foods,
            'categories' => $categories,
            'mealTypes' => Food::MEAL_TYPES,
            'filters' => $request->only(['category', 'meal_type', 'is_active', 'search']),
        ]);
    }

    /**
     * Show the form for creating a new food.
     */
    public function create(): Response
    {
        $categories = Food::global()
            ->whereNotNull('category')
            ->distinct()
            ->pluck('category');

        return Inertia::render('Admin/Foods/Create', [
            'categories' => $categories,
            'mealTypes' => Food::MEAL_TYPES,
        ]);
    }

    /**
     * Store a newly created food.
     */
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'category' => 'nullable|string|max:100',
            'meal_type' => 'nullable|string|in:' . implode(',', array_keys(Food::MEAL_TYPES)),
            'serving_size' => 'nullable|string|max:100',
            'serving_weight' => 'nullable|numeric|min:0',
            'proteins' => 'required|numeric|min:0|max:100',
            'carbs' => 'required|numeric|min:0|max:100',
            'fats' => 'required|numeric|min:0|max:100',
            'fiber' => 'nullable|numeric|min:0|max:100',
            'is_active' => 'nullable|boolean',
        ]);

        // Calculate calories: 4 cal/g protein, 4 cal/g carbs, 9 cal/g fat
        $validated['calories'] = ($validated['proteins'] * 4) + 
                                  ($validated['carbs'] * 4) + 
                                  ($validated['fats'] * 9);
        
        $validated['is_custom'] = false; // Global food
        $validated['user_id'] = null;
        $validated['is_active'] = $validated['is_active'] ?? true;

        Food::create($validated);

        return redirect()->route('admin.foods.index')
            ->with('success', 'Alimento creado correctamente.');
    }

    /**
     * Show the form for editing the specified food.
     */
    public function edit(Food $food): Response
    {
        $categories = Food::global()
            ->whereNotNull('category')
            ->distinct()
            ->pluck('category');

        return Inertia::render('Admin/Foods/Edit', [
            'food' => $food,
            'categories' => $categories,
            'mealTypes' => Food::MEAL_TYPES,
        ]);
    }

    /**
     * Display the specified food.
     */
    public function show(Food $food): Response
    {
        return Inertia::render('Admin/Foods/Show', [
            'food' => $food,
        ]);
    }

    /**
     * Update the specified food.
     */
    public function update(Request $request, Food $food): RedirectResponse
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'category' => 'nullable|string|max:100',
            'meal_type' => 'nullable|string|in:' . implode(',', array_keys(Food::MEAL_TYPES)),
            'serving_size' => 'nullable|string|max:100',
            'serving_weight' => 'nullable|numeric|min:0',
            'proteins' => 'required|numeric|min:0|max:100',
            'carbs' => 'required|numeric|min:0|max:100',
            'fats' => 'required|numeric|min:0|max:100',
            'fiber' => 'nullable|numeric|min:0|max:100',
            'is_active' => 'nullable|boolean',
        ]);

        // Recalculate calories
        $validated['calories'] = ($validated['proteins'] * 4) + 
                                  ($validated['carbs'] * 4) + 
                                  ($validated['fats'] * 9);

        $food->update($validated);

        return redirect()->route('admin.foods.index')
            ->with('success', 'Alimento actualizado correctamente.');
    }

    /**
     * Remove the specified food.
     */
    public function destroy(Food $food): RedirectResponse
    {
        if ($food->is_custom) {
            return back()->with('error', 'No se puede eliminar un alimento personalizado desde el panel de administración.');
        }

        $food->delete();

        return redirect()->route('admin.foods.index')
            ->with('success', 'Alimento eliminado correctamente.');
    }

    /**
     * Export foods to various formats.
     */
    public function export(Request $request)
    {
        $format = $request->get('format', 'csv');
        $foods = Food::global()->where('is_active', true)->orderBy('name')->get();

        switch ($format) {
            case 'csv':
                return $this->exportCsv($foods);
            case 'txt':
                return $this->exportTxt($foods);
            case 'json':
                return $this->exportJson($foods);
            case 'excel':
                return $this->exportExcel($foods);
            default:
                return $this->exportCsv($foods);
        }
    }

    private function exportCsv($foods)
    {
        $filename = 'alimentos_' . date('Y-m-d') . '.csv';
        $headers = [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ];

        $callback = function() use ($foods) {
            $file = fopen('php://output', 'w');
            // UTF-8 BOM for Excel compatibility
            fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
            
            // Header row
            fputcsv($file, ['Nombre', 'Categoría', 'Proteínas (g)', 'Carbohidratos (g)', 'Grasas (g)', 'Fibra (g)', 'Calorías', 'Porción', 'Peso Porción (g)']);
            
            foreach ($foods as $food) {
                fputcsv($file, [
                    $food->name,
                    $food->category ?? '',
                    $food->proteins,
                    $food->carbs,
                    $food->fats,
                    $food->fiber ?? 0,
                    $food->calories,
                    $food->serving_size ?? '',
                    $food->serving_weight ?? '',
                ]);
            }
            fclose($file);
        };

        return response()->stream($callback, 200, $headers);
    }

    private function exportTxt($foods)
    {
        $filename = 'alimentos_' . date('Y-m-d') . '.txt';
        $content = "Lista de Alimentos - " . date('d/m/Y') . "\n";
        $content .= str_repeat('=', 50) . "\n\n";

        foreach ($foods as $food) {
            $content .= $food->name . "\n";
        }

        return response($content, 200, [
            'Content-Type' => 'text/plain; charset=UTF-8',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ]);
    }

    private function exportJson($foods)
    {
        $filename = 'alimentos_' . date('Y-m-d') . '.json';
        $data = $foods->map(function($food) {
            return [
                'name' => $food->name,
                'category' => $food->category,
                'proteins' => $food->proteins,
                'carbs' => $food->carbs,
                'fats' => $food->fats,
                'fiber' => $food->fiber,
                'calories' => $food->calories,
                'serving_size' => $food->serving_size,
                'serving_weight' => $food->serving_weight,
            ];
        });

        return response()->json($data, 200, [
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ]);
    }

    private function exportExcel($foods)
    {
        // Simple Excel XML format
        $filename = 'alimentos_' . date('Y-m-d') . '.xls';
        
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">' . "\n";
        $xml .= '<Worksheet ss:Name="Alimentos"><Table>' . "\n";
        
        // Header
        $xml .= '<Row>';
        $headers = ['Nombre', 'Categoría', 'Proteínas (g)', 'Carbohidratos (g)', 'Grasas (g)', 'Fibra (g)', 'Calorías', 'Porción', 'Peso Porción (g)'];
        foreach ($headers as $header) {
            $xml .= '<Cell><Data ss:Type="String">' . htmlspecialchars($header) . '</Data></Cell>';
        }
        $xml .= '</Row>' . "\n";
        
        // Data
        foreach ($foods as $food) {
            $xml .= '<Row>';
            $xml .= '<Cell><Data ss:Type="String">' . htmlspecialchars($food->name) . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="String">' . htmlspecialchars($food->category ?? '') . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . $food->proteins . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . $food->carbs . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . $food->fats . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . ($food->fiber ?? 0) . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . $food->calories . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="String">' . htmlspecialchars($food->serving_size ?? '') . '</Data></Cell>';
            $xml .= '<Cell><Data ss:Type="Number">' . ($food->serving_weight ?? 0) . '</Data></Cell>';
            $xml .= '</Row>' . "\n";
        }
        
        $xml .= '</Table></Worksheet></Workbook>';

        return response($xml, 200, [
            'Content-Type' => 'application/vnd.ms-excel',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ]);
    }

    /**
     * Import foods from file (CSV, TXT, JSON).
     */
    public function import(Request $request): RedirectResponse
    {
        $request->validate([
            'file' => 'required|file|mimes:csv,txt,json|max:10240',
        ]);

        $file = $request->file('file');
        $extension = strtolower($file->getClientOriginalExtension());
        $content = file_get_contents($file->getPathname());

        $imported = 0;
        $skipped = 0;
        $errors = [];

        try {
            switch ($extension) {
                case 'csv':
                    $result = $this->importCsv($content);
                    break;
                case 'txt':
                    $result = $this->importTxt($content);
                    break;
                case 'json':
                    $result = $this->importJson($content);
                    break;
                default:
                    return back()->with('error', 'Formato de archivo no soportado.');
            }

            $imported = $result['imported'];
            $skipped = $result['skipped'];
            
        } catch (\Exception $e) {
            return back()->with('error', 'Error al importar: ' . $e->getMessage());
        }

        return back()->with('success', "{$imported} alimentos importados, {$skipped} omitidos (duplicados).");
    }

    private function importCsv(string $content): array
    {
        $imported = 0;
        $skipped = 0;
        
        // Remove BOM if present
        $content = preg_replace('/^\xEF\xBB\xBF/', '', $content);
        $lines = array_filter(explode("\n", str_replace("\r\n", "\n", $content)));
        
        // Skip header if it looks like one
        $firstLine = str_getcsv($lines[0] ?? '');
        if (isset($firstLine[0]) && in_array(strtolower($firstLine[0]), ['nombre', 'name', 'alimento'])) {
            array_shift($lines);
        }

        foreach ($lines as $line) {
            $row = str_getcsv($line);
            if (empty($row[0])) continue;

            $name = trim($row[0]);
            
            // Check if exists
            if (Food::whereRaw('LOWER(name) = ?', [strtolower($name)])->exists()) {
                $skipped++;
                continue;
            }

            Food::create([
                'name' => $name,
                'category' => isset($row[1]) && !empty($row[1]) ? trim($row[1]) : null,
                'proteins' => isset($row[2]) ? (float) $row[2] : 0,
                'carbs' => isset($row[3]) ? (float) $row[3] : 0,
                'fats' => isset($row[4]) ? (float) $row[4] : 0,
                'fiber' => isset($row[5]) ? (float) $row[5] : 0,
                'calories' => isset($row[6]) ? (float) $row[6] : (isset($row[2]) ? ((float) $row[2] * 4) + ((float) ($row[3] ?? 0) * 4) + ((float) ($row[4] ?? 0) * 9) : 0),
                'serving_size' => isset($row[7]) && !empty($row[7]) ? trim($row[7]) : '100g',
                'serving_weight' => isset($row[8]) ? (float) $row[8] : 100,
                'is_custom' => false,
                'is_active' => true,
            ]);
            $imported++;
        }

        return ['imported' => $imported, 'skipped' => $skipped];
    }

    private function importTxt(string $content): array
    {
        $imported = 0;
        $skipped = 0;
        
        $lines = array_filter(array_map('trim', explode("\n", str_replace("\r\n", "\n", $content))));

        foreach ($lines as $line) {
            // Skip headers, separators
            if (empty($line) || str_starts_with($line, '=') || str_starts_with($line, '#') || str_starts_with($line, 'Lista')) {
                continue;
            }

            $name = trim($line);
            
            if (Food::whereRaw('LOWER(name) = ?', [strtolower($name)])->exists()) {
                $skipped++;
                continue;
            }

            Food::create([
                'name' => $name,
                'proteins' => 0,
                'carbs' => 0,
                'fats' => 0,
                'calories' => 0,
                'is_custom' => false,
                'is_active' => true,
            ]);
            $imported++;
        }

        return ['imported' => $imported, 'skipped' => $skipped];
    }

    private function importJson(string $content): array
    {
        $imported = 0;
        $skipped = 0;
        
        $data = json_decode($content, true);
        if (!is_array($data)) {
            throw new \Exception('Formato JSON inválido');
        }

        foreach ($data as $item) {
            $name = trim($item['name'] ?? $item['nombre'] ?? '');
            if (empty($name)) continue;

            if (Food::whereRaw('LOWER(name) = ?', [strtolower($name)])->exists()) {
                $skipped++;
                continue;
            }

            Food::create([
                'name' => $name,
                'category' => $item['category'] ?? $item['categoria'] ?? null,
                'proteins' => (float) ($item['proteins'] ?? $item['proteinas'] ?? 0),
                'carbs' => (float) ($item['carbs'] ?? $item['carbohidratos'] ?? 0),
                'fats' => (float) ($item['fats'] ?? $item['grasas'] ?? 0),
                'fiber' => (float) ($item['fiber'] ?? $item['fibra'] ?? 0),
                'calories' => (float) ($item['calories'] ?? $item['calorias'] ?? 0),
                'serving_size' => $item['serving_size'] ?? $item['porcion'] ?? '100g',
                'serving_weight' => (float) ($item['serving_weight'] ?? $item['peso_porcion'] ?? 100),
                'is_custom' => false,
                'is_active' => true,
            ]);
            $imported++;
        }

        return ['imported' => $imported, 'skipped' => $skipped];
    }

    /**
     * Get foods by meal type (API endpoint for AJAX calls).
     */
    public function getByMealType(Request $request)
    {
        $query = Food::where('is_active', true);

        // Filter by meal type if provided
        if ($request->filled('meal_type')) {
            $query->where('meal_type', $request->meal_type);
        }

        // Filter by category if provided
        if ($request->filled('category')) {
            $query->where('category', $request->category);
        }

        // Search by name if provided
        if ($request->filled('search')) {
            $query->where('name', 'like', "%{$request->search}%");
        }

        return $query->orderBy('name')
            ->select('id', 'name', 'category', 'meal_type', 'serving_size', 'serving_weight', 'calories', 'proteins', 'carbs', 'fats', 'fiber')
            ->get();
    }
}
