DoomsdayNight = DoomsdayNight or {}
DoomsdayNight.active = false
DoomsdayNight.start_time = 0
DoomsdayNight.participants = {}
DoomsdayNight.spectators = {}
DoomsdayNight.spawn_positions = {}

DoomsdayNight.weapons = {
    "tfa_ins2_ak74", "tfa_ins2_m4a1", "tfa_ins2_ak12", "tfa_ins2_m16a4", "tfa_ins2_scar_h_ssr",
    "tfa_ins2_m40a1", "tfa_ins2_mosin", "tfa_ins2_svd", "tfa_ins2_m590", "tfa_ins2_toz",
    "tfa_ins2_glock_17", "tfa_ins2_m9", "tfa_ins2_makarov", "tfa_ins2_mp5", "tfa_ins2_ump45", "tfa_ins2_mp40"
}

util.AddNetworkString("doomsday_night_notification")
util.AddNetworkString("doomsday_night_hud_update")

function DoomsdayNight:Init()
    SetGlobalBool("doomsday_night_active", false)
    SetGlobalInt("doomsday_night_start_time", 0)
    SetGlobalInt("doomsday_night_alive_count", 0)
    self:GenerateSpawnPositions()
end

function DoomsdayNight:GenerateSpawnPositions()
    local map = game.GetMap()
    local map_positions = {
        ["gm_construct"] = {
            Vector(980, -1500, -79), Vector(-700, 1000, 200), Vector(1500, 800, 100), Vector(-1200, -800, 50)
        },
        ["rp_valkyrie_forest_v1"] = {
            Vector(5000, 3000, 200), Vector(-5000, -3000, 150), Vector(8000, -2000, 100), Vector(-8000, 2000, 180)
        }
    }
    self.spawn_positions = map_positions[map] or { Vector(1000, 1000, 100), Vector(-1000, -1000, 100) }
end

function DoomsdayNight:StartEvent(ply)
    local players = player.GetAll()
    if (#players < 2) then
        ply:Notify("Недостаточно игроков для начала Судной Ночи!")
        return
    end

    self.active = true
    self.start_time = CurTime()
    self.participants = {}
    self.spectators = {}
    
    SetGlobalBool("doomsday_night_active", true)
    SetGlobalInt("doomsday_night_start_time", CurTime())

    for _, player in ipairs(players) do
        if (IsValid(player)) then self:PreparePlayer(player) end
    end

    self:BroadcastMessage("🌙 СУДНАЯ НОЧЬ НАЧАЛАСЬ! 🌙\nСражайтесь до последнего выжившего!\nВыдано случайное оружие.")
    
    timer.Simple(3, function() if (self.active) then self:TeleportPlayers() end end)
    self:UpdateHUD()
end

function DoomsdayNight:PreparePlayer(ply)
    local steamid = ply:SteamID()
    self.participants[steamid] = {
        start_pos = ply:GetPos(),
        join_time = CurTime(),
        kills = 0,
        nick = ply:Nick(),
        alive = true
    }
    ply:StripWeapons()
    self:GiveRandomWeapons(ply)
end

function DoomsdayNight:GiveRandomWeapons(ply)
    if (!IsValid(ply) or !ply:Alive()) then return end
    ply:Give("ix_hands")
    
    local weapons_to_give = {}
    local used = {}
    for i = 1, math.random(2, 3) do
        local w = self.weapons[math.random(1, #self.weapons)]
        if (!used[w]) then
            used[w] = true
            table.insert(weapons_to_give, w)
        end
    end

    for _, w_class in ipairs(weapons_to_give) do
        local weapon = ply:Give(w_class)
        if (IsValid(weapon)) then
            ply:GiveAmmo(500, weapon:GetPrimaryAmmoType(), true)
        end
    end
    
    ply:Give("weapon_frag")
    ply:GiveAmmo(2, "Grenade", true)
    ply:SetHealth(100)
    ply:SetArmor(100)
end

function DoomsdayNight:TeleportPlayers()
    local players = {}
    for steamid, data in pairs(self.participants) do
        local ply = player.GetBySteamID(steamid)
        if (IsValid(ply)) then table.insert(players, ply) end
    end

    local positions = table.Copy(self.spawn_positions)
    for i, ply in ipairs(players) do
        local spawn_pos = positions[((i - 1) % #positions) + 1]
        ply:SetPos(spawn_pos)
        ply:SetEyeAngles(Angle(0, math.random(0, 360), 0))
    end
    
    SetGlobalInt("doomsday_night_alive_count", #players)
    self:BroadcastMessage("⚡ Игроки телепортированы! К БОЮ!")
end

function DoomsdayNight:EndEvent(ply, cancelled)
    if (!self.active) then return end
    self.active = false
    SetGlobalBool("doomsday_night_active", false)
    
    for steamid, _ in pairs(self.spectators) do
        local spec_ply = player.GetBySteamID(steamid)
        if (IsValid(spec_ply)) then
            spec_ply:UnSpectate()
            spec_ply:Spawn()
        end
    end

    self:BroadcastMessage(cancelled and "🛑 СУДНАЯ НОЧЬ ОТМЕНЕНА" or "🏆 СУДНАЯ НОЧЬ ЗАВЕРШЕНА")
    self.participants = {}
    self.spectators = {}
    self:UpdateHUD()
end

function DoomsdayNight:OnPlayerKilled(victim, attacker)
    if (!self.active) then return end
    local data = self.participants[victim:SteamID()]
    if (!data) then return end

    data.alive = false
    if (IsValid(attacker) and attacker:IsPlayer()) then
        local attacker_data = self.participants[attacker:SteamID()]
        if (attacker_data) then attacker_data.kills = attacker_data.kills + 1 end
    end

    timer.Simple(2, function()
        if (IsValid(victim)) then
            self.spectators[victim:SteamID()] = true
            victim:Spectate(OBS_MODE_ROAMING)
            victim:Notify("👁️ Вы перешли в режим наблюдения до конца ивента.")
        end
    end)

    local alive_count = 0
    for _, d in pairs(self.participants) do
        if (d.alive) then alive_count = alive_count + 1 end
    end
    SetGlobalInt("doomsday_night_alive_count", alive_count)

    if (alive_count <= 1) then
        timer.Simple(3, function() if (self.active) then self:EndEvent() end end)
    end
end

function DoomsdayNight:BroadcastMessage(msg)
    for _, ply in ipairs(player.GetAll()) do ply:ChatPrint(msg) end
end

function DoomsdayNight:UpdateHUD()
    net.Start("doomsday_night_hud_update")
        net.WriteBool(self.active)
        net.WriteInt(self.start_time, 32)
    net.Broadcast()
end

-- Hook aliases for PLUGIN
function PLUGIN:DoomsdayNight_Init() DoomsdayNight:Init() end
function PLUGIN:DoomsdayNight_PlayerDeath(victim, inflictor, attacker) DoomsdayNight:OnPlayerKilled(victim, attacker) end

hook.Add("InitPostEntity", "DoomsdayNight_Init", function() DoomsdayNight:Init() end)
