<?php
/**
 * Modelo Repartidor - Gestión de repartidores/vendedores
 */
class Repartidor
{
    private $conn;

    public function __construct($db)
    {
        $this->conn = $db;
    }

    /**
     * Obtener todos los repartidores con filtros
     */
    public function obtenerTodos($filtros = [])
    {
        try {
            $where = ["r.id > 0"];
            $params = [];

            // Filtro por búsqueda
            if (!empty($filtros['search'])) {
                $where[] = "(r.nombre LIKE :search OR r.apellidos LIKE :search OR r.codigo LIKE :search OR r.email LIKE :search OR r.telefono LIKE :search)";
                $params[':search'] = '%' . $filtros['search'] . '%';
            }

            $whereClause = implode(' AND ', $where);

            $query = "SELECT 
                        r.*,
                        CONCAT(r.nombre, ' ', r.apellidos) as nombre_completo,
                        CASE 
                            WHEN r.ultimo_login IS NULL THEN 'Nunca'
                            WHEN r.ultimo_login > DATE_SUB(NOW(), INTERVAL 1 DAY) THEN 'Hoy'
                            WHEN r.ultimo_login > DATE_SUB(NOW(), INTERVAL 7 DAY) THEN 'Esta semana'
                            ELSE 'Hace más de una semana'
                        END as ultimo_acceso_texto
                      FROM repartidores r
                      WHERE $whereClause
                      ORDER BY r.created_at DESC";

            $stmt = $this->conn->prepare($query);
            $stmt->execute($params);

            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error obteniendo repartidores: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Obtener repartidor por ID
     */
    public function obtenerPorId($id)
    {
        try {
            $query = "SELECT 
                        r.*,
                        CONCAT(r.nombre, ' ', r.apellidos) as nombre_completo
                      FROM repartidores r 
                      WHERE r.id = :id";
            
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':id', $id);
            $stmt->execute();

            return $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error obteniendo repartidor por ID: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Crear nuevo repartidor
     */
    public function crear($datos)
    {
        try {
            $this->conn->beginTransaction();

            // Generar código único
            $codigo = $this->generarCodigo();

            // Hash de la contraseña
            $passwordHash = password_hash($datos['password'], PASSWORD_DEFAULT);

            $query = "INSERT INTO repartidores (
                        codigo, nombre, apellidos, telefono, telefono_secundario,
                        email, password_hash, puede_vincular_qr, notas
                      ) VALUES (
                        :codigo, :nombre, :apellidos, :telefono, :telefono_secundario,
                        :email, :password_hash, :puede_vincular_qr, :notas
                      )";

            $stmt = $this->conn->prepare($query);

            // Valor por defecto para puede_vincular_qr si no se envía
            $puede_vincular_qr = isset($datos['puede_vincular_qr']) ? ($datos['puede_vincular_qr'] ? 1 : 0) : 1;

            $stmt->bindParam(':codigo', $codigo);
            $stmt->bindParam(':nombre', $datos['nombre']);
            $stmt->bindParam(':apellidos', $datos['apellidos']);
            $stmt->bindParam(':telefono', $datos['telefono']);
            $stmt->bindParam(':telefono_secundario', $datos['telefono_secundario']);
            $stmt->bindParam(':email', $datos['email']);
            $stmt->bindParam(':password_hash', $passwordHash);
            $stmt->bindParam(':puede_vincular_qr', $puede_vincular_qr, PDO::PARAM_INT);
            $stmt->bindParam(':notas', $datos['notas']);

            $stmt->execute();
            $id = $this->conn->lastInsertId();

            $this->conn->commit();

            return [
                'id' => $id,
                'codigo' => $codigo
            ];
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error creando repartidor: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Actualizar repartidor
     */
    public function actualizar($id, $datos)
    {
        try {
            $this->conn->beginTransaction();

            $campos = [];
            $params = [':id' => $id];

            // Construir dinámicamente la query según los campos enviados
            $camposPermitidos = [
                'nombre', 'apellidos', 'telefono', 'telefono_secundario',
                'email', 'notas'
            ];

            foreach ($camposPermitidos as $campo) {
                if (isset($datos[$campo])) {
                    $campos[] = "$campo = :$campo";
                    $params[":$campo"] = $datos[$campo];
                }
            }

            // Manejar puede_vincular_qr como campo booleano
            if (isset($datos['puede_vincular_qr'])) {
                $campos[] = "puede_vincular_qr = :puede_vincular_qr";
                $params[':puede_vincular_qr'] = $datos['puede_vincular_qr'] ? 1 : 0;
            }

            // Si se envía nueva contraseña
            if (!empty($datos['password'])) {
                $campos[] = "password_hash = :password_hash";
                $params[':password_hash'] = password_hash($datos['password'], PASSWORD_DEFAULT);
            }

            if (empty($campos)) {
                throw new Exception("No se proporcionaron campos para actualizar");
            }

            $query = "UPDATE repartidores SET " . implode(', ', $campos) . " WHERE id = :id";
            
            $stmt = $this->conn->prepare($query);
            $stmt->execute($params);

            $this->conn->commit();
            return true;
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Error actualizando repartidor: " . $e->getMessage());
            throw $e;
        }
    }


    /**
     * Eliminar repartidor (eliminación real)
     */
    public function eliminar($id)
    {
        try {
            $query = "DELETE FROM repartidores WHERE id = :id";
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':id', $id);
            
            return $stmt->execute();
        } catch (Exception $e) {
            error_log("Error eliminando repartidor: " . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Obtener estadísticas generales
     */
    public function obtenerEstadisticas()
    {
        try {
            $query = "SELECT 
                        COUNT(*) as total,
                        SUM(CASE WHEN ultimo_login > DATE_SUB(NOW(), INTERVAL 1 DAY) THEN 1 ELSE 0 END) as activos_hoy,
                        SUM(CASE WHEN ultimo_login > DATE_SUB(NOW(), INTERVAL 7 DAY) THEN 1 ELSE 0 END) as activos_semana
                      FROM repartidores";

            $stmt = $this->conn->prepare($query);
            $stmt->execute();

            return $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            error_log("Error obteniendo estadísticas: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Validar login para app móvil
     */
    public function validarLogin($email, $password)
    {
        try {
            $query = "SELECT id, codigo, nombre, apellidos, email, password_hash, puede_vincular_qr
                      FROM repartidores
                      WHERE email = :email";
            
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':email', $email);
            $stmt->execute();
            
            $repartidor = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($repartidor && password_verify($password, $repartidor['password_hash'])) {
                // Actualizar último login
                $this->actualizarUltimoLogin($repartidor['id']);
                
                // No devolver el hash de la contraseña
                unset($repartidor['password_hash']);
                
                return $repartidor;
            }
            
            return false;
        } catch (Exception $e) {
            error_log("Error validando login: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Actualizar último login
     */
    private function actualizarUltimoLogin($id)
    {
        try {
            $query = "UPDATE repartidores SET ultimo_login = NOW() WHERE id = :id";
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':id', $id);
            $stmt->execute();
        } catch (Exception $e) {
            error_log("Error actualizando último login: " . $e->getMessage());
        }
    }

    /**
     * Generar código único para repartidor
     */
    private function generarCodigo()
    {
        try {
            // Obtener el siguiente número
            $query = "SELECT MAX(CAST(SUBSTRING(codigo, 5) AS UNSIGNED)) as max_num FROM repartidores WHERE codigo LIKE 'REP-%'";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $nextNum = ($result['max_num'] ?? 0) + 1;
            return 'REP-' . str_pad($nextNum, 3, '0', STR_PAD_LEFT);
        } catch (Exception $e) {
            error_log("Error generando código: " . $e->getMessage());
            return 'REP-' . str_pad(rand(1, 999), 3, '0', STR_PAD_LEFT);
        }
    }

    /**
     * Verificar si email ya existe
     */
    public function emailExiste($email, $excludeId = null)
    {
        try {
            $query = "SELECT COUNT(*) FROM repartidores WHERE email = :email";
            $params = [':email' => $email];
            
            if ($excludeId) {
                $query .= " AND id != :exclude_id";
                $params[':exclude_id'] = $excludeId;
            }
            
            $stmt = $this->conn->prepare($query);
            $stmt->execute($params);
            
            return $stmt->fetchColumn() > 0;
        } catch (Exception $e) {
            error_log("Error verificando email: " . $e->getMessage());
            return false;
        }
    }

}
?>