CreateCharacter = {}

local window = nil
local sexGroup = nil
local vocationGroup = nil
local selectedSex = 1
local selectedVocation = 1

local DEFAULT_VOCATIONS = {
    { id = 1, name = 'Sorcerer' },
    { id = 2, name = 'Druid' },
    { id = 3, name = 'Paladin' },
    { id = 4, name = 'Knight' },
}

local DEFAULT_GENDERS = {
    { id = 1, name = 'Male' },
    { id = 0, name = 'Female' },
}

local function clearPanel(panel)
    if not panel then
        return
    end
    while panel:getChildCount() > 0 do
        local child = panel:getChildByIndex(1)
        panel:removeChild(child)
        child:destroy()
    end
end

local function buildRadioGroup(panel, items, isSex)
    clearPanel(panel)
    local group = UIRadioGroup.create()
    local first = nil
    for _, item in ipairs(items) do
        local box = g_ui.createWidget('CheckBox', panel)
        box:setText(tostring(item.name or item.Name or ''))
        box:setHeight(20)
        box.optionId = item.id or item.Id
        group:addWidget(box)
        if not first then
            first = box
        end
    end
    if first then
        group:selectWidget(first)
        if isSex then
            selectedSex = first.optionId
        else
            selectedVocation = first.optionId
        end
    end
    group.onSelectionChange = function(_, selected)
        if not selected then
            return
        end
        if isSex then
            selectedSex = selected.optionId
        else
            selectedVocation = selected.optionId
        end
    end
    return group
end

local function normalizeVocations(list)
    if type(list) ~= 'table' or #list == 0 then
        return DEFAULT_VOCATIONS
    end
    local out = {}
    for _, item in ipairs(list) do
        table.insert(out, {
            id = item.id or item.Id or item.vocationId,
            name = item.name or item.Name or item.vocationName or tostring(item.id or '')
        })
    end
    return #out > 0 and out or DEFAULT_VOCATIONS
end

local function normalizeGenders(list)
    if type(list) ~= 'table' or #list == 0 then
        return DEFAULT_GENDERS
    end
    local out = {}
    for _, item in ipairs(list) do
        local id = item.id or item.Id or item.sex
        local name = item.name or item.Name or item.sexName
        if name == 'male' or name == 'Male' or name == 'Masculino' then
            name = 'Male'
        elseif name == 'female' or name == 'Female' or name == 'Femenino' then
            name = 'Female'
        end
        table.insert(out, { id = id, name = name })
    end
    return #out > 0 and out or DEFAULT_GENDERS
end

local function applyOptions(vocations, genders)
    if not window then
        return
    end
    local sexPanel = window:getChildById('sexPanel')
    local vocationPanel = window:getChildById('vocationPanel')
    sexGroup = buildRadioGroup(sexPanel, normalizeGenders(genders), true)
    vocationGroup = buildRadioGroup(vocationPanel, normalizeVocations(vocations), false)
end

local function loadOptions()
    if not Services or not Services.createAccount or Services.createAccount == '' then
        applyOptions(DEFAULT_VOCATIONS, DEFAULT_GENDERS)
        return
    end
    HTTP.postJSON(Services.createAccount, {
        type = 'getcharactercreationoptions'
    }, function(response, err)
        if err or type(response) ~= 'table' then
            applyOptions(DEFAULT_VOCATIONS, DEFAULT_GENDERS)
            return
        end
        applyOptions(response.Vocations or response.vocations, response.Genders or response.genders)
    end)
end

local function tryDisplayUI()
    local paths = {
        '/modules/client_entergame/createCharacter',
        '/client_entergame/createCharacter',
        'createCharacter'
    }
    for _, path in ipairs(paths) do
        local ok, result = pcall(function()
            return g_ui.displayUI(path)
        end)
        if ok and result then
            return result
        end
    end

    -- Fallback: import style then create widget
    pcall(function()
        g_ui.importStyle('/modules/client_entergame/createCharacter')
    end)
    pcall(function()
        g_ui.importStyle('/client_entergame/createCharacter')
    end)
    pcall(function()
        g_ui.importStyle('createCharacter')
    end)

    local ok, result = pcall(function()
        return g_ui.createWidget('CreateCharacterWindow', g_ui.getRootWidget and g_ui.getRootWidget() or rootWidget)
    end)
    if ok and result then
        return result
    end
    return nil
end

function CreateCharacter.show()
    if window then
        local destroyed = false
        pcall(function()
            destroyed = window:isDestroyed()
        end)
        if not destroyed then
            window:show()
            window:raise()
            window:focus()
            local nameEdit = window:getChildById('nameEdit')
            if nameEdit then
                nameEdit:focus()
            end
            return
        end
        window = nil
    end

    window = tryDisplayUI()
    if not window then
        displayErrorBox(tr('Create Character'), tr('Could not open create character window.'))
        g_logger.error('[CreateCharacter] UI load failed for createCharacter.otui')
        return
    end

    window:show()
    window:raise()
    window:focus()
    applyOptions(DEFAULT_VOCATIONS, DEFAULT_GENDERS)
    loadOptions()

    local nameEdit = window:getChildById('nameEdit')
    if nameEdit then
        nameEdit:setText('')
        nameEdit:focus()
    end
end

function CreateCharacter.hide()
    if window then
        pcall(function()
            window:destroy()
        end)
        window = nil
    end
    sexGroup = nil
    vocationGroup = nil
end

function CreateCharacter.submit()
    if not window then
        return
    end
    if not G.account or G.account == '' or not G.password or G.password == '' then
        displayErrorBox(tr('Create Character'), tr('You must login with Discord first.'))
        return
    end

    local nameEdit = window:getChildById('nameEdit')
    local name = nameEdit and nameEdit:getText() or ''
    name = name:trim()
    if name == '' then
        displayErrorBox(tr('Create Character'), tr('Please enter your character name.'))
        return
    end

    local createBtn = window:getChildById('buttonCreate')
    if createBtn then
        createBtn:disable()
    end

    HTTP.postJSON(Services.createAccount, {
        type = 'createcharacter',
        EMail = G.account,
        Password = G.password,
        CharacterName = name,
        CharacterSex = selectedSex or 1,
        CharacterVocation = selectedVocation or 1
    }, function(response, err)
        if createBtn then
            createBtn:enable()
        end
        if err or not response then
            displayErrorBox(tr('Create Character'), tostring(err or tr('Request failed.')))
            return
        end
        if response.errorCode and response.errorCode ~= 0 then
            displayErrorBox(tr('Create Character'), response.errorMessage or tr('Could not create character.'))
            return
        end
        CreateCharacter.hide()
        if EnterGame and EnterGame.doLoginAfterCreate then
            EnterGame.doLoginAfterCreate()
        elseif EnterGame and EnterGame.tryHttpLogin then
            EnterGame.tryHttpLogin(G.clientVersion or 1525, true)
        end
    end)
end
