EbonholdHub.MainWindow = {}

local ST = EbonholdHub.SiteTheme
local SW = EbonholdHub.SiteWidgets
local L  = ST and ST.Layout

local WINDOW_WIDTH  = (L and L.WIN_W) or 1040
local WINDOW_HEIGHT = (L and L.WIN_H) or 720
local LEFT_WIDTH    = 218
local FRAME_NAME    = "EbonholdHubMainWindow"

local NAV_VIEW_MAP = {
    welcome        = "myBuild",
    buildOverview  = "myBuild",
    buildTabs      = "myBuild",
    publicBuilds   = "catalog",
    echoMap        = "echoMap",
}

local frame
local bodyRow
local leftPanel
local divider
local rightPanel

local function ShouldHideSidebar(viewName)
    return viewName == "welcome"
        or viewName == "buildOverview"
        or viewName == "buildTabs"
        or viewName == "publicBuilds"
        or viewName == "echoMap"
end

local function ApplyBodyLayout(viewName)
    if not frame or not bodyRow or not leftPanel or not rightPanel then return end

    if ShouldHideSidebar(viewName) then
        leftPanel:Hide()
        if divider then divider:Hide() end
        rightPanel:ClearAllPoints()
        rightPanel:SetPoint("TOPLEFT", bodyRow, "TOPLEFT", 0, 0)
        rightPanel:SetPoint("BOTTOMRIGHT", bodyRow, "BOTTOMRIGHT", 0, 0)
    else
        leftPanel:Show()
        if divider then divider:Show() end
        leftPanel:SetWidth(LEFT_WIDTH)
        rightPanel:ClearAllPoints()
        rightPanel:SetPoint("TOPLEFT", divider, "TOPRIGHT", 8, 0)
        rightPanel:SetPoint("BOTTOMRIGHT", bodyRow, "BOTTOMRIGHT", 0, 0)
    end
end

local function BuildFrame()
    local f
    f = SW.CreateSiteWindow({
        name   = FRAME_NAME,
        width  = WINDOW_WIDTH,
        height = WINDOW_HEIGHT,
        closable = false,
        onClose = function()
            f:Hide()
            if EbonholdHub.MainNav and EbonholdHub.MainNav.Hide then
                EbonholdHub.MainNav.Hide()
            end
        end,
    })

    local body = f.body

    bodyRow = CreateFrame("Frame", nil, body)
    bodyRow:SetAllPoints(body)

    leftPanel = CreateFrame("Frame", nil, bodyRow)
    leftPanel:SetPoint("TOPLEFT", bodyRow, "TOPLEFT", 0, 0)
    leftPanel:SetPoint("BOTTOMLEFT", bodyRow, "BOTTOMLEFT", 0, 0)
    leftPanel:SetWidth(LEFT_WIDTH)

    divider = bodyRow:CreateTexture(nil, "ARTWORK")
    divider:SetTexture(ST.FLAT)
    divider:SetVertexColor(unpack(ST.C.border))
    divider:SetPoint("TOPLEFT", leftPanel, "TOPRIGHT", 8, 0)
    divider:SetPoint("BOTTOMLEFT", leftPanel, "BOTTOMRIGHT", 8, 0)
    divider:SetWidth(1)

    rightPanel = CreateFrame("Frame", nil, bodyRow)
    rightPanel:SetPoint("TOPLEFT", divider, "TOPRIGHT", 8, 0)
    rightPanel:SetPoint("BOTTOMRIGHT", bodyRow, "BOTTOMRIGHT", 0, 0)

    local rightContent = CreateFrame("Frame", nil, rightPanel)
    rightContent:SetAllPoints(rightPanel)

    f._left = leftPanel
    f._right = rightPanel
    f._rightContent = rightContent
    f._divider = divider
    f._bodyRow = bodyRow

    if EbonholdHub.MainNav and EbonholdHub.MainNav.Create then
        EbonholdHub.MainNav.Create(f, {
            onClose = function()
                f:Hide()
                if EbonholdHub.MainNav and EbonholdHub.MainNav.Hide then
                    EbonholdHub.MainNav.Hide()
                end
            end,
        })
    end

    EbonholdHub.ViewRouter.OnChanged(function(viewName)
        local navId = NAV_VIEW_MAP[viewName]
        if EbonholdHub.BuildList and EbonholdHub.BuildList.SetActiveNav then
            EbonholdHub.BuildList.SetActiveNav(navId)
        end
        ApplyBodyLayout(viewName)
    end)

    return f
end

function EbonholdHub.MainWindow.Init()
    frame = BuildFrame()

    EbonholdHub.MainWindow._frame = frame
    EbonholdHub.MainWindow._left  = frame._left
    EbonholdHub.MainWindow._right = frame._right

    EbonholdHub.ViewRouter.SetContainer(frame._rightContent)
    EbonholdHub.BuildList.Init(frame._left)
    EbonholdHub.WeightsView.Init()
    EbonholdHub.BuildForm.Init()
    EbonholdHub.SettingsView.Init()
    if EbonholdHub.AdvisorView then EbonholdHub.AdvisorView.Init() end
    EbonholdHub.BuildTabs.Init()
    EbonholdHub.BuildOverview.Init()
    EbonholdHub.PublicBuildsView.Init()
    EbonholdHub.EchoMapView.Init()

    EbonholdHub.ViewRouter.Register("welcome", {
        Show = function(container, _)
            EbonholdHub.WelcomeView.Mount(container)
        end,
        Hide = function()
            EbonholdHub.WelcomeView.Unmount()
        end,
    })

    EbonholdHub.ViewRouter.Register("publicBuilds", {
        Show = function(container, _)
            EbonholdHub.PublicBuildsView.Mount(container)
        end,
        Hide = function()
            EbonholdHub.PublicBuildsView.Unmount()
        end,
    })

    EbonholdHub.ViewRouter.Register("echoMap", {
        Show = function(container, _)
            EbonholdHub.EchoMapView.Mount(container)
        end,
        Hide = function()
            EbonholdHub.EchoMapView.Unmount()
        end,
    })

    EbonholdHub.MainWindow._ShowInitialView()
end

function EbonholdHub.MainWindow._ShowInitialView()
    local active = EbonholdHub.Build.GetActive()
    if active then
        EbonholdHub.ViewRouter.Show("buildOverview", { build = active })
    else
        EbonholdHub.ViewRouter.Show("welcome")
    end
end

SLASH_EbonholdHub1 = "/ebh"
SLASH_EbonholdHub2 = "/ebonholdhub"
SlashCmdList["EbonholdHub"] = function(msg)
    msg = strtrim(msg or "")
    if EbonholdHub.SiteDesignDemo and EbonholdHub.SiteDesignDemo.HandleSlash(msg) then
        return
    end
    if EbonholdHub.AutoPickDebug and EbonholdHub.AutoPickDebug.HandleSlash(msg) then
        return
    end
    if EbonholdHub.PickLog and EbonholdHub.PickLog.HandleSlash(msg) then
        return
    end
    if EbonholdHub.ApiDump and EbonholdHub.ApiDump.HandleSlash(msg) then
        return
    end
    if EbonholdHub.Build and EbonholdHub.Build.HandleSlash(msg) then
        return
    end
    if EbonholdHub.LootTracker and EbonholdHub.LootTracker.HandleSlash(msg) then
        return
    end
    EbonholdHub.MainWindow.Toggle()
end

local function SetShown(show)
    local f = EbonholdHub.MainWindow._frame
    if not f then return end
    if show then
        f:Show()
        if EbonholdHub.MainNav and EbonholdHub.MainNav.Show then
            EbonholdHub.MainNav.Show()
        end
    else
        f:Hide()
        if EbonholdHub.MainNav and EbonholdHub.MainNav.Hide then
            EbonholdHub.MainNav.Hide()
        end
    end
end

function EbonholdHub.MainWindow.Toggle()
    local f = EbonholdHub.MainWindow._frame
    if not f then return end
    SetShown(not f:IsShown())
end

function EbonholdHub.MainWindow.Show()
    SetShown(true)
end
