local frases = {
    "La temperatura del agua es: " .. math.floor(ac.getCar(0).waterTemperature) .. " grados.",
    "La temperatura del aceite es: " .. math.floor(ac.getCar(0).oilTemperature) .. " grados..",
    "La presión de turbo es: " .. ac.getCar(0).turboBoost .. " bar.",
    "El nivel de combustible actual es de: " .. ac.getCar(0).fuel .. " litros.",
    "Creemos que la mejor distribución de para este circuito es: " .. math.floor(ac.getCar(1).brakeBias) .. " %.",
}
local vueltaAnterior = -1
local vueltaAnterior2 = -1
local ultimaReproduccion = 0
local tiempoEntreReproduccion = 30 -- 60 segundos = 1 minuto
local vueltaObligatoriaCambioNeumaticos = 3  -- La vuelta en la que el cambio de neumáticos es obligatorio
local indiceNeumaticosInicio = 0  -- El índice del compuesto de neumáticos con el que el jugador debe comenzar
local indiceNeumaticosACambiar = 1  -- El índice del compuesto de neumáticos al que el jugador debe cambiar
local tiempoEsperadoCambioNeumaticos = 20.8 -- Tiempo esperado para que el auto esté detenido en pits cambiando neumáticos.
local compuestosSalidaIA = {}
local aiTakePlayersFuel = false  -- Cambiar a true para que la IA tome la carga de combustible del jugador.
local aiDriverCount = 0
local velocidadiaenvsc = 100
local intervaloComprobacion = 180 -- 3 minutos expresados en segundos
local activeFlag = nil
colisionPreviaConCoche = false
-- Variables configurables para detectar donuts
--umbralGrados = 95 -- activar el VSC si se detecta un cambio de dirección de 180 grados o más en un lapso de tiempo configurable en tiempoMaximoCambioCompass
--tiempoMaximoCambioCompass = 3.2 -- Tiempo máximo (en segundos) permitido entre cambios de dirección antes de activar el VSC
-- Supongamos que hay una variable para mantener el estado de si el piloto ya tiene un DT
local tieneDT = false
local cortesDespuesDeDT = 0 -- Nueva variable para contar los cortes después del DT
local ultimoCorteRegistrado = -1 -- Para que la comprobación funcione la primera vez
local ventanaAveriaActiva = false
local windowId = "VentanaAveria"
local windowPos = vec2(200, 200) -- Posición de la ventana
local windowSize = vec2(400, 200) -- Tamaño de la ventana
-- Variables globales
local neumaticosVerificados = false
local velocidadParaVerificarNeumaticos = 80 -- La velocidad a la que decidimos verificar el neumático
local mensajeFinalMostrado = false
local mostrarMensajeFinal = false
local mensajeActualParaPiloto = ""
local jugadorEntroAPitsEnVueltaObligatoria = false
local audiosReproducidos = {}
local audiosReproducidos = {}
local audioActual = nil -- La referencia al audio que se está reproduciendo actualmente
local tiempoInicioAudio = 0 -- El tiempo cuando el audio actual comenzó a reproducirse
local duracionAudio = 0 -- La duración estimada del audio actual en segundos
local colaReproduccion = {} -- Nueva cola de reproducción
local reproduciendo = false -- Estado de reproducción
local audioAnterior = nil
local conteoIAs = 0
local primeraVez = true
local estrategiasParadaIAs = {}
local tiempoParadaEnPitsParaCambioNeumaticosIA = {}
local tiempoDetenidoEnPitsIA = {}
local neumaticosInicialesIA = {}
local neumaticosAsignados = false
local tiempoUltimaComprobacion = 0 -- Guarda el tiempo desde la última comprobación de rotura
local cocheRoto = false -- Estado del coche, si se ha roto o no
local mensajedeaveria =""
local avisoUltimaOportunidadEmitido = false
local ultimoTiempoDeActualizacion = 0
intervaloDeActualizacion = 1.0 -- Por ejemplo, 1 segundo
startTime = nil
local mostrarMensajeVueltaObligatoria = false
--physics.setCarPenalty(ac.PenaltyType.MandatoryPits,2)--esto es para poner un DT drive trought
--local isCSPCompatible = ac.getPatchVersionCode and ac.getPatchVersionCode() >= 2219
local ultimoAudioReproducido = nil

-- Variables globales para el manejo del VSC
local prevCollisionDepth = 0
local prevCollisionDepth = {}
local prevHitValue = {}
local HitValue = 0
local carsCount = ac.getSim().carsCount -- Obtiene el número total de coches
for i = 1, carsCount do
    prevCollisionDepth[i] = 0
    prevHitValue[i] = 0
  end
isVSCActive = false
playerPositionAtVSC = nil
vscTimer = 0 -- Temporizador desde la activación del VSC
vscTimerActive = false -- Estado del temporizador
vscActivationTime = nil
gracePeriod = 50 -- 90 segundos de virtualsafetycar
local tiempoTranscurridoVSC = 0
local imagenamostrar ="ingeniero.png"


-- Variables de configuración detectar giros bruscos donuts roscos
local muestra1 = nil
local ultimoTiempo = os.clock()
local accidenteReciente = false

posicionesEnVSC = nil -- Almacenará las posiciones de los coches cuando se active el VSC
playerPositionAtVSC = 0 -- La posición del jugador cuando se activó el VSC
isVSCActive = false -- Estado de activación del VSC
mejorPosicionObjetivoVSC = nil -- Para rastrear la mejor posición objetivo durante el VSC

---compass borrar todo no lo uso


local mensajeActualParaPilotocierrepits =""
-- Inicialización de la cola de mensajes y variables de control
local colaDeMensajes = {}
local mensajeMostrando = false
local tiempoMensaje = 3
local duracionMensaje = 0.01 -- Duración de cada mensaje en segundos
local settings = {
    autopilot = {enabled = true, Speed = 100, Agression = 100, Pitnow = false},
    initialized = false,
    timerStarted = false,
    timer = 0
  }
  settings.timerStarted = true
  settings.timer = 0
local sesionActual
local sesionAnterior
local sessionRestarted = false
-- function mostrarVentanaAveria()
--     ventanaAveriaActiva = true
--     ui.transparentWindow(windowId, windowPos, windowSize, true, false, function()
--         ui.pushDWriteFont('Segoe UI;Weight=Bold')
--         ui.dwriteText("AVERÍA IMPORTANTE - ENTRA EN BOXES INMEDIATAMENTE", 24)
--         ui.popDWriteFont()
--         ui.image('averia.png', vec2(10, 10)) -- Muestra una imagen de bandera roja
--     end)
-- end

function ocultarVentanaAveria()
    ventanaAveriaActiva = false
end

function detectarVuelcos()
    -- Sistema de detección de vuelcos de cualquier coche
        local carsCountvolcar = ac.getSim().carsCount
        for i = 0, carsCountvolcar - 1 do
            --local carvolcar = ac.getCar(i)
            local estadoUp = ac.getCar(i).up.y
            if estadoUp < 0 then
                --ac.log("estadoUP: " .. tostring(estadoUp))
                --reproducirAudio('accid.mp3')
                reproducirAudio('accid.mp3', 7) 
                setTimeout(function()
                    activarVSC(i)
                end, 6) -- El retraso está en segundos            
            end
        end
end

function detectarCortesYDT()
-- Sistema de detección de cortes y DT (drive through)
local cortes = ac.getCar(0).lapCutsCount

if tieneDT then
    -- Ajustar el conteo de cortes para reflejar los cortes después del DT
    cortes = cortes - 4
end

local cortesDespuesDeDT = 0 -- Mantener el conteo de cortes después del DT


if cortes ~= ultimoCorteRegistrado then
    -- Actualiza el último corte registrado
    ultimoCorteRegistrado = cortes 


        
    -- Actualizar el mensaje para el piloto
    if tieneDT then
        mensajeActualParaPiloto = "CUMPLE EL DRIVE-THROUGH"
    else
        if ac.getSim().raceSessionType == ac.SessionType.Practice then
            imagenamostrar="ingeniero.png"
            mensajeActualParaPiloto = "SESIÓN DE PRÁCTICA, DISFRUTA DEL CIRCUITO.   " .. "Cortes: " .. (cortes)
        elseif ac.getSim().raceSessionType == ac.SessionType.Qualify then
            imagenamostrar="ingeniero.png"
            mensajeActualParaPiloto = "INTENTA HACER LA MEJOR QUALY POSIBLE PARA EL EQUIPO.   " .. "Cortes: " .. (cortes)
        end
    end

    if not tieneDT then
        if cortes >= 4 then
                physics.setCarPenalty(ac.PenaltyType.MandatoryPits, 2)
                tieneDT = true -- Marcar que el piloto ha recibido un DT
                cortesDespuesDeDT = 0 -- Resetear el conteo de cortes después del DT
                --reproducirAudio('cortes7_dt.mp3') -- Reproducir audio para el DT
                reproducirAudio('cortes7_dt.mp3', 14)
            elseif cortes == 3 then
                --reproducirAudio('cortes6ultimocorte.mp3') -- Reproducir audio del último corte antes del DT
                reproducirAudio('cortes6ultimocorte.mp3', 5)
            elseif cortes == 2 then
                --reproducirAudio('cortes3.mp3') -- Reproducir audio del último corte antes del DT
                reproducirAudio('cortes3.mp3', 3)
            elseif cortes == 1 then
                --reproducirAudio('cortes1.mp3') -- Reproducir audio del último corte antes del DT
                reproducirAudio('cortes1.mp3', 3)
            end
        else
            -- Si el piloto ya tiene un DT, ajustar el conteo de cortes después del DT
            cortesDespuesDeDT = cortes
            if cortesDespuesDeDT >= 2 then
                    physics.setCarPenalty(ac.PenaltyType.BlackFlag, -1)
                    reproducirAudio('cortes8_black.mp3',10) -- Reproducir audio de expulsión
                    cortes=0 --para que deje de sonar el audio.
            elseif cortesDespuesDeDT == 1 then
                    reproducirAudio('cortes8a_oportunidad.mp3',6) -- Reproducir audio de última oportunidad
            end
        end
    end
end

-- Función para detectar giros bruscos y activar el VSC
function detectarGiroBruscoYActivarVSC()
    local car = ac.getCar(0) -- Coche con índice 0
    local lookActual = car.look -- Vector look actual
    local tiempoActual = os.clock()
    local tiempoTranscurrido = tiempoActual - ultimoTiempo
    local intervaloMinimo = 1.2 -- Tiempo mínimo en segundos para detectar el cambio
    
    
    -- Verificar si ha habido un accidente a más de 180 de mi coche, para sacar el vsc
    local collisionDepthChange = car.collisionDepth - (prevCollisionDepth[1] or 0)

    if collisionDepthChange > 0 and car.collidedWith ~= 0 and car.speedKmh > 180 then
        accidenteReciente = true
        ac.log("accidente a más de 180")
        activarVSC(0)
    else
        accidenteReciente = false
    end

    -- Verificar si ha habido un accidente reciente a 50kmh y si justo después se gira mi coche, sacamos el vsc
    if collisionDepthChange > 0.09 and car.collidedWith ~= 0 and car.speedKmh > 50 then
        accidenteReciente = true
        ac.log("accidente a más de 50kmh me pueden girar o no y si lo hacen, sale el vsc")
        ac.log(("collisondepth:")..collisionDepthChange)
        activarVSC(0)
    else
        accidenteReciente = false
    end


    
    -- Actualizar los valores previos para la próxima verificación
    prevCollisionDepth[1] = car.collisionDepth
    if muestra1 and tiempoTranscurrido >= intervaloMinimo then
        local muestra2 = lookActual.z
        -- Redondear los valores a cuatro decimales
        local muestra1Redondeada = math.floor((muestra1) * 10 + 0.0)
        local muestra2Redondeada = math.floor((muestra2) * 10 + 0.0)
        --ac.log("Giro normal: x de " .. tostring(muestra1Redondeada) .. " a " .. tostring(muestra2Redondeada))
        -- Comprobar si los números son iguales pero de signo opuesto
        if muestra1Redondeada == -muestra2Redondeada then
            ac.log("Giro brusco detectado,(sacamos vsc porque hay accidente reciente): z de " .. tostring(muestra1Redondeada) .. " a " .. tostring(muestra2Redondeada))
            if accidenteReciente then
                reproducirAudio('situacionpeligro.mp3',5)
                setTimeout(function()
                    activarVSC(0)
                    accidenteReciente = false
                end, 4) -- El retraso está en segundos
            end
        end
        -- Reinicia la muestra para la próxima comprobación
        muestra1 = lookActual.z
        ultimoTiempo = tiempoActual
    elseif not muestra1 then
        -- Inicializa la primera muestra y el tiempo si es la primera ejecución
        muestra1 = lookActual.z
        ultimoTiempo = tiempoActual
    end
end


function reproducirFraseAleatoria()
    local fraseAleatoria = frases[math.random(#frases)]
    agregarMensajeACola(fraseAleatoria)
    -- Aquí puedes agregar el código para reproducir la frase como audio si lo deseas
end





function script.update(dt)
    if ac.getSim().isSessionStarted then
        --detectarGiroBruscoYActivarVSC()-- Sistema de detección de giros bruscos roscos
        --detectarVuelcos() --lo comento y solo lo pongo en carrera, mas abajo
        detectarCortesYDT()

            -- -- Ejemplo de cómo usar la función para reproducir la temperatura del agua como audio.
            -- if ac.getCar(0).waterTemperature then
            --     local temperaturaAgua = tostring(math.floor(ac.getCar(0).waterTemperature))
            --     reproducirNumeroComoAudio(temperaturaAgua)
            --     ac.log("temperatura agua = " .. temperaturaAgua)
            -- end
            ----reproducir frases cada minuto
            ultimaReproduccion = ultimaReproduccion + dt
            if ultimaReproduccion >= tiempoEntreReproduccion then
                reproducirFraseAleatoria()
                ultimaReproduccion = 0
            end

    end

    if sessionRestarted == true then
        reiniciarEstado()
          sessionRestarted = false
          ac.log("DETECTADO REINCIO")
    end

    sesionActual = ac.getSim().raceSessionType
    -- Comprobar si la sesión ha cambiado
    if sesionActual ~= sesionAnterior then
        -- La sesión ha cambiado
        reiniciarEstado()
        sesionAnterior = sesionActual -- Actualizar sesionAnterior
    end

    
    -- Read Current Flag (Update only on change)
    if activeFlag ~= ac.getSim().raceFlagType then
        activeFlag = ac.getSim().raceFlagType
        ac.log("Current Flag = " .. activeFlag)
    end
-- ac.log("temperatura de agua:" .. ac.getCar(0).waterTemperature)
-- ac.log("vida del motor:" .. ac.getCar(0).engineLifeLeft)
-- ac.log("preloader diff:" .. ac.getCar(1).differentialPreload)
-- ac.log("coast diff:" .. ac.getCar(1).differentialCoast)
-- ac.log("diff power:" .. ac.getCar(1).differentialPower)




--A PARTIR DE AQUI, EL CÓDIGO NORMAL QUE TENÍA, AHORA SOLO SE EJECUTA EN SESIÓN RACE
if ac.getSim().raceSessionType == ac.SessionType.Race then

--este primer código es para que cante la posición cada vez que pasamos por meta 
local vueltaActual = ac.getCar(0).lapCount + 1 -- Obtiene la vuelta actual del jugador y suma 1 porque lapCount comienza en 0 
local posicion = ac.getCar(0).racePosition 
if vueltaActual ~= vueltaAnterior then -- La vuelta actual es diferente a la anterior 
    ac.log("ESTAMOS EN LA P " .. posicion) 
    ac.log("ESTAMOS EN LA VUELTA " .. vueltaActual) 
    reproducirPosicionAudio(posicion) 
    vueltaAnterior = vueltaActual 
end




    -- -- --este primer código es para que cante la posición cada vez que pasamos por meta
    -- -- local vueltaActual = ac.getCar(0).lapCount + 1 -- Obtiene la vuelta actual del jugador y suma 1 porque lapCount comienza en 0
    -- -- local posicion = ac.getCar(0).racePosition

    -- -- if vueltaActual ~= vueltaAnterior and vueltaActual > 1 then
    -- --     -- La vuelta actual es diferente a la anterior
    -- --     ac.log("ESTAMOS EN LA P " .. posicion)
    -- --     ac.log("ESTAMOS EN LA VUELTA " .. vueltaActual)
    -- --     reproducirPosicionAudio(posicion)
    -- --     vueltaAnterior = vueltaActual
    -- -- end


    --ACTUALIZAR MENSAJES EN EL CUADRO
    detectarGiroBruscoYActivarVSC()-- Sistema de detección de giros bruscos roscos
    detectarVuelcos()
    actualizarYMostrarMensaje(dt)
    actualizarEstadoDelJuego(dt)--esta función avisa de que es la última vuelta de la ventana de pits o expusion
    --actualizarYDibujarBarraVSC(dt)
    --esto es para las averías
    tiempoUltimaComprobacion = tiempoUltimaComprobacion + dt
    if tiempoUltimaComprobacion >= intervaloComprobacion then
        comprobarRoturaCoche()
        tiempoUltimaComprobacion = 0 -- Reinicia el contador después de cada comprobación
    end
        
        -- --local car = ac.getCar(0) -- Obtener el coche del jugador (índice 0)
        -- --local currentPenalty = car.currentPenaltyType -- Obtener el tipo de penalización actual del coche del jugador
        -- --local currentPenalty = ac.getCar(0).currentPenaltyType
        -- ac.log("currentpenalty: " .. (ac.getCar(0).currentPenaltyType))
        -- ac.log("Tipo de penalización actual: " .. tostring(ac.getCar(0).currentPenaltyType))

        -- if ac.getCar(0).currentPenaltyType == ac.PenaltyType.SlowDown then -- Suponiendo que SlowDown es el valor correcto
        --     physics.setCarPenalty(ac.PenaltyType.None, -1) -- Suponiendo que 'None' elimina la penalización
        --     ac.log("currentpenalty: " .. (ac.getCar(0).currentPenaltyParameter))
        --     ac.log("Tipo de penalización actual: " .. tostring(ac.getCar(0).currentPenaltyType))

        -- end

        -- Obtiene el coche del usuario
local userCar = ac.getCar(0)

-- Verifica si hay una penalización activa que no sea 'None'
if userCar.currentPenaltyType ~= ac.PenaltyType.None then
    -- Si hay una penalización diferente de 'None', registra el tipo y el parámetro de la penalización
    --ac.log("Penalización activa: Tipo = " .. tostring(userCar.currentPenaltyType) .. ", Parámetro = " .. tostring(userCar.currentPenaltyParameter))
end
        --ac.log("currentpenalty: " .. (currentPenalty))
        -- if currentPenalty == ac.PenaltyType.SlowDown then
        --     -- Si el coche del jugador tiene la penalización SlowDown, establecer la penalización a None
        --     physics.setCarPenalty(ac.PenaltyType.None, -1, 0)
        --     ac.getCarState(0).currentPenaltyType.None
        --     ac.log("SLOW DOWN ANULADO")
        -- end


        -- Actualización del temporizador
    if settings.timerStarted then
            settings.timer = settings.timer + dt
    end
      
        -- Configurar IA después de 15 segundos desde el inicio de la carrera
    if settings.timerStarted and settings.timer > 15 and not settings.initialized then
            settings.initialized = true
            settings.autopilot.Speed = 100  -- Configura el nivel de IA al x%
            settings.autopilot.enabled = true  -- Asegúrate de que el autopiloto esté habilitado
            settings.autopilot.Agression = 50
            for i = 1, 23 do -- Itera sobre todos los coches
                physics.setAILevel(i, settings.autopilot.Speed / 100)
                physics.setAIAggression(i, settings.autopilot.Agression / 100)
            end
        ac.log("level y agression seteados")
        ac.log("LEVEL: " .. (settings.autopilot.Speed / 100) .. " AGRSN: " .. (settings.autopilot.Agression / 100))
    end
 
    ----------------------------------------------------------------------------verificarGiroYActivarVSC(dt)--esto es para ver si nos giran el coche

    --esto es para el vsc
    --verificarYActivarVSC() --la comento, ya no la uso porque ahora lo detecto desde la función que detecta giros bruscos
    verificarmurosYActivarVSC()--verificamos si me doy contra el muro y saco vsc

    if isVSCActive then
        actualizarTemporizadorVSC(dt)
        local mensaje = ""
        vscTimer = vscTimer + dt  -- Actualiza el temporizador con el deltaTime
    
        -- Lógica para contar los coches en pits y ajustar la posición
        local cochesDelanteEnPits = 0
        for i = 1, (conteoIAs-1) do
            local car = ac.getCar(i)
            if car.isInPitlane and posicionesEnVSC[i] < playerPositionAtVSC then
                cochesDelanteEnPits = cochesDelanteEnPits + 1
            end
        end

        local posicionAjustadaDelJugador = playerPositionAtVSC - cochesDelanteEnPits
        if posicionAjustadaDelJugador < mejorPosicionObjetivoVSC then
            mejorPosicionObjetivoVSC = posicionAjustadaDelJugador -- Actualiza si el jugador mejora su posición
        end

        local tiempoRestante = gracePeriod - vscTimer
        --ac.log("tiemporestante" .. tostring(tiempoRestante))
            if isVSCActive then
                mensaje = string.format("VSC: MANTÉN LA POSICIÓN %d. VIRTUAL SAFETY CAR 100 KMH/MAX. Tiempo restante: %.2f segundos.", mejorPosicionObjetivoVSC, tiempoRestante)
            else
                mensaje = string.format("VSC TERMINADO")
                imagenamostrar="ingeniero.png"
            end

        -- Comprueba si el tiempo restante es igual a 3, 2 o 1 y reproduce el audio correspondiente
        if tiempoRestante <= 7 and tiempoRestante > 6 then
            -- Reproduce el audio para 3 segundos
            reproducirAudio('tres.mp3',1)
            
        elseif tiempoRestante <= 5 and tiempoRestante > 4 then
            -- Reproduce el audio para 2 segundos
            reproducirAudio('dos.mp3',1)
            
        elseif tiempoRestante <= 3 and tiempoRestante > 2 then
            -- Reproduce el audio para 1 segundo
            reproducirAudio('uno.mp3',1)
            
        elseif tiempoRestante <= 1 and tiempoRestante > 0 then
            -- Reproduce el audio para 0 segundos
            reproducirAudio('cero.mp3',1)
            reproducirAudio('scfin.mp3', 6)
            
        end
        -- Resto del código para mensajes de audio y agregar mensaje a cola
        agregarMensajeACola(mensaje)
        imagenamostrar="sc.gif"
        mensajeActualParaPiloto = mensaje
    else --SE HA TERMINADO EL VSC    
        --local mensaje = string.format("VSC: fin")
        --agregarMensajeACola(mensaje)
        --limpiarColaDeMensajes()
        --imagenamostrar="ingeniero.png"
        --reproducirAudio('scfin.mp3', 6)
        --local mensajefinsc = string.format("VSC: VIRTUAL SAFETY CAR TERMINADO. SE RELANZA LA CARRERA")
        --mensajeActualParaPiloto = mensajefinsc
        --mensajeActualParaPiloto = mensaje
        --agregarMensajeACola(mensaje)
    
    end

    -- Actualización de prevCollisionDepth y prevHitValue para cada coche
    local carsCount = ac.getSim().carsCount
    for i = 0, carsCount - 1 do
        local car = ac.getCar(i)
        prevCollisionDepth[i+1] = car.collisionDepth
        -- Asumiendo que tienes una forma de calcular HitValue basado en alguna lógica de colisión
        -- prevHitValue[i+1] = Aquí deberías calcular o actualizar el HitValue basado en las colisiones detectadas para el coche i
    end

    if not isVSCActive then
        if mostrarMensajeVueltaObligatoria then
            mensajeActualParaPiloto = mensajeActualParaPilotocierrepits
            agregarMensajeACola(mensajeActualParaPiloto)
        else
        -- Obtener el nombre largo del compuesto de neumáticos al que debe cambiar el jugador
            local tyreChangeName = ac.getTyresName(0, ruedaCambio)
                if not tyreChangeName then
                    tyreChangeName = "desconocido"  -- En caso de que no se pueda obtener el nombre, usar un valor por defecto
                end
                local nombreNeumaticosACambiar = ac.getTyresName(0, indiceNeumaticosACambiar)
                if not cocheRoto then
                    imagenamostrar="ingeniero.png"
                end
                    --a continuación hago que el mensaje solo salga si hay ventana de pits
                    local vueltaActual = ac.getCar(0).lapCount + 1 -- Obtiene la vuelta actual del jugador y suma 1 porque lapCount comienza en 0

                    -- Verifica si la vuelta actual está dentro de alguna ventana de pits abierta
                    if vueltaActual >= vueltaObligatoriaCambioNeumaticos - 1 and vueltaActual <= vueltaObligatoriaCambioNeumaticos + 1 then
                        -- El mensaje se mostrará solo si la vuelta actual está dentro de la ventana permitida
                        if not isVSCActive then
                            if mostrarMensajeVueltaObligatoria then
                                mensajeActualParaPiloto = mensajeActualParaPilotocierrepits
                            else
                                -- Código para preparar y mostrar el mensaje sobre el cambio de neumáticos
                                -- Este bloque es donde preparas el mensaje como ya estabas haciendo
                            end
                            mensajeActualParaPiloto = "Recuerda: Puedes entrar a pits entre las vueltas " .. (vueltaObligatoriaCambioNeumaticos - 1) .. " y " .. (vueltaObligatoriaCambioNeumaticos + 1) .. " Debes montar neumaticos " .. nombreNeumaticosACambiar .. "."
                            agregarMensajeACola(mensajeActualParaPiloto) -- Asegúrate de agregar el mensaje a la cola solo una vez
                            


                            local vueltaActual = ac.getCar(0).lapCount + 1 -- Obtiene la vuelta actual del jugador y suma 1 porque lapCount comienza en 0 
                            if vueltaActual ~= vueltaAnterior2 then -- La vuelta actual es diferente a la anterior 
                                reproducirAudio('pitsabiertos.mp3',3)
                                vueltaAnterior2 = vueltaActual
                            end
                                

                            
                        end
                    else
                        -- Si no está en la ventana de pits, asegúrate de no mostrar el mensaje
                        mostrarMensajeVueltaObligatoria = false
                    end
            --imagenamostrar="ingeniero.png"
        end
    end




    if cocheRoto then
        --ac.log("averia")
        mensajeActualParaPiloto = mensajedeaveria
        agregarMensajeACola(mensajeActualParaPiloto)
        ac.setFFBMultiplier(3)
        mostrarVentanaAveria("AVERÍA IMPORTANTE - ENTRA EN BOXES INMEDIATAMENTE")
        --ui.image('averia_0005_005-piston.png', vec2(85, 85)) 
        -- Establece un temporizador para cambiar cocheRoto a false después de 10 segundos
        setTimeout(function()
            cocheRoto = false
            ac.setFFBMultiplier(1)
            -- Aquí también podrías añadir cualquier otra lógica que necesites ejecutar
            -- después de que el estado de cocheRoto cambie, como registrar un mensaje.
            --ac.log("El coche ha sido reparado.")
        end, 15) -- El retraso está en segundos
   end

    if avisoUltimaOportunidadEmitido then
        --ac.log("cierre de ventana de pits")
        setTimeout(function()
            mensajeActualParaPiloto = mensajeActualParaPilotocierrepits
            agregarMensajeACola(mensajeActualParaPiloto)
            imagenamostrar="ingeniero.png"
        end, 15) -- El retraso está en segundos
    end



    --PONEMOS FUEL A TODOS
    aiDriverCount = ac.getSim().carsCount - 1
    --if ac.getSim().raceSessionType == ac.SessionType.Race and ac.getPatchVersionCode() >= 2278 then
    if ac.getSim().raceSessionType == ac.SessionType.Race then
        if ac.getCar(0).speedMs < 1 and ac.getCar(0).lapCount < 1 then  -- used to run only at first lap while stationary.
        if aiTakePlayersFuel == false then
            physics.setCarFuel(0, ac.getCar(1).fuel) -- Set player fuel to same as ai opponents
            --ac.log("Set players fuel level to: " .. ac.getCar(1).fuel)
        elseif  aiTakePlayersFuel == true then
            -- Loop through ai drivers
            for i = 1, aiDriverCount, 1
                do
                    physics.setCarFuel(i, ac.getCar(0).fuel) -- Set ai fuel to the same as the players fuel
                    --ac.log("Set ai driver's fuel to: " .. ac.getCar(i).fuel)
                end
            end
        end
    else
        ac.log("Not in race session or CSP version too low. Must be atleast v0.2.0")
    end

 

    -- AQUÍ COMPRUEBO QUE LAS RUEDAS DEL PILOTO SEAN LAS QUE HE INDICADO AL INICIO.
    -- Solo ejecutar la comprobación si no se ha realizado antes
    if not neumaticosVerificados then
        local velocidadActual = ac.getCarSpeedKmh(0) -- Obtener la velocidad actual del coche del jugador en km/h          
        -- Verificar si el coche del jugador ha alcanzado la velocidad mínima requerida
        if velocidadActual > velocidadParaVerificarNeumaticos then
            -- Obtener el nombre corto del compuesto de neumáticos actualmente seleccionado para el coche del jugador
            local nombreCortoNeumaticos = ac.getTyresName(0, -1)
            
            local carIndex = 0 -- Índice del coche actual (0 para el jugador)

            --LISTO LOS NEUMÁTICOS DISPONIBLES PARA EL COCHE ELEGIDO


            local carIndex = 0 -- Índice del coche actual (0 para el jugador)
            local nombreCortoNeumaticos = ac.getTyresName(carIndex, -1)
            local indiceNeumaticosSeleccionado = ac.getTyresIndex(carIndex, nombreCortoNeumaticos)
            
            ac.log("El índice del juego de neumáticos actualmente seleccionado es: " .. indiceNeumaticosSeleccionado)
            
            ac.log("Listando el índice seleccionado y 3 índices menos y 3 índices más:")
            
            -- Función para obtener el nombre largo de un índice de neumático (o una cadena vacía si no existe)
            local function getNombreLargoNeumatico(indice)
                local nombreLargo = ac.getTyresLongName(carIndex, indice) or ""
                return nombreLargo
            end
            
            -- Listar los 3 índices menores
            for i = indiceNeumaticosSeleccionado - 1, indiceNeumaticosSeleccionado - 3, -1 do
                if i >= 0 then
                    local nombreLargo = getNombreLargoNeumatico(i)
                    ac.log(i .. ". " .. nombreLargo .. " (Índice: " .. i .. ")")
                end
            end
            
            -- Listar el índice seleccionado
            local nombreLargoSeleccionado = getNombreLargoNeumatico(indiceNeumaticosSeleccionado)
            ac.log(indiceNeumaticosSeleccionado .. ". " .. nombreLargoSeleccionado .. " (Índice: " .. indiceNeumaticosSeleccionado .. ")")
            
            -- Listar los 3 índices mayores
            for i = indiceNeumaticosSeleccionado + 1, indiceNeumaticosSeleccionado + 3 do
                local nombreLargo = getNombreLargoNeumatico(i)
                if nombreLargo ~= "" then
                    ac.log(i .. ". " .. nombreLargo .. " (Índice: " .. i .. ")")
                end
            end

            -----------------------------------

            if nombreCortoNeumaticos then
                local indiceNeumaticos = ac.getTyresIndex(0, nombreCortoNeumaticos)
                ac.log("El índice del juego de neumáticos actualmente seleccionado es: " .. indiceNeumaticos)
             
                -- Comprobar si el índice del juego de neumáticos coincide con el neumático de inicio requerido
                if indiceNeumaticos ~= indiceNeumaticosInicio then
                    -- Si el índice no coincide, el jugador no ha puesto el neumático indicado. Expulsar al jugador.
                    ac.log("El jugador no ha seleccionado el compuesto de neumáticos correcto. Se cerrará el juego.")
                    imagenamostrar="ingeniero.png"
                    mensajeActualParaPiloto = "DESCALIFICADO POR NO MONTAR EL COMPUESTO INDICADO POR EL EQUIPO."
                    agregarMensajeACola(mensajeActualParaPiloto)
                    ac.setSystemMessage("Penalización", "Has sido penalizado por no montar el compuesto de neumáticos indicado por el equipo.")
                    physics.setCarPenalty(ac.PenaltyType.BlackFlag, -1)
                else
                    ac.log("El jugador ha seleccionado el compuesto de neumáticos correcto.")
                end  
                -- Marcar como verificado para evitar comprobaciones repetidas
                neumaticosVerificados = true
            else
                ac.log("No se pudo obtener el nombre corto del juego de neumáticos. No es posible verificar el compuesto.")
            end
        end
    end

    -- Cosas a hacer una sola vez al inicio
    if primeraVez == true then
        conteoIAs = ac.getSim().carsCount - 1 -- Restamos uno aquí porque el conteo incluye al jugador.
        math.randomseed(os.time())  -- usado para que los números aleatorios funcionen correctamente.
        asignarNeumaticosInicialesIA()
        definirTiemposParadaEnPitsParaCambioNeumaticosIA()
        establecerEstrategiasParadaIAs()
        --reproducirFraseAleatoria()
        primeraVez = false
        --ac.getSession(ac.getSim().timeHours(23))
        ac.getSession(ac.getSim().currentSessionIndex)
        --ac.log(ac.getSim().timeHours)--SABER LA HORA
        --aqui pongo una ventana modalPopup para informar de la rueda que hay que montar en la salida
        -- Obtiene el nombre corto del compuesto de neumáticos con el que el jugador debe comenzar
        local nombreCortoNeumaticos = ac.getTyresName(indiceNeumaticosInicio)
        
        local carIndex = 0 -- Índice del coche actual (0 para el jugador)
        local indiceNeumaticosInicio = 0  -- Asumimos que este es el índice del neumático con el que debes iniciar

        -- Obtiene el nombre largo del neumático para el índice de inicio
        local nombreLargoNeumaticoInicio = ac.getTyresLongName(carIndex, indiceNeumaticosInicio) or "neumático desconocido"

        -- Mensaje para la ventana modal
        local mensajeNeumaticosInicio = "Recuerda que debes salir con el neumático " .. nombreLargoNeumaticoInicio

        -- Muestra la ventana modal con el mensaje
        ui.modalPopup(
            "Recordatorio de Neumáticos", -- Título de la ventana modal
            mensajeNeumaticosInicio, -- Mensaje a mostrar, ahora incluye el compuesto de neumáticos dinámico
            "OK", -- Texto del botón de OK
            "", -- Texto del botón de Cancelar, `nil` porque quizás no necesitemos uno
            nil, -- ID del ícono para el botón de OK, `nil` para no usar ícono
            nil, -- ID del ícono para el botón de Cancelar, `nil` para no usar ícono
            function(okPressed)
                if okPressed then
                    -- Acciones a realizar cuando el usuario presiona OK, si es necesario
                    ac.log("El usuario ha presionado OK en el recordatorio del neumático " .. nombreLargoNeumaticoInicio .. ".")
                end
            end
        )
    end

    -- Actualizar array
    actualizarTiempoDetenidoEnPitsTodasIAs(dt)
    -- Gestión de la sesión de carrera en vivo
    gestionarSolicitudesEntradaAPitsIAs()
    gestionarIAsEnPits()

    -- A PITS EN VUELTA OBLIGATORIA: Marcar si el jugador ha entrado a pits en la vuelta obligatoria o en las vueltas adyacentes
    if (ac.getCar(0).lapCount + 1 >= vueltaObligatoriaCambioNeumaticos - 1) and (ac.getCar(0).lapCount + 1 <= vueltaObligatoriaCambioNeumaticos + 1) and ac.getCar(0).isInPitlane then
        jugadorEntroAPitsEnVueltaObligatoria = true
    end

    -- COMPROBAR GOMAS INDICADAS DESPUÉS DE LA PARADA EN PITS
    if ac.getCar(0).lapCount + 1 > vueltaObligatoriaCambioNeumaticos and (jugadorEntroAPitsEnVueltaObligatoria or ac.getCar(0).lapCount >= vueltaObligatoriaCambioNeumaticos + 1) then
        if not ac.getCar(0).isInPitlane then
            local nombreCortoNeumaticos = ac.getTyresName(0, -1)
            if nombreCortoNeumaticos then
                local indiceNeumaticos = ac.getTyresIndex(0, nombreCortoNeumaticos)
                if indiceNeumaticos == indiceNeumaticosACambiar then
                    
                    if ac.getCar(0).lapCount <= vueltaObligatoriaCambioNeumaticos + 2 then
                        -- Mostrar mensaje y reproducir audio solo si aún no han pasado dos vueltas desde el cambio obligatorio                        
                        --ac.log("El jugador ha cambiado al compuesto de neumáticos correcto después de la parada en pits.")
                        mensajeActualParaPiloto = "LISTO, NO HAY MÁS PARADAS PROGRAMADAS."
                        imagenamostrar="ingeniero.png"
                        agregarMensajeACola(mensajeActualParaPiloto)
                            if mensajeFinalMostrado == true then

                                setTimeout(function()
                                    reproducirAudio('nomaspits.mp3',5)
                                end, 8) -- El retraso está en segundos
                            
                            mensajeFinalMostrado = true
                            end
                        -- Variable global para manejar si el mensaje final ya se mostró
                        if not mensajeFinalMostrado then
                            mensajeFinalMostrado = true
                        end
                    end
                else
                    -- Si el jugador no cambió al compuesto correcto, manejar como se requiera
                    ac.log("El jugador no ha cambiado al compuesto de neumáticos correcto después de la parada en pits. Debe cambiar a: " .. tostring(indiceNeumaticosACambiar))
                    
                    -- Verificar si el jugador está después de la última vuelta permitida
                    if ac.getCar(0).lapCount >= vueltaObligatoriaCambioNeumaticos + 1 then
                        -- Aplicar penalización de bandera negra
                        ac.log("El jugador no ha cambiado al compuesto de neumáticos correcto después de la última vuelta permitida.")
                        imagenamostrar="ingeniero.png"
                        mensajeActualParaPiloto = "DESCALIFICADO POR NO MONTAR EL COMPUESTO INDICADO POR EL EQUIPO."
                        agregarMensajeACola(mensajeActualParaPiloto)
                        physics.setCarPenalty(ac.PenaltyType.BlackFlag, -1)
                        ac.setSystemMessage("Penalización", "Has sido penalizado por no cambiar al compuesto de neumáticos indicado.")
                    end
                end
            else
                ac.log("No se pudo obtener el nombre corto del juego de neumáticos. No es posible verificar el compuesto.")
            end
        end
    end


    -- Verificar si el jugador está en pits y hay una avería activa
    if ac.getCar(0).isInPitlane and ventanaAveriaActiva and ac.getCar(i).speedKmh < 5 then
        -- Reparar el coche (restablecer los valores por defecto)
        physics.setCarEngineLife(0, 1000) -- Vida del motor al 100%
        physics.setCarRestrictor(0, 0) -- Eliminar restrictor
        physics.setCarBallast(0, 0) -- Eliminar lastre
        physics.setCarBodyDamage(0, {0, 0, 0, 0}) -- Eliminar daño en la carrocería
        physics.setTyresVirtualKM(0, 0, 0) -- Restaurar el desgaste de los neumáticos
        -- Ocultar la ventana de avería
        ocultarVentanaAveria()
        local msg = "VEHICULO REPARADO"
        local description = "TODO CORRECTO"

        ac.setSystemMessage(msg, description)
        ac.setFFBMultiplier(1) -- Restablecer el multiplicador de FFB
        imagenamostrar="ingeniero - copia.png"
        reproducirAudio('end.mp3',3)
        agregarMensajeACola(mensajeActualParaPiloto)
        ac.setSystemMessage(msg, description)
    end


end--final del if inicial donde miro si es carrera o no lo es.
end------FINAL DE FUNCION UPDATE




function mostrarVentanaAveria(mensaje)
    ventanaAveriaActiva = true
    local msg = "VEHICULO AVERIADO"
    local description = "! A BOXES YA !"
    --imagenamostrar="averia.png"
    --mensajeActualParaPiloto = "VEHICULO AVERIADO ! A BOXES YA ! ! A BOXES YA ! ! A BOXES YA !"
    agregarMensajeACola(mensajeActualParaPiloto)
    ac.setSystemMessage(msg, description)
    ui.toolWindow(windowId, windowPos, windowSize, true, false, function()
        ui.pushDWriteFont('Segoe UI;Weight=Bold')
        ui.dwriteText(mensaje, 24)
        ui.popDWriteFont()
        -- Aquí puedes agregar una imagen o bandera adicional que indique la urgencia de la reparación
        ui.image('averia.png', vec2(40, 40)) -- Ejemplo de imagen de bandera roja
    end)
end

function ocultarVentanaAveria()
    ventanaAveriaActiva = false
end

function actualizarEstadoDelJuego(dt)
    -- Asume que 'dt' es el delta de tiempo desde la última actualización
    ultimoTiempoDeActualizacion = ultimoTiempoDeActualizacion + dt
    
    -- Verificar la condición de última oportunidad para entrar a pits
    if not avisoUltimaOportunidadEmitido and (ac.getCar(0).lapCount == vueltaObligatoriaCambioNeumaticos) then
        if ultimoTiempoDeActualizacion >= intervaloDeActualizacion then
            mensajeActualParaPilotocierrepits = "OBLIGATORIO: A PITS EN ESTA VUELTA."
            imagenamostrar="ingeniero.png"
            agregarMensajeACola(mensajeActualParaPilotocierrepits)
            reproducirAudio('pitahora.mp3',9)
            avisoUltimaOportunidadEmitido = true
            mostrarMensajeVueltaObligatoria = true -- Establece la variable a true
            ultimoTiempoDeActualizacion = 0
        end
    end
    -- Asegúrate de restablecer 'avisoUltimaOportunidadEmitido' después de que el jugador entre a pits o cuando sea relevante
    -- (por ejemplo, si el jugador entra a pits o al iniciar una nueva carrera)
end

function script.windowMain(dt)

    ui.image(imagenamostrar, vec2(85, 85))  -- Ajusta (100, 100) al tamaño deseado.        
    if not mensajeFinalMostrado then
        -- Obtener el nombre largo del compuesto de neumáticos al que debe cambiar el jugador
        local nombreNeumaticosACambiar = ac.getTyresName(0, indiceNeumaticosACambiar)
        if not nombreNeumaticosACambiar then
            nombreNeumaticosACambiar = "desconocido"  -- En caso de que no se pueda obtener el nombre, usar un valor por defecto
        end        
    end
    ui.pushDWriteFont('Segoe UI;Weight=Bold')
    ui.sameLine()
    ui.dwriteText("    " .. string.upper(mensajeActualParaPiloto), 24)
    ui.popDWriteFont()



      -- Show Flag Circles
    if activeFlag == 0 then  -- None
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(0,0,0,1),32)
        limpiarColaDeMensajes()
    elseif activeFlag == 1 then -- Green
        --ui.drawRectFilled(vec2(30,38),100,rgbm(0,1,0,1),62)
        --ui.drawRectFilled(0,1110, rgbm(0,1,0,1),0, 0)
    
    elseif activeFlag == 2 then -- Yellow
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(1,1,0,1),32)
        mensajeActualParaPiloto = ""
        
        agregarMensajeACola(mensajeActualParaPiloto)
        ui.drawRectFilled(0,4110, rgbm(1,1,0,1),0, 0)

    elseif activeFlag == 12 then -- Blue
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(0,0,1,1),32)
        mensajeActualParaPiloto = ""
        agregarMensajeACola(mensajeActualParaPiloto)
        ui.drawRectFilled(0,4110, rgbm(0,0,1,1),0, 0)
    
    elseif activeFlag == 13 then -- Checkered
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(1,1,1,1),32)

    elseif activeFlag == 13 then -- Checkered
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(1,1,1,1),32)


    else
        --ui.drawCircleFilled(vec2(30,38),15,rgbm(0,0,0,0.7),32)
        

    end


    -- -- ID único para la ventana
    -- local windowId = "NumeroDeCortesDeVuelta"
    -- -- Posición de la ventana (ajusta según tus necesidades)
    -- local windowPos = vec2(50, 100) -- Ejemplo: en la parte superior derecha
    -- -- Tamaño de la ventana (ajusta según tus necesidades)
    -- local windowSize = vec2(1920, 100) -- Suficiente para mostrar el mensaje

    -- ui.transparentWindow(windowId, windowPos, windowSize, true, false, function()
    --     --ui.image(imagenamostrar, vec2(85, 85)) 
    --     -- Asumiendo que 'lapCutsCount' es la variable que tiene el número actual de cortes        
    --     local mensaje = "direccion: " .. ac.getCar(0).compass
    --     -- Configura el estilo de la fuente si es necesario
    --     ui.pushDWriteFont('Segoe UI;Weight=Bold')
    --     -- Muestra el mensaje. Ajusta el tamaño y posición según sea necesario
    --     ui.dwriteText(mensaje, 24)
    --     --ui.dwriteText("    " .. string.upper(mensajeActualParaPiloto), 24)
    --     ui.popDWriteFont()
    -- end)

end

-- Runs once per frame on to update Window Icon


--------------------------------------------REPRODUCCION DE AUDIOS EN COLA--------------------------------------------------

-- La función de temporizador para manejar la cola de reproducción.
local function temporizadorReproduccion(nombreArchivo, reproductor)
    setTimeout(function()
        audiosReproducidos[nombreArchivo] = nil
        -- Aquí puedes llamar a la función que verifica si hay más audios en la cola y reproduce el siguiente.
        reproducirSiguiente() 
    end, reproductor:getLength()) -- Utiliza la duración del archivo de audio si es posible obtenerla.
end

-- La función para reproducir el siguiente audio en la cola.
function reproducirSiguiente()
    -- Verifica si hay audios en la cola y no se está reproduciendo nada actualmente.
    if not reproduciendo and #colaReproduccion > 0 then
        -- Obtiene el siguiente archivo de audio de la cola.
        local nombreArchivo = table.remove(colaReproduccion, 1)
        local reproductor = ui.MediaPlayer(ac.getFolder(ac.FolderID.ScriptOrigin) .. '/' .. nombreArchivo)
        reproductor:setVolume(0.5) -- Ajusta el volumen.
        reproductor:play() -- Inicia la reproducción.
        audiosReproducidos[nombreArchivo] = true -- Marca el audio como reproducido.

        -- Configura el temporizador basado en la duración estimada del audio.
        temporizadorReproduccion(nombreArchivo, reproductor)
    end
end

-- La función para añadir un audio a la cola y reproducir si es posible.
function reproducirAudio(nombreArchivo, duracion)
    -- Verifica si el archivo actual es diferente al último reproducido
    if nombreArchivo ~= ultimoAudioReproducido then
        if audioActual == nil then
            -- No hay ningún audio reproduciéndose actualmente, así que reproduce el archivo
            local reproductor = ui.MediaPlayer(ac.getFolder(ac.FolderID.ScriptOrigin) .. '/' .. nombreArchivo)
            reproductor:setVolume(0.5)
            reproductor:play()
            audioActual = nombreArchivo
            ultimoAudioReproducido = nombreArchivo -- Actualiza el último audio reproducido

            -- Establece un temporizador para marcar el audio como no reproducido después de que finalice
            setTimeout(function()
                audioActual = nil
            end, duracion)
        end
    end
end

function reproducirNumeroComoAudio(numero)
    -- Convertir el número a cadena para iterar sobre cada carácter
    local numeroComoCadena = tostring(numero)
    -- Redondear el número entero hacia abajo para identificar el archivo de la carpeta específica
    local parteEntera = math.floor(numero)
    local rutaArchivoEntero = "numbers/" .. tostring(parteEntera) .. "/1.wav"
    
    -- Reproducir la parte entera del número
    reproducirAudio(rutaArchivoEntero, 0) -- Asumiendo que cada audio dura 1 segundo
    
    -- Verificar si hay parte decimal
    if numeroComoCadena:find('%.') then
        -- Reproducir el sonido para el punto decimal
        reproducirAudio("numbers/point/1.wav", 0)
        
        -- Iterar sobre la parte decimal del número
        local inicioDecimal = numeroComoCadena:find('%.') + 1
        for i = inicioDecimal, #numeroComoCadena do
            local caracter = numeroComoCadena:sub(i, i)
            local rutaArchivoDecimal = "numbers/" .. caracter .. "/1.wav"
            
            -- Reproducir cada dígito de la parte decimal
            reproducirAudio(rutaArchivoDecimal, 0)
        end
    end
end

function reproducirPosicionAudio(posicion)
    setTimeout(function()
        limpiarColaDeMensajes()
        reproducirAudio("posicion.mp3", 1.5)
        setTimeout(function()
            reproducirNumeroComoAudio(posicion)
        end, 2) -- El retraso está en segundos
    end, 5) -- El retraso está en segundos
end

-- function asignarNeumaticosInicialesIA()
--     if not neumaticosAsignados then
--         for i = 1, conteoIAs do
--             -- Asignar un compuesto de neumáticos aleatorio entre 0 y 1 para cada IA.
--             local indiceNeumaticosAleatorio = math.random(0, 1)
--             physics.setAITyres(i, indiceNeumaticosAleatorio)

--             -- Almacenar el compuesto de neumáticos inicial en la tabla compuestosSalidaIA.
--             compuestosSalidaIA[i] = indiceNeumaticosAleatorio
--             --ac.log("Coche: " .. i .. " set starting tyre index: " .. indiceNeumaticosAleatorio)
--         end
--         neumaticosAsignados = true -- Establecer la variable de control a true después de la asignación.
--     end
-- end

function asignarNeumaticosInicialesIA()
    if not neumaticosAsignados then
        local conteoNeumaticos = {}
        local nombresNeumaticos = {}

        for i = 1, conteoIAs do
            local indiceNeumaticosAleatorio = math.random(0, 1)
            physics.setAITyres(i, indiceNeumaticosAleatorio)
            compuestosSalidaIA[i] = indiceNeumaticosAleatorio
            conteoNeumaticos[indiceNeumaticosAleatorio] = (conteoNeumaticos[indiceNeumaticosAleatorio] or 0) + 1
            if not nombresNeumaticos[indiceNeumaticosAleatorio] then
                nombresNeumaticos[indiceNeumaticosAleatorio] = ac.getTyresLongName(0, indiceNeumaticosAleatorio)
            end
        end

        neumaticosAsignados = true

        local partesMensaje = {}
        for indiceNeumatico, cantidad in pairs(conteoNeumaticos) do
            if cantidad > 0 then
                table.insert(partesMensaje, "" .. cantidad .. " rivales salen con neumaticos " .. nombresNeumaticos[indiceNeumatico])
            end
        end
        local mensajeActualParaPiloto = table.concat(partesMensaje, " y ") .. "."
        agregarMensajeACola(mensajeActualParaPiloto)
    end
end


function establecerEstrategiasParadaIAs()
    -- Define las estrategias de pits para la IA
    for i = 1, conteoIAs, 1
    do
        estrategiasParadaIAs[i] = math.random(vueltaObligatoriaCambioNeumaticos - 1, vueltaObligatoriaCambioNeumaticos + 1) -- Cada IA entrará en pits en una vuelta aleatoria entre 2 y 4
    end
end

function gestionarSolicitudesEntradaAPitsIAs()
    -- Gestiona las solicitudes de entrada a pits de la IA
    for i = 1, conteoIAs, 1
    do
        if (ac.getCar(i).lapCount + 1) == estrategiasParadaIAs[i] and ac.getCar(i).lapTimeMs < 1000 and ac.getCar(i).speedKmh > 1 then  -- 1s = 1000ms
            physics.setAIPitStopRequest(i, true)
            --ac.log("Coche: " .. i .. " requests a pit")
        end
    end
end

function definirTiemposParadaEnPitsParaCambioNeumaticosIA()
    -- Define los tiempos de parada en pits para cada IA
    for i = 1, conteoIAs, 1
    do
        --tiempoParadaEnPitsParaCambioNeumaticosIA[i] = tiempoEsperadoCambioNeumaticos
        tiempoDetenidoEnPitsIA[i] =tiempoEsperadoCambioNeumaticos
    end
end

function actualizarTiempoDetenidoEnPitsTodasIAs(dt)
    -- Actualiza el tiempo que cada conductor permanece detenido en pits
    for i = 1, conteoIAs, 1
    do
        if ac.getCar(i).isInPitlane == true and ac.getCar(i).speedKmh < 5 then
            tiempoDetenidoEnPitsIA[i] = tiempoDetenidoEnPitsIA[i] + dt
        else
            if ac.getCar(i).isInPitlane == false and tiempoDetenidoEnPitsIA[i] == nil then
                tiempoDetenidoEnPitsIA[i] = 0
            end
        end
    end
end

-- function gestionarIAsEnPits()  ---PARECE FUNCIONAR CON CSP 2.0 PERO CREO QUE CON 2.1 NO FUNCIONABA
--     -- Controla el comportamiento de la IA en pits
--     for i = 1, conteoIAs, 1 do
--         if ac.getCar(i).isInPit then
--             -- Determinar el neumático opuesto al compuesto de salida
--             local neumaticoSalida = compuestosSalidaIA[i]
--             local nuevoIndiceNeumaticos = (neumaticoSalida == 0) and 1 or 0  -- Cambia al otro tipo de neumático.
--             physics.setAITyres(i, nuevoIndiceNeumaticos)
--             --ac.log("Coche: " .. i .. " changed to tyre index: " .. nuevoIndiceNeumaticos)
--             physics.setGentleStop(i, false)  -- Reanuda el movimiento de la IA después del cambio de neumáticos.
--         end
--     end
-- end

function gestionarIAsEnPits()
    -- Controla el comportamiento de la IA en pits
    for i = 1, conteoIAs, 1 do
        if ac.getCar(i).isInPit then
            -- Verificar si el tiempo detenido en pits es suficiente
            if tiempoDetenidoEnPitsIA[i] >= tiempoEsperadoCambioNeumaticos then
                -- Determinar el neumático opuesto al compuesto de salida
                local neumaticoSalida = compuestosSalidaIA[i]
                local nuevoIndiceNeumaticos = (neumaticoSalida == 0) and 1 or 0  -- Cambia al otro tipo de neumático.
                physics.setAITyres(i, nuevoIndiceNeumaticos)
                --ac.log("Coche: " .. i .. " changed to tyre index: " .. nuevoIndiceNeumaticos)
                physics.setGentleStop(i, false)  -- Reanuda el movimiento de la IA después del cambio de neumáticos.
                tiempoDetenidoEnPitsIA[i] = 0 -- Reinicia el tiempo detenido en pits después del cambio de neumáticos
            end
        end
    end
end



function comprobarRoturaCoche()
    if not cocheRoto and math.random(1, 100) <= 3 then --porcentaje de probabilidad de averia
        cocheRoto = true
        local averia = math.random(1, 10) -- Selecciona una avería al azar de la lista
        mensajeActualParaPiloto = ""
        agregarMensajeACola(mensajeActualParaPiloto)

        if averia == 1 then
            physics.setCarEngineLife(0, 600) -- Deja el motor al 60% de su vida útil.
            imagenamostrar = "averia_0005_005-piston.png"
            mensajeActualParaPiloto = "PROBLEMA GRAVE: Sobrecalentamiento del motor detectado, motor al 60%. Entra en pits a reparar."
            reproducirAudio('danosleves.mp3',7)
        elseif averia == 2 then
            physics.setCarRestrictor(0, 50) -- Aplica un restrictor del 50%.
            imagenamostrar = "averia_0000_010-turbo-engine.png"
            mensajeActualParaPiloto = "ALERTA: Fallo en el sistema de turbo detectado. Motor al 50%. Necesitamos reparaciones urgentes."
            reproducirAudio('danosgraves.mp3',10)
        elseif averia == 3 then
            physics.setCarBallast(0, 1500) -- Añade lastre.
            imagenamostrar = "averia_0007_003-gears.png"
            mensajeActualParaPiloto = "ATENCIÓN: Problemas en la caja de cambios. Debemos reparar. Por favor, regresa a boxes."
            reproducirAudio('danosgraves.mp3',10)
        elseif averia == 4 then
            physics.setCarBodyDamage(0, {45, 45, 0, 0}) -- Daño frontal y trasero.
            imagenamostrar = "averia_0008_002-engine-oil.png"
            mensajeActualParaPiloto = "AVISO: Detectada una fuga de líquido. Debe haber fallos mecánicos. Deberíamos revisar el coche."
            reproducirAudio('danosleves.mp3',7)
        elseif averia == 5 then
            physics.setCarRestrictor(0, 60) -- Aplica un restrictor del 20%.
            imagenamostrar = "averia_0009_001-brake.png"
            mensajeActualParaPiloto = "URGENTE: Fallos en el sistema de frenos. La electrónica del coche está en estado de protección, regresa a boxes."
            reproducirAudio('danosgraves.mp3',8)
        elseif averia == 6 then
            physics.setTyresVirtualKM(0, 60, 500) -- Desgaste acelerado de neumáticos.
            imagenamostrar = "averia_0004_006-fan.png"
            mensajeActualParaPiloto = "PROBLEMA: Neumático reventado. Tu carrera ha terminado."
            reproducirAudio('danosseveros.mp3',8)
        elseif averia == 7 then
            physics.setCarBodyDamage(0, {0, 0, 50, 50}) -- Daño lateral.
            imagenamostrar = "averia_0003_007-oil.png"
            mensajeActualParaPiloto = "NOTIFICACIÓN: Desgaste de neumáticos anormalmente rápido. Daños significativos en gomas. Considera un cambio de neumáticos."
            reproducirAudio('danosleves.mp3',10)
        elseif averia == 8 then
            physics.setCarEngineLife(0, 980) -- Motor al 98% de su capacidad.
            imagenamostrar = "averia_0002_008-battery.png"
            mensajeActualParaPiloto = "ADVERTENCIA: Batería baja o fallos de arranque. Vida del motor al 98%. Es posible que necesites asistencia."
            reproducirAudio('danosgraves.mp3',7)
        elseif averia == 9 then
            physics.setCarBallast(0, 900) -- Añade 500 kg de lastre.
            imagenamostrar = "averia_0006_004-chain.png"
            mensajeActualParaPiloto = "PRECAUCIÓN: Pérdida de potencia detectada. Podría haber un problema serio."
            reproducirAudio('danosgraves.mp3',10)
        elseif averia == 10 then
            physics.setCarRestrictor(0, 60) -- Aplica un restrictor del 60%.
            imagenamostrar = "averia_0005_005-piston.png"
            mensajeActualParaPiloto = "ALERTA MÁXIMA: Sistema de escape dañado. Esto afecta directamente al rendimiento."
            reproducirAudio('danosgraves.mp3',8)
        end

        agregarMensajeACola(mensajeActualParaPiloto)
        mensajedeaveria = mensajeActualParaPiloto
        mostrarVentanaAveria()
    end
end

-------COMIENZO DE LAS FUNCIONES DEL VSC---------------------------------------------------------------------------------------------------

        -- Función para actualizar el temporizador de VSC
function actualizarTemporizadorVSC(dt)
    if isVSCActive and vscTimerActive then
        vscTimer = vscTimer + dt
        if vscTimer >= gracePeriod then
        -- Antes de finalizar el VSC, verifica si el jugador adelantó
        verificarPosicionJugadorYAplicarPenalizacion()  
        -- Finaliza el VSC
        finalizarVSC()
        end
    end
end
  
  -- Función para verificar la posición del jugador y aplicar penalización si adelantó durante el VSC
  function verificarPosicionJugadorYAplicarPenalizacion()
    local posicionActual = ac.getCar(0).racePosition
    -- Usamos mejorPosicionObjetivoVSC para verificar si el jugador adelantó ilegalmente
        if posicionActual < mejorPosicionObjetivoVSC then
            -- El jugador ha adelantado durante el VSC, aplicar penalización
            ac.log("El jugador adelantó durante el VSC. Aplicando bandera negra.")
            agregarMensajeACola("VSC: ADELANTASTE POSICIONES DURANTE EL VSC. BANDERA NEGRA.")
            physics.setCarPenalty(ac.PenaltyType.BlackFlag, 0)
        end
    end
  
  -- Función para finalizar el VSC
  function finalizarVSC()
      isVSCActive = false
      vscTimerActive = false
      vscTimer = 0 -- Opcional, si quieres resetear el temporizador
      ajustarVelocidadIA(500) -- Restablece la velocidad máxima de IA
      settings.autopilot.Agression = 50
      for i = 0, carsCount - 1 do
        local car = ac.getCar(i)
        posicionesEnVSC[i+1] = car.racePosition
        physics.setAIAggression(i, settings.autopilot.Agression / 100)
        end
      reproducirAudio('scfin.mp3', 6)
      agregarMensajeACola("VSC: VIRTUAL SAFETY CAR FINALIZADO. CARRERA LIBRE.                                             ")
      
  end
  
   -- Función para ajustar la velocidad máxima de los coches IA, esta función simple funciona bien para mantener a todos en  x/kmh
   function ajustarVelocidadIA(velocidad)
     local carsCount = ac.getSim().carsCount
     for i = 0, carsCount - 1 do
         physics.setAITopSpeed(i, velocidad)
     end
   end


    -- -- Función para detectar colisiones DE TODOS LOS COCHES DE LA PARRILLA y activar el VSC 
    -- function verificarYActivarVSC() 
    --     local carsCount = ac.getSim().carsCount 
    --     --ac.log(ac.getCarByDriverName("VRS-TV")) con esto veo que el index de mi coche es el 0
    --     for i = 0, carsCount - 1 do 
    --         local car = ac.getCar(i) 
    --         local collisionDepthChange = car.collisionDepth - (prevCollisionDepth[i+1] or 0) 
    --         local hitValueChange = HitValue - (prevHitValue[i+1] or 0) 
    --         if (collisionDepthChange > 0 or hitValueChange > 0) and car.collidedWith ~= 0 and car.speedKmh > 100 then
    --             if i ==0 then -- Si es tu coche (índice 0)
    --             activarVSC(car)
    --             end
    --         end -- Actualiza los valores previos para la próxima verificación 
    --         prevCollisionDepth[i+1] = car.collisionDepth 
    --         prevHitValue[i+1] = HitValue 
    --     end 
    -- end

     
    --  function verificarmurosYActivarVSC() -- Función para detectar colisiones DE MI PROPIO COCHE contra el muro, y saco vsc 
    --      local carsCount = ac.getSim().carsCount 
    --      --ac.log(ac.getCarByDriverName("VRS-TV")) con esto veo que el index de mi coche es el 0
    --      for i = 0, carsCount - 1 do 
    --          local car = ac.getCar(i) 
    --          --local collisionDepthChange = car.collisionDepth - (prevCollisionDepth[i+1] or 0) 
    --          --local hitValueChange = HitValue - (prevHitValue[i+1] or 0) 
    --          if car.collidedWith == 0  then
    --              if i ==0 then -- Si es tu coche (índice 0)
    --             ac.log("ostia contra el muro")
    --              activarVSC(car)
    --              end
    --          end -- Actualiza los valores previos para la próxima verificación 
    --          prevCollisionDepth[i+1] = car.collisionDepth 
    --          --prevHitValue[i+1] = HitValue 
    --      end 
    --  end

    function verificarmurosYActivarVSC()
        local carsCount = ac.getSim().carsCount
        for i = 0, carsCount - 1 do
            local car = ac.getCar(i)
            if car.collidedWith == 0 then -- Si el coche colisionó con un muro
                if i == 0 and car.speedKmh > 70 and colisionPreviaConCoche then -- Verifica si es tu coche, si va a más de 70 km/h y si hubo una colisión previa con otro coche
                    ac.log("Impacto contra el muro a más de 70km/h después de una colisión previa con otro coche. Activando VSC.")
                    activarVSC(car)
                    colisionPreviaConCoche = false -- Opcional: Resetear el estado de colisión previa si así lo deseas después de activar el VSC
                end
            end
            -- Actualiza los valores previos para la próxima verificación
            prevCollisionDepth[i+1] = car.collisionDepth
        end
    end
    

  
  -- Función para activar el VSC
  function activarVSC(car)
    reproducirAudio('sc.mp3', 9) 
    imagenamostrar="sc.gif"
    
    isVSCActive = true
    vscTimerActive = true
    vscTimer = 0 -- Reinicia el temporizador
    --playerPositionAtVSC = ac.getCarLeaderboardPosition(0)
    playerPositionAtVSC = ac.getCar(0).racePosition
    ajustarVelocidadIA(velocidadiaenvsc)

    --ac.log("mantén la posición, VSC de 100 km/h.")
    isVSCActive = true
    posicionesEnVSC = {}
    playerPositionAtVSC = ac.getCar(0).racePosition
    mejorPosicionObjetivoVSC = playerPositionAtVSC -- Inicializa con la posición actual del jugador
    local carsCount = ac.getSim().carsCount
    settings.autopilot.Agression = 1

    for i = 0, carsCount - 1 do
        local car = ac.getCar(i)
        posicionesEnVSC[i+1] = car.racePosition
        physics.setAIAggression(i, settings.autopilot.Agression / 100)
    end
  end


--COLA DE MENSAJES 


    function limpiarColaDeMensajes()
        colaDeMensajes = {} -- Reinicia la cola de mensajes a una lista vacía
    end
    -- Función para agregar mensajes a la cola
    function agregarMensajeACola(mensaje)
        -- Verificar si el mensaje ya está en cola
        for _, msg in ipairs(colaDeMensajes) do
            if msg == mensaje then
                return -- Si el mensaje ya está en cola, no hacer nada
            end
        end
        table.insert(colaDeMensajes, mensaje)
    end

    -- Función para actualizar y mostrar mensajes
    function actualizarYMostrarMensaje(dt)
        if mensajeMostrando and #colaDeMensajes > 0 then
            tiempoMensaje = tiempoMensaje + dt
            if tiempoMensaje >= duracionMensaje then
                -- Tiempo de mostrar el mensaje actual ha terminado, mostrar el siguiente mensaje
                table.remove(colaDeMensajes, 1) -- Elimina el mensaje mostrado de la cola
                tiempoMensaje = 0 -- Reinicia el contador de tiempo
                mensajeMostrando = false
            end
        end
        if not mensajeMostrando and #colaDeMensajes > 0 then
            -- Hay mensajes en la cola y ninguno se está mostrando
            mensajeActualParaPiloto = colaDeMensajes[1] -- Toma el primer mensaje de la cola
            mensajeMostrando = true -- Marca que hay un mensaje mostrándose
        end
    end  



-----------------------------------------------------DETECTAR CAMBIOS DE SESIÓN----------------------------------------------
    function reiniciarEstado()
        -- Reiniciar variables globales
        ac.log("REINICIANDO TODO")
         ultimaReproduccion = 0
         tiempoEntreReproduccion = 30
         vueltaObligatoriaCambioNeumaticos = 3
         indiceNeumaticosInicio = 0
         indiceNeumaticosACambiar = 1
         tiempoEsperadoCambioNeumaticos = 20.8
         compuestosSalidaIA = {}
         aiTakePlayersFuel = false
         aiDriverCount = 0
         velocidadiaenvsc = 100
         intervaloComprobacion = 180
         activeFlag = nil
        colisionPreviaConCoche = false
         tieneDT = false
         cortesDespuesDeDT = 0
         ultimoCorteRegistrado = -1
         ventanaAveriaActiva = false
         windowId = "VentanaAveria"
         windowPos = vec2(200, 200)
         windowSize = vec2(400, 200)
         neumaticosVerificados = false
         velocidadParaVerificarNeumaticos = 80
         mensajeFinalMostrado = false
         mostrarMensajeFinal = false
         mensajeActualParaPiloto = ""
         jugadorEntroAPitsEnVueltaObligatoria = false
         audiosReproducidos = {}
         audiosReproducidos = {}
         audioActual = nil 
         tiempoInicioAudio = 0
         duracionAudio = 0
         colaReproduccion = {}
         reproduciendo = false
         audioAnterior = nil
         conteoIAs = 0
         primeraVez = true
         estrategiasParadaIAs = {}
         tiempoParadaEnPitsParaCambioNeumaticosIA = {}
         tiempoDetenidoEnPitsIA = {}
         neumaticosInicialesIA = {}
         neumaticosAsignados = false
         tiempoUltimaComprobacion = 0
         cocheRoto = false
         mensajedeaveria =""
         avisoUltimaOportunidadEmitido = false
         ultimoTiempoDeActualizacion = 0
        intervaloDeActualizacion = 1.0
        startTime = nil
         mostrarMensajeVueltaObligatoria = false
         ultimoAudioReproducido = nil
         prevCollisionDepth = 0
         prevCollisionDepth = {}
         prevHitValue = {}
         HitValue = 0
         carsCount = ac.getSim().carsCount
            for i = 1, carsCount do
                prevCollisionDepth[i] = 0
                prevHitValue[i] = 0
            end
        isVSCActive = false
        playerPositionAtVSC = nil
        vscTimer = 0
        vscTimerActive = false
        vscActivationTime = nil
        gracePeriod = 50
         tiempoTranscurridoVSC = 0
         imagenamostrar ="ingeniero.png"
         muestra1 = nil
         ultimoTiempo = os.clock()
         accidenteReciente = false        
        posicionesEnVSC = nil
        playerPositionAtVSC = 0
        isVSCActive = false
        mejorPosicionObjetivoVSC = nil
         mensajeActualParaPilotocierrepits =""
         colaDeMensajes = {}
         mensajeMostrando = false
         tiempoMensaje = 3
         duracionMensaje = 0.01
         settings = {
            autopilot = {enabled = true, Speed = 100, Agression = 100, Pitnow = false},
            initialized = false,
            timerStarted = false,
            timer = 0
          }
          settings.timerStarted = true
          settings.timer = 0
         sessionRestarted = false
        -- Limpiar colas de mensajes
        limpiarColaDeMensajes()
end
-----------------------------------------------------DETECTAR CAMBIOS DE SESIÓN----------------------------------------------

local function onSessionStart(sessionIndex, restarted)
    if restarted then
      -- Las siguientes líneas se moverían al callback de `ac.startBackgroundWorker`
      local msg = "Salir del juego"
      local description = "! Nos vemos pronto !"
      ac.setSystemMessage(msg, description)
    end
end

  -- Establecer el callback de inicio de sesión
  ac.onSessionStart(onSessionStart)
  --ac.onSessionStart(function(sessionIndex, restarted)
    ac.log("---------------------------")
    ac.log("Session Restart occured")
    sessionRestarted = true;
  --end)