<?php
class MotivoStock
{
    private $conn;

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

    public function obtenerTodos($filtros = [])
    {
        try {
            $where = ["m.id > 0"];
            $params = [];

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

            // Filtro por tipo de movimiento
            if (!empty($filtros['tipo_movimiento'])) {
                $where[] = "(m.tipo_movimiento = :tipo OR m.tipo_movimiento = 'todos')";
                $params[':tipo'] = $filtros['tipo_movimiento'];
            }

            // Filtro por estado
            if (isset($filtros['activo'])) {
                $where[] = "m.activo = :activo";
                $params[':activo'] = $filtros['activo'];
            }

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

            $query = "SELECT 
                        m.*,
                        CASE 
                            WHEN m.tipo_movimiento = 'entrada' THEN 'Entrada'
                            WHEN m.tipo_movimiento = 'salida' THEN 'Salida'
                            WHEN m.tipo_movimiento = 'ajuste' THEN 'Ajuste'
                            ELSE 'Todos'
                        END as tipo_movimiento_texto
                      FROM motivos_stock m
                      WHERE $whereClause
                      ORDER BY m.predeterminado DESC, m.nombre ASC";

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

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

    public function obtenerPorId($id)
    {
        try {
            $query = "SELECT * FROM motivos_stock WHERE 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 motivo: " . $e->getMessage());
            return false;
        }
    }

    public function crear($datos)
    {
        try {
            // Verificar que el nombre no existe
            $checkQuery = "SELECT COUNT(*) as count FROM motivos_stock WHERE nombre = :nombre";
            $checkStmt = $this->conn->prepare($checkQuery);
            $checkStmt->bindParam(':nombre', $datos['nombre']);
            $checkStmt->execute();
            $result = $checkStmt->fetch(PDO::FETCH_ASSOC);

            if ($result['count'] > 0) {
                throw new Exception("Ya existe un motivo con este nombre");
            }

            $query = "INSERT INTO motivos_stock (
                        nombre, descripcion, tipo_movimiento, activo
                      ) VALUES (
                        :nombre, :descripcion, :tipo_movimiento, :activo
                      )";

            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':nombre', $datos['nombre']);
            $stmt->bindParam(':descripcion', $datos['descripcion']);
            $stmt->bindParam(':tipo_movimiento', $datos['tipo_movimiento']);
            $stmt->bindParam(':activo', $datos['activo']);

            $stmt->execute();
            return $this->conn->lastInsertId();
        } catch (Exception $e) {
            error_log("Error creando motivo: " . $e->getMessage());
            throw $e;
        }
    }

    public function actualizar($id, $datos)
    {
        try {
            // Verificar que el nombre no existe en otro registro
            if (isset($datos['nombre'])) {
                $checkQuery = "SELECT COUNT(*) as count FROM motivos_stock WHERE nombre = :nombre AND id != :id";
                $checkStmt = $this->conn->prepare($checkQuery);
                $checkStmt->bindParam(':nombre', $datos['nombre']);
                $checkStmt->bindParam(':id', $id);
                $checkStmt->execute();
                $result = $checkStmt->fetch(PDO::FETCH_ASSOC);

                if ($result['count'] > 0) {
                    throw new Exception("Ya existe un motivo con este nombre");
                }
            }

            $updateFields = [];
            $allowedFields = ['nombre', 'descripcion', 'tipo_movimiento', 'activo'];

            foreach ($allowedFields as $field) {
                if (isset($datos[$field])) {
                    $updateFields[] = "$field = :$field";
                }
            }

            if (empty($updateFields)) {
                throw new Exception("No hay datos para actualizar");
            }

            $query = "UPDATE motivos_stock SET " . implode(', ', $updateFields) . ", updated_at = CURRENT_TIMESTAMP WHERE id = :id";
            $stmt = $this->conn->prepare($query);

            foreach ($allowedFields as $field) {
                if (isset($datos[$field])) {
                    $stmt->bindValue(":$field", $datos[$field]);
                }
            }
            $stmt->bindParam(':id', $id);

            return $stmt->execute();
        } catch (Exception $e) {
            error_log("Error actualizando motivo: " . $e->getMessage());
            throw $e;
        }
    }

    public function eliminar($id)
    {
        try {
            // Verificar si el motivo está siendo usado
            $checkQuery = "SELECT COUNT(*) as count FROM movimientos_stock WHERE motivo_id = :id";
            $checkStmt = $this->conn->prepare($checkQuery);
            $checkStmt->bindParam(':id', $id);
            $checkStmt->execute();
            $result = $checkStmt->fetch(PDO::FETCH_ASSOC);

            if ($result['count'] > 0) {
                // Si está siendo usado, solo desactivar
                $query = "UPDATE motivos_stock SET activo = 0, updated_at = CURRENT_TIMESTAMP WHERE id = :id";
                $stmt = $this->conn->prepare($query);
                $stmt->bindParam(':id', $id);
                return $stmt->execute();
            } else {
                // Si no está siendo usado, eliminar completamente
                $query = "DELETE FROM motivos_stock WHERE id = :id AND predeterminado = 0";
                $stmt = $this->conn->prepare($query);
                $stmt->bindParam(':id', $id);
                return $stmt->execute();
            }
        } catch (Exception $e) {
            error_log("Error eliminando motivo: " . $e->getMessage());
            return false;
        }
    }

    public function obtenerPorTipo($tipoMovimiento)
    {
        try {
            $query = "SELECT * FROM motivos_stock 
                      WHERE activo = 1 
                      AND (tipo_movimiento = :tipo OR tipo_movimiento = 'todos')
                      ORDER BY predeterminado DESC, nombre ASC";
            
            $stmt = $this->conn->prepare($query);
            $stmt->bindParam(':tipo', $tipoMovimiento);
            $stmt->execute();

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

    public function establecerPredeterminado($id)
    {
        try {
            $this->conn->beginTransaction();

            // Quitar predeterminado de todos
            $query1 = "UPDATE motivos_stock SET predeterminado = 0";
            $this->conn->exec($query1);

            // Establecer nuevo predeterminado
            $query2 = "UPDATE motivos_stock SET predeterminado = 1, activo = 1 WHERE id = :id";
            $stmt = $this->conn->prepare($query2);
            $stmt->bindParam(':id', $id);
            $result = $stmt->execute();

            $this->conn->commit();
            return $result;
        } catch (Exception $e) {
            $this->conn->rollback();
            error_log("Error estableciendo motivo predeterminado: " . $e->getMessage());
            throw $e;
        }
    }

    public function obtenerEstadisticas()
    {
        try {
            $stats = [];

            // Total motivos
            $query = "SELECT COUNT(*) as total FROM motivos_stock WHERE activo = 1";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $stats['total_motivos'] = $stmt->fetchColumn();

            // Por tipo de movimiento
            $query = "SELECT 
                        tipo_movimiento,
                        COUNT(*) as cantidad
                      FROM motivos_stock 
                      WHERE activo = 1 
                      GROUP BY tipo_movimiento";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $stats['por_tipo'] = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Más utilizados (últimos 30 días)
            $query = "SELECT 
                        ms.nombre,
                        COUNT(mov.id) as usos
                      FROM motivos_stock ms
                      LEFT JOIN movimientos_stock mov ON ms.id = mov.motivo_id
                          AND mov.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
                      WHERE ms.activo = 1
                      GROUP BY ms.id, ms.nombre
                      ORDER BY usos DESC
                      LIMIT 5";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $stats['mas_utilizados'] = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return $stats;
        } catch (Exception $e) {
            error_log("Error obteniendo estadísticas de motivos: " . $e->getMessage());
            return [];
        }
    }
}
?>