<?php
/**
 * API RESTful para Sistema de Desayunos Boutique
 * Hotel Casablanca Spa & Wine
 * 
 * @author Sistema de Desayunos
 * @version 2.0
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

// Manejar preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

class API {
    private $db;
    private $config;
    
    /**
     * Constructor - Inicializa la conexión a la base de datos
     */
    public function __construct() {
        $this->config = [
            'host' => 'localhost',
            'dbname' => 'cma112915_desayuno',  // Nombre de tu base de datos
            'username' => 'cma112915_hotel',          // Tu usuario
            'password' => 'HotelCasablancaChile',                    // ← COLOCA AQUÍ TU CONTRASEÑA
            'charset' => 'utf8mb4'
        ];
        
        $this->conectarDB();
    }
    
    /**
     * Establece la conexión con la base de datos
     */
    private function conectarDB() {
        try {
            $dsn = "mysql:host={$this->config['host']};dbname={$this->config['dbname']};charset={$this->config['charset']}";
            $this->db = new PDO($dsn, $this->config['username'], $this->config['password']);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            
            // Establecer zona horaria
            $this->db->exec("SET time_zone = 'America/Santiago'");
            
        } catch (PDOException $e) {
            $this->responderError("Error de conexión a la base de datos: " . $e->getMessage(), 500);
        }
    }
    
    /**
     * Responde con un mensaje de error
     */
    private function responderError($mensaje, $codigo = 400) {
        http_response_code($codigo);
        echo json_encode(['success' => false, 'error' => $mensaje]);
        exit();
    }
    
    /**
     * Verifica la conexión a la base de datos
     */
    public function verificarConexion() {
        try {
            $this->db->query("SELECT 1")->fetch();
            return ['success' => true, 'message' => 'Conexión exitosa'];
        } catch (PDOException $e) {
            return ['success' => false, 'error' => 'Error de conexión'];
        }
    }
    
    // ============================================
    // FUNCIONES PARA PEDIDOS DE DESAYUNO
    // ============================================
    
    /**
     * Obtiene la disponibilidad por horario para una fecha específica
     */
    public function getDisponibilidad($params) {
        try {
            $fecha = $params['fecha'] ?? date('Y-m-d');
            
            // Definir horarios
            $horarios = [
                "8:00 – 8:30",
                "8:30 – 9:00", 
                "9:00 – 9:30",
                "9:30 – 10:00",
                "10:00 – 10:30"
            ];
            
            $capacidad_maxima = 15;
            $disponibilidad = [];
            
            foreach ($horarios as $horario) {
                // Obtener reservados para este horario
                $stmt = $this->db->prepare("
                    SELECT COALESCE(SUM(total_pasajeros), 0) as total
                    FROM pedidos 
                    WHERE DATE(fecha_pedido) = ? AND horario = ?
                ");
                $stmt->execute([$fecha, $horario]);
                $reservados = (int)$stmt->fetch()['total'];
                
                $disponibilidad[$horario] = [
                    'max' => $capacidad_maxima,
                    'reservados' => $reservados,
                    'disponibles' => max(0, $capacidad_maxima - $reservados)
                ];
            }
            
            return $disponibilidad;
            
        } catch (PDOException $e) {
            error_log("Error en getDisponibilidad: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al obtener disponibilidad'];
        }
    }
    
    /**
     * Obtiene los pedidos para una fecha específica
     */
    public function getPedidos($params) {
        try {
            $fecha = $params['fecha'] ?? date('Y-m-d');
            
            $stmt = $this->db->prepare("
                SELECT 
                    p.*,
                    DATE_FORMAT(p.fecha_pedido, '%H:%i') as hora_pedido
                FROM pedidos p
                WHERE DATE(p.fecha_pedido) = ?
                ORDER BY p.horario, p.habitacion
            ");
            
            $stmt->execute([$fecha]);
            $pedidos = $stmt->fetchAll();
            
            // Decodificar JSON
            foreach ($pedidos as &$pedido) {
                $pedido['desayunos'] = json_decode($pedido['desayunos'], true) ?: [];
                $pedido['variaciones'] = json_decode($pedido['variaciones'], true) ?: [];
            }
            
            return $pedidos;
            
        } catch (PDOException $e) {
            error_log("Error en getPedidos: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al obtener pedidos'];
        }
    }
    
    /**
     * Registra un nuevo pedido de desayuno
     */
    public function nuevoPedido($data) {
        try {
            // Validar datos requeridos
            if (!isset($data['habitacion']) || !isset($data['horario']) || 
                !isset($data['desayunos']) || !isset($data['totalPasajeros'])) {
                return ['success' => false, 'error' => 'Datos incompletos'];
            }
            
            $habitacion = $data['habitacion'];
            $fecha = date('Y-m-d');
            
            // Verificar que la habitación tiene check-in activo
            $stmt = $this->db->prepare("
                SELECT id FROM checkins 
                WHERE habitacion = ? AND activo = 1 
                AND fecha_checkin <= ? AND fecha_checkout >= ?
            ");
            $stmt->execute([$habitacion, $fecha, $fecha]);
            
            if (!$stmt->fetch()) {
                return [
                    'success' => false, 
                    'error' => 'checkin_requerido',
                    'mensaje' => 'Esta habitación no tiene check-in activo'
                ];
            }
            
            // Verificar si ya existe un pedido para esta habitación hoy
            $stmt = $this->db->prepare("
                SELECT id FROM pedidos 
                WHERE habitacion = ? AND DATE(fecha_pedido) = ?
            ");
            $stmt->execute([$habitacion, $fecha]);
            
            if ($stmt->fetch()) {
                return [
                    'success' => false, 
                    'error' => 'pedido_duplicado',
                    'mensaje' => 'Ya existe un pedido para esta habitación hoy'
                ];
            }
            
            // Verificar disponibilidad del horario
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(total_pasajeros), 0) as total
                FROM pedidos 
                WHERE DATE(fecha_pedido) = ? AND horario = ?
            ");
            $stmt->execute([$fecha, $data['horario']]);
            $reservados = (int)$stmt->fetch()['total'];
            
            if ($reservados + $data['totalPasajeros'] > 15) {
                return [
                    'success' => false,
                    'error' => 'excede_capacidad',
                    'mensaje' => 'No hay suficiente capacidad en este horario'
                ];
            }
            
            // Insertar el pedido
            $stmt = $this->db->prepare("
                INSERT INTO pedidos 
                (habitacion, nombre_pasajero, horario, desayunos, variaciones, 
                 nota, total_pasajeros, estado_cocina, fecha_pedido)
                VALUES (?, ?, ?, ?, ?, ?, ?, 'nuevo', NOW())
            ");
            
            $stmt->execute([
                $habitacion,
                $data['nombre_pasajero'] ?? '',
                $data['horario'],
                json_encode($data['desayunos'], JSON_UNESCAPED_UNICODE),
                json_encode($data['variaciones'] ?? [], JSON_UNESCAPED_UNICODE),
                $data['nota'] ?? '',
                $data['totalPasajeros']
            ]);
            
            $pedido_id = $this->db->lastInsertId();
            
            // Registrar en log
            error_log("✅ Nuevo pedido #$pedido_id - Habitación $habitacion - {$data['totalPasajeros']} pax");
            
            return [
                'success' => true,
                'message' => 'Pedido registrado correctamente',
                'pedido_id' => $pedido_id
            ];
            
        } catch (PDOException $e) {
            error_log("Error en nuevoPedido: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al registrar el pedido'];
        }
    }
    
    /**
     * Actualiza el estado de cocina de un pedido
     */
    public function actualizarEstadoPedido($data) {
        try {
            if (!isset($data['pedido_id']) || !isset($data['estado'])) {
                return ['success' => false, 'error' => 'Datos incompletos'];
            }
            
            $estados_validos = ['nuevo', 'preparacion', 'listo', 'completado'];
            if (!in_array($data['estado'], $estados_validos)) {
                return ['success' => false, 'error' => 'Estado no válido'];
            }
            
            $stmt = $this->db->prepare("
                UPDATE pedidos 
                SET estado_cocina = ?, fecha_estado = NOW() 
                WHERE id = ?
            ");
            
            $stmt->execute([$data['estado'], $data['pedido_id']]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Estado actualizado'];
            } else {
                return ['success' => false, 'error' => 'Pedido no encontrado'];
            }
            
        } catch (PDOException $e) {
            error_log("Error en actualizarEstadoPedido: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al actualizar estado'];
        }
    }
    
    /**
     * Obtiene estadísticas para una fecha específica
     */
    public function getEstadisticas($params) {
        try {
            $fecha = $params['fecha'] ?? date('Y-m-d');
            
            // Total de desayunos (personas)
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(total_pasajeros), 0) as total
                FROM pedidos 
                WHERE DATE(fecha_pedido) = ?
            ");
            $stmt->execute([$fecha]);
            $totalReservas = (int)$stmt->fetch()['total'];
            
            // Total de pedidos
            $stmt = $this->db->prepare("
                SELECT COUNT(*) as total 
                FROM pedidos 
                WHERE DATE(fecha_pedido) = ?
            ");
            $stmt->execute([$fecha]);
            $totalPedidos = (int)$stmt->fetch()['total'];
            
            // Desglose por tipo de desayuno
            $stmt = $this->db->prepare("
                SELECT desayunos FROM pedidos WHERE DATE(fecha_pedido) = ?
            ");
            $stmt->execute([$fecha]);
            $pedidos = $stmt->fetchAll();
            
            $desglose = [1 => 0, 2 => 0, 3 => 0, 4 => 0];
            foreach ($pedidos as $p) {
                $desayunos = json_decode($p['desayunos'], true) ?: [];
                foreach ($desayunos as $d) {
                    if (isset($d['id']) && isset($desglose[$d['id']])) {
                        $desglose[$d['id']] += $d['cantidad'] ?? 1;
                    }
                }
            }
            
            // Estados de cocina
            $stmt = $this->db->prepare("
                SELECT 
                    SUM(CASE WHEN estado_cocina = 'nuevo' THEN 1 ELSE 0 END) as nuevo,
                    SUM(CASE WHEN estado_cocina = 'preparacion' THEN 1 ELSE 0 END) as preparacion,
                    SUM(CASE WHEN estado_cocina = 'listo' THEN 1 ELSE 0 END) as listo,
                    SUM(CASE WHEN estado_cocina = 'completado' THEN 1 ELSE 0 END) as completado
                FROM pedidos 
                WHERE DATE(fecha_pedido) = ?
            ");
            $stmt->execute([$fecha]);
            $estados = $stmt->fetch();
            
            return [
                'success' => true,
                'totalReservas' => $totalReservas,
                'totalPedidos' => $totalPedidos,
                'desglose' => $desglose,
                'estados' => $estados
            ];
            
        } catch (PDOException $e) {
            error_log("Error en getEstadisticas: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al obtener estadísticas'];
        }
    }
    
    /**
     * Obtiene informe para un rango de fechas
     */
    public function getInformeRango($params) {
        try {
            if (!isset($params['desde']) || !isset($params['hasta'])) {
                return ['success' => false, 'error' => 'Fechas requeridas'];
            }
            
            $desde = $params['desde'];
            $hasta = $params['hasta'];
            
            // Total de desayunos en el período
            $stmt = $this->db->prepare("
                SELECT COALESCE(SUM(total_pasajeros), 0) as total
                FROM pedidos 
                WHERE DATE(fecha_pedido) BETWEEN ? AND ?
            ");
            $stmt->execute([$desde, $hasta]);
            $totalDesayunos = (int)$stmt->fetch()['total'];
            
            // Total de pedidos
            $stmt = $this->db->prepare("
                SELECT COUNT(*) as total 
                FROM pedidos 
                WHERE DATE(fecha_pedido) BETWEEN ? AND ?
            ");
            $stmt->execute([$desde, $hasta]);
            $totalPedidos = (int)$stmt->fetch()['total'];
            
            // Días con actividad
            $stmt = $this->db->prepare("
                SELECT COUNT(DISTINCT DATE(fecha_pedido)) as dias
                FROM pedidos 
                WHERE DATE(fecha_pedido) BETWEEN ? AND ?
            ");
            $stmt->execute([$desde, $hasta]);
            $diasConPedidos = (int)$stmt->fetch()['dias'];
            
            // Promedio diario
            $promedioDiario = $diasConPedidos > 0 ? round($totalDesayunos / $diasConPedidos, 1) : 0;
            
            // Ranking por tipo de desayuno
            $stmt = $this->db->prepare("
                SELECT desayunos FROM pedidos 
                WHERE DATE(fecha_pedido) BETWEEN ? AND ?
            ");
            $stmt->execute([$desde, $hasta]);
            $pedidos = $stmt->fetchAll();
            
            $ranking = [];
            foreach ($pedidos as $p) {
                $desayunos = json_decode($p['desayunos'], true) ?: [];
                foreach ($desayunos as $d) {
                    $id = $d['id'];
                    $cantidad = $d['cantidad'] ?? 1;
                    if (!isset($ranking[$id])) {
                        $ranking[$id] = 0;
                    }
                    $ranking[$id] += $cantidad;
                }
            }
            
            arsort($ranking);
            $rankingTipos = [];
            foreach ($ranking as $id => $cantidad) {
                $rankingTipos[] = ['id' => $id, 'cantidad' => $cantidad];
            }
            
            // Por horario
            $stmt = $this->db->prepare("
                SELECT horario, SUM(total_pasajeros) as total
                FROM pedidos 
                WHERE DATE(fecha_pedido) BETWEEN ? AND ?
                GROUP BY horario
                ORDER BY horario
            ");
            $stmt->execute([$desde, $hasta]);
            $porHorario = [];
            while ($row = $stmt->fetch()) {
                $porHorario[$row['horario']] = (int)$row['total'];
            }
            
            return [
                'success' => true,
                'totalDesayunos' => $totalDesayunos,
                'totalPedidos' => $totalPedidos,
                'diasConPedidos' => $diasConPedidos,
                'promedioDiario' => $promedioDiario,
                'rankingTipos' => $rankingTipos,
                'porHorario' => $porHorario
            ];
            
        } catch (PDOException $e) {
            error_log("Error en getInformeRango: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al generar informe'];
        }
    }
    
    // ============================================
    // FUNCIONES PARA GESTIÓN DE CHECK-IN
    // ============================================
    
    /**
     * Registrar un nuevo check-in
     */
    public function registrarCheckin($data) {
        try {
            // Validar datos requeridos
            if (!isset($data['habitacion']) || !isset($data['nombre_huesped']) || 
                !isset($data['num_pasajeros']) || !isset($data['fecha_checkin']) || 
                !isset($data['fecha_checkout'])) {
                return ['success' => false, 'error' => 'Datos incompletos'];
            }

            // Verificar que la habitación no tenga ya un check-in activo
            $stmt = $this->db->prepare("SELECT id FROM checkins WHERE habitacion = ? AND activo = 1");
            $stmt->execute([$data['habitacion']]);
            if ($stmt->fetch()) {
                return ['success' => false, 'error' => 'La habitación ya tiene un check-in activo'];
            }

            // Insertar el check-in
            $stmt = $this->db->prepare("
                INSERT INTO checkins 
                (habitacion, nombre_huesped, num_pasajeros, fecha_checkin, fecha_checkout, activo) 
                VALUES (?, ?, ?, ?, ?, 1)
            ");
            
            $stmt->execute([
                $data['habitacion'],
                $data['nombre_huesped'],
                $data['num_pasajeros'],
                $data['fecha_checkin'],
                $data['fecha_checkout']
            ]);

            return [
                'success' => true,
                'message' => 'Check-in registrado correctamente',
                'id' => $this->db->lastInsertId()
            ];

        } catch (PDOException $e) {
            error_log("Error en registrarCheckin: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error en la base de datos'];
        }
    }

    /**
     * Obtener todos los check-ins (activos e inactivos)
     */
    public function getCheckins() {
        try {
            $stmt = $this->db->query("
                SELECT 
                    c.*,
                    CASE WHEN p.id IS NOT NULL THEN 1 ELSE 0 END as desayuno_pedido
                FROM checkins c
                LEFT JOIN pedidos p ON c.habitacion = p.habitacion AND DATE(p.fecha_pedido) = CURDATE()
                ORDER BY c.activo DESC, c.fecha_checkin DESC
            ");
            
            $checkins = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // Formatear fechas si es necesario
            foreach ($checkins as &$c) {
                $c['fecha_checkin'] = date('Y-m-d', strtotime($c['fecha_checkin']));
                $c['fecha_checkout'] = date('Y-m-d', strtotime($c['fecha_checkout']));
            }
            
            return $checkins;
            
        } catch (PDOException $e) {
            error_log("Error en getCheckins: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al obtener check-ins'];
        }
    }

    /**
     * Registrar check-out (desactivar check-in)
     */
    public function registrarCheckout($data) {
        try {
            if (!isset($data['habitacion'])) {
                return ['success' => false, 'error' => 'Número de habitación requerido'];
            }

            $stmt = $this->db->prepare("
                UPDATE checkins 
                SET activo = 0, fecha_checkout_real = NOW() 
                WHERE habitacion = ? AND activo = 1
            ");
            
            $stmt->execute([$data['habitacion']]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Check-out registrado correctamente'];
            } else {
                return ['success' => false, 'error' => 'No hay check-in activo para esta habitación'];
            }

        } catch (PDOException $e) {
            error_log("Error en registrarCheckout: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error en la base de datos'];
        }
    }

    /**
     * Eliminar un check-in del historial (solo para inactivos)
     */
    public function eliminarCheckin($data) {
        try {
            if (!isset($data['id'])) {
                return ['success' => false, 'error' => 'ID requerido'];
            }

            // Solo permitir eliminar check-ins inactivos
            $stmt = $this->db->prepare("DELETE FROM checkins WHERE id = ? AND activo = 0");
            $stmt->execute([$data['id']]);
            
            if ($stmt->rowCount() > 0) {
                return ['success' => true, 'message' => 'Registro eliminado correctamente'];
            } else {
                return ['success' => false, 'error' => 'No se puede eliminar un check-in activo'];
            }

        } catch (PDOException $e) {
            error_log("Error en eliminarCheckin: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error en la base de datos'];
        }
    }

    /**
     * Obtener habitaciones activas para el selector de la app del huésped
     */
    public function getHabitacionesActivas() {
        try {
            $stmt = $this->db->query("
                SELECT 
                    c.habitacion,
                    c.nombre_huesped,
                    c.num_pasajeros,
                    CASE WHEN p.id IS NOT NULL THEN 1 ELSE 0 END as desayuno_pedido
                FROM checkins c
                LEFT JOIN pedidos p ON c.habitacion = p.habitacion AND DATE(p.fecha_pedido) = CURDATE()
                WHERE c.activo = 1
                ORDER BY c.habitacion
            ");
            
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
            
        } catch (PDOException $e) {
            error_log("Error en getHabitacionesActivas: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al obtener habitaciones activas'];
        }
    }
    
    /**
     * Resetear desayunos del día - Ahora no hace nada (registro permanente)
     */
    public function resetearDesayunoDiario() {
        try {
            // Esta función ya no elimina nada, solo registra en log
            error_log("🔄 Intento de reseteo de desayunos - Acción deshabilitada para mantener registro histórico");
            
            return [
                'success' => true,
                'message' => 'Los registros son permanentes - No se han eliminado datos'
            ];
            
        } catch (PDOException $e) {
            error_log("Error en resetearDesayunoDiario: " . $e->getMessage());
            return ['success' => false, 'error' => 'Error al procesar la solicitud'];
        }
    }
}

// ============================================
// PROCESAMIENTO DE LA SOLICITUD
// ============================================

$api = new API();

// Obtener la acción solicitada
$action = $_GET['action'] ?? '';

// Obtener datos del cuerpo de la solicitud para POST
$input = json_decode(file_get_contents('php://input'), true) ?: [];

// Procesar según la acción
switch($action) {
    
    // ===== FUNCIONES DE VERIFICACIÓN =====
    case 'verificarConexion':
        echo json_encode($api->verificarConexion());
        break;
    
    // ===== FUNCIONES DE PEDIDOS =====
    case 'getDisponibilidad':
        echo json_encode($api->getDisponibilidad($_GET));
        break;
        
    case 'getPedidos':
        echo json_encode($api->getPedidos($_GET));
        break;
        
    case 'nuevoPedido':
        echo json_encode($api->nuevoPedido($input));
        break;
        
    case 'actualizarEstadoPedido':
        echo json_encode($api->actualizarEstadoPedido($input));
        break;
        
    case 'getEstadisticas':
        echo json_encode($api->getEstadisticas($_GET));
        break;
        
    case 'getInformeRango':
        echo json_encode($api->getInformeRango($_GET));
        break;
    
    // ===== FUNCIONES DE CHECK-IN =====
    case 'registrarCheckin':
        echo json_encode($api->registrarCheckin($input));
        break;
        
    case 'getCheckins':
        echo json_encode($api->getCheckins());
        break;
        
    case 'registrarCheckout':
        echo json_encode($api->registrarCheckout($input));
        break;
        
    case 'eliminarCheckin':
        echo json_encode($api->eliminarCheckin($input));
        break;
        
    case 'getHabitacionesActivas':
        echo json_encode($api->getHabitacionesActivas());
        break;
    
    // ===== FUNCIONES DE RESETEO (DESHABILITADAS) =====
    case 'reiniciarDia':
    case 'resetearDesayunoDiario':
        echo json_encode($api->resetearDesayunoDiario());
        break;
    
    // ===== ACCIÓN NO VÁLIDA =====
    default:
        http_response_code(400);
        echo json_encode([
            'success' => false, 
            'error' => 'Acción no válida',
            'acciones_disponibles' => [
                'verificarConexion',
                'getDisponibilidad',
                'getPedidos', 
                'nuevoPedido',
                'actualizarEstadoPedido',
                'getEstadisticas',
                'getInformeRango',
                'registrarCheckin',
                'getCheckins',
                'registrarCheckout',
                'eliminarCheckin',
                'getHabitacionesActivas'
            ]
        ]);
        break;
}
?>