// custom.hpp
#pragma once

namespace MenuColors {
    const ImVec4 WindowBg = ImVec4(0.05f, 0.05f, 0.08f, 0.98f);           // Deep black
    const ImVec4 TopBarBg = ImVec4(0.03f, 0.03f, 0.05f, 1.0f);            // Very dark black
    const ImVec4 TabBg = ImVec4(0.04f, 0.04f, 0.07f, 1.00f);              // Dark black
    const ImVec4 TabSelected = ImVec4(0.06f, 0.02f, 0.12f, 1.00f);        // Purple selected
    const ImVec4 SidebarBg = ImVec4(0.02f, 0.02f, 0.04f, 1.00f);          // Almost black
    const ImVec4 ContentBg = ImVec4(0.05f, 0.05f, 0.08f, 1.00f);          // Deep black
    const ImVec4 PanelBg = ImVec4(0.08f, 0.08f, 0.12f, 0.95f);            // Dark panel
    const ImVec4 PanelBorder = ImVec4(0.50f, 0.20f, 0.80f, 0.4f);         // Purple border
    const ImVec4 TextBright = ImVec4(0.95f, 0.95f, 0.95f, 1.00f);         // Off-white text
    const ImVec4 TextNormal = ImVec4(0.70f, 0.70f, 0.75f, 1.00f);         // Light gray text
    const ImVec4 TextDim = ImVec4(0.75f, 0.50f, 0.95f, 1.00f);            // Purple dim text
    const ImVec4 CheckboxBg = ImVec4(0.10f, 0.05f, 0.15f, 1.00f);         // Purple background
    const ImVec4 CheckboxBorder = ImVec4(0.60f, 0.30f, 0.90f, 1.00f);     // Purple border
    const ImVec4 SliderBg = ImVec4(0.08f, 0.04f, 0.12f, 1.00f);           // Dark purple
    const ImVec4 SliderGrab = ImVec4(0.70f, 0.30f, 1.00f, 1.00f);         // Bright purple
    const ImVec4 ComboBoxBg = ImVec4(0.08f, 0.04f, 0.12f, 1.00f);         // Dark purple
    const ImVec4 PopupBg = ImVec4(0.05f, 0.02f, 0.10f, 0.98f);            // Dark popup
    const ImVec4 PopupHover = ImVec4(0.15f, 0.08f, 0.20f, 1.00f);         // Purple hover
    const ImVec4 SectionBg = ImVec4(0.06f, 0.03f, 0.10f, 0.8f);           // Dark section
    const ImVec4 Accent = ImVec4(0.70f, 0.30f, 1.00f, 1.00f);             // Vibrant purple
    const ImVec4 AccentHover = ImVec4(0.80f, 0.40f, 1.00f, 1.00f);        // Lighter purple
    const ImVec4 AccentActive = ImVec4(0.60f, 0.20f, 0.90f, 1.00f);       // Darker purple

    const ImVec4 Green = ImVec4(0.30f, 0.85f, 0.50f, 1.00f);
    const ImVec4 Red = ImVec4(0.90f, 0.25f, 0.30f, 1.00f);
    const ImVec4 Orange = ImVec4(0.90f, 0.65f, 0.30f, 1.00f);
}

static int g_CurrentLanguage = 0;


struct LanguageStrings {
    const char* title;
    const char* aimbot;
    const char* visuals;
    const char* configs;
    const char* settings;

    const char* enable_aimbot;
    const char* mouse_key;
    const char* aim_bone;
    const char* aim_priority;
    const char* fov;
    const char* smooth;
    const char* vischeck;
    const char* draw_fov;
    const char* prediction;
    const char* head;
    const char* neck;
    const char* chest;
    const char* pelvis;
    const char* closest_crosshair;
    const char* closest_distance;

    const char* player_box;
    const char* box_type;
    const char* corner_box;
    const char* filled_box;
    const char* outlined_box;
    const char* skeleton_esp;
    const char* snaplines;
    const char* distance;
    const char* username;
    const char* platform;
    const char* weapon;
    const char* rank;
    const char* esp_distance;
    const char* text_size;

    const char* visible_color;
    const char* not_visible_color;
    const char* skeleton_visible;
    const char* skeleton_invisible;

    const char* vsync;
    const char* press_insert;
    const char* version;
    const char* fps;
};

static LanguageStrings g_LanguagesArray[1] = {
    {
        "XenoWare External (BETA)", "Aimbot", "Visuals", "Configs", "Settings",

        "Enable Aimbot", "Mouse Key", "Aim Bone", "Aim Priority",
        "FOV", "Smooth", "Visibility Check", "Draw FOV Circle", "Prediction",
        "Head", "Neck", "Chest", "Pelvis",
        "Closest to Crosshair", "Closest Distance",

        "Player Box", "Box Type", "Corner", "Filled", "Outlined Box",
        "Skeleton ESP", "Snaplines", "Distance", "Username",
        "Platform", "Weapon", "Rank", "ESP Distance", "Text Size",

        "Visible Color", "Not Visible Color",
        "Skeleton Visible", "Skeleton Invisible",

        "V-Sync",
        "Press INSERT to toggle menu", "Version 1.0.0",
        "FPS:"
    }
};

static LanguageStrings& GetLang() {
    return g_LanguagesArray[g_CurrentLanguage];
}
struct AnimationState {
    float checkbox_anim[32] = { 0.0f };
    float slider_hover[32] = { 0.0f };
    float combo_hover[32] = { 0.0f };

    void Update(float delta_time) {
        const float speed = 8.0f;
        for (int i = 0; i < 32; i++) {
            slider_hover[i] *= (1.0f - delta_time * speed);
            combo_hover[i] *= (1.0f - delta_time * speed);
        }
    }
};

static AnimationState g_Anim;

static bool Checkbox(const char* label, bool* value) {
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems) return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    const ImGuiID id = window->GetID(label);

    const float box_size = 18.0f;
    const float rounding = 3.0f;

    ImVec2 pos = window->DC.CursorPos;
    const ImVec2 label_size = ImGui::CalcTextSize(label);

    const ImRect total_bb(pos, ImVec2(pos.x + box_size + 10.0f + label_size.x, pos.y + box_size));
    ImGui::ItemSize(total_bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(total_bb, id)) return false;

    bool hovered, held;
    bool pressed = ImGui::ButtonBehavior(total_bb, id, &hovered, &held);
    if (pressed) {
        *value = !*value;
        g_Anim.checkbox_anim[id % 32] = 0.0f;
        ImGui::MarkItemEdited(id);
    }

    float anim_progress = g_Anim.checkbox_anim[id % 32];
    if (*value) {
        anim_progress += ImGui::GetIO().DeltaTime * 8.0f;
        if (anim_progress > 1.0f) anim_progress = 1.0f;
    }
    else {
        anim_progress -= ImGui::GetIO().DeltaTime * 8.0f;
        if (anim_progress < 0.0f) anim_progress = 0.0f;
    }
    g_Anim.checkbox_anim[id % 32] = anim_progress;

    const ImRect checkbox_bb(pos, ImVec2(pos.x + box_size, pos.y + box_size));

    ImVec4 bg_lerp = ImVec4(
        MenuColors::CheckboxBg.x + (MenuColors::Accent.x - MenuColors::CheckboxBg.x) * anim_progress,
        MenuColors::CheckboxBg.y + (MenuColors::Accent.y - MenuColors::CheckboxBg.y) * anim_progress,
        MenuColors::CheckboxBg.z + (MenuColors::Accent.z - MenuColors::CheckboxBg.z) * anim_progress,
        1.0f
    );

    window->DrawList->AddRectFilled(checkbox_bb.Min, checkbox_bb.Max, ImGui::GetColorU32(bg_lerp), rounding);

    if (hovered) {
        window->DrawList->AddRect(
            ImVec2(checkbox_bb.Min.x - 2, checkbox_bb.Min.y - 2),
            ImVec2(checkbox_bb.Max.x + 2, checkbox_bb.Max.y + 2),
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.3f)),
            rounding + 1.0f, 0, 2.0f
        );
    }

    ImU32 border_col = hovered ? ImGui::GetColorU32(MenuColors::AccentHover) :
        ImGui::GetColorU32(MenuColors::CheckboxBorder);
    window->DrawList->AddRect(checkbox_bb.Min, checkbox_bb.Max, border_col, rounding, 0, 1.5f);

    if (anim_progress > 0.0f) {
        float check_alpha = anim_progress;
        ImVec2 p1 = ImVec2(pos.x + 5, pos.y + 10);
        ImVec2 p2 = ImVec2(pos.x + 8, pos.y + 13);
        ImVec2 p3 = ImVec2(pos.x + 13, pos.y + 6);

        ImU32 check_col = ImGui::GetColorU32(ImVec4(0.15f, 0.15f, 0.20f, check_alpha));
        window->DrawList->AddLine(p1, p2, check_col, 2.0f * anim_progress);
        window->DrawList->AddLine(p2, p3, check_col, 2.0f * anim_progress);
    }

    ImVec2 label_pos(pos.x + box_size + 10.0f, pos.y + (box_size - label_size.y) * 0.5f);
    ImGui::RenderText(label_pos, label);

    return pressed;
}
static bool Combo(const char* label, int* current_item, const char* const items[], int items_count) {
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems) return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    const ImGuiID id = window->GetID(label);

    const float combo_width = ImGui::CalcItemWidth() > 0 ? ImGui::CalcItemWidth() : 180.0f;
    const float combo_height = 28.0f;
    const float rounding = 4.0f;

    ImVec2 pos = window->DC.CursorPos;
    const ImRect combo_bb(pos, ImVec2(pos.x + combo_width, pos.y + combo_height));

    ImGui::ItemSize(combo_bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(combo_bb, id)) return false;

    bool hovered, held;
    bool pressed = ImGui::ButtonBehavior(combo_bb, id, &hovered, &held);

    bool popup_open = ImGui::IsPopupOpen(label);

    if (hovered || popup_open) {
        g_Anim.combo_hover[id % 32] += ImGui::GetIO().DeltaTime * 6.0f;
        if (g_Anim.combo_hover[id % 32] > 1.0f) g_Anim.combo_hover[id % 32] = 1.0f;
    }
    else {
        g_Anim.combo_hover[id % 32] -= ImGui::GetIO().DeltaTime * 6.0f;
        if (g_Anim.combo_hover[id % 32] < 0.0f) g_Anim.combo_hover[id % 32] = 0.0f;
    }

    ImU32 bg_col = ImGui::GetColorU32(MenuColors::ComboBoxBg);
    window->DrawList->AddRectFilled(combo_bb.Min, combo_bb.Max, bg_col, rounding);

    if (g_Anim.combo_hover[id % 32] > 0.0f) {
        float glow_alpha = 0.4f * g_Anim.combo_hover[id % 32];
        window->DrawList->AddRect(
            ImVec2(combo_bb.Min.x - 2, combo_bb.Min.y - 2),
            ImVec2(combo_bb.Max.x + 2, combo_bb.Max.y + 2),
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, glow_alpha)),
            rounding + 1.0f, 0, 2.0f
        );
    }

    ImU32 border_col = (hovered || popup_open) ? ImGui::GetColorU32(MenuColors::Accent) :
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.2f));
    window->DrawList->AddRect(combo_bb.Min, combo_bb.Max, border_col, rounding, 0, 1.5f);

    const char* current_text = items[*current_item];
    ImVec2 text_size = ImGui::CalcTextSize(current_text);
    ImVec2 text_pos(combo_bb.Min.x + 10.0f, combo_bb.Min.y + (combo_height - text_size.y) * 0.5f);
    window->DrawList->AddText(text_pos, ImGui::GetColorU32(MenuColors::TextNormal), current_text);

    ImVec2 arrow_center(combo_bb.Max.x - 14.0f, combo_bb.Min.y + combo_height * 0.5f);
    float arrow_size = 4.5f;
    ImVec2 p1(arrow_center.x - arrow_size, arrow_center.y - arrow_size * 0.5f);
    ImVec2 p2(arrow_center.x + arrow_size, arrow_center.y - arrow_size * 0.5f);
    ImVec2 p3(arrow_center.x, arrow_center.y + arrow_size * 0.5f);
    window->DrawList->AddTriangleFilled(p1, p2, p3, ImGui::GetColorU32(
        hovered ? MenuColors::Accent : MenuColors::TextDim
    ));

    if (pressed) {
        ImGui::OpenPopup(label);
    }

    bool changed = false;

    ImGui::PushStyleColor(ImGuiCol_PopupBg, MenuColors::PopupBg);
    ImGui::PushStyleColor(ImGuiCol_Border, MenuColors::CheckboxBorder);
    ImGui::PushStyleColor(ImGuiCol_HeaderHovered, MenuColors::PopupHover);
    ImGui::PushStyleColor(ImGuiCol_Header, MenuColors::Accent);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 4));
    ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f);
    ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 1.5f);
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 2));

    if (ImGui::BeginPopup(label, ImGuiWindowFlags_NoScrollbar)) {
        for (int i = 0; i < items_count; i++) {
            bool is_selected = (i == *current_item);

            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10, 6));

            if (ImGui::Selectable(items[i], is_selected, 0, ImVec2(combo_width, 0))) {
                *current_item = i;
                changed = true;
            }

            ImGui::PopStyleVar();

            if (is_selected) {
                ImGui::SetItemDefaultFocus();
            }
        }

        ImGui::EndPopup();
    }

    ImGui::PopStyleVar(4);
    ImGui::PopStyleColor(4);

    return changed;
}
static bool TabButton(const char* label, int index, int* selected, float width) {
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems) return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;

    char id_str[64];
    sprintf_s(id_str, "##tab_%d", index);
    const ImGuiID id = window->GetID(id_str);

    const ImVec2 pos = window->DC.CursorPos;
    const float height = 42.0f;

    const ImRect bb(pos, ImVec2(pos.x + width, pos.y + height));
    ImGui::ItemSize(bb);
    if (!ImGui::ItemAdd(bb, id)) return false;

    bool hovered, held;
    bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held);

    static int prev_selected = *selected;
    static float tab_anim[4] = { 0.0f };

    if (pressed) {
        prev_selected = *selected;
        *selected = index;
    }

    bool is_selected = (*selected == index);

    float target = is_selected ? 1.0f : 0.0f;
    tab_anim[index] += (target - tab_anim[index]) * ImGui::GetIO().DeltaTime * 10.0f;

    if (tab_anim[index] > 0.01f) {
        float alpha = tab_anim[index];
        window->DrawList->AddRectFilled(bb.Min, bb.Max,
            ImGui::GetColorU32(ImVec4(0.06f, 0.02f, 0.12f, alpha)), 4.0f);

        window->DrawList->AddLine(
            ImVec2(bb.Min.x, bb.Max.y - 2.0f),
            ImVec2(bb.Max.x, bb.Max.y - 2.0f),
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, alpha)),
            3.0f
        );

        window->DrawList->AddLine(
            bb.Min,
            ImVec2(bb.Min.x, bb.Max.y),
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.5f * alpha)),
            2.0f
        );
    }
    else if (hovered) {
        window->DrawList->AddRectFilled(bb.Min, bb.Max,
            ImGui::GetColorU32(ImVec4(0.08f, 0.04f, 0.12f, 0.8f)), 4.0f);

        window->DrawList->AddRect(bb.Min, bb.Max,
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.4f)), 4.0f, 0, 1.0f);
    }

    ImVec2 label_size = ImGui::CalcTextSize(label);
    ImVec2 label_pos(
        bb.Min.x + (width - label_size.x) * 0.5f,
        bb.Min.y + (height - label_size.y) * 0.5f
    );

    ImU32 color = ImGui::GetColorU32(
        ImVec4(
            MenuColors::TextDim.x + (MenuColors::TextBright.x - MenuColors::TextDim.x) * tab_anim[index],
            MenuColors::TextDim.y + (MenuColors::TextBright.y - MenuColors::TextDim.y) * tab_anim[index],
            MenuColors::TextDim.z + (MenuColors::TextBright.z - MenuColors::TextDim.z) * tab_anim[index],
            1.0f
        )
    );
    window->DrawList->AddText(label_pos, color, label);

    return pressed;
}

static bool CustomSliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%d") {
    ImGuiWindow* window = ImGui::GetCurrentWindow();
    if (window->SkipItems) return false;

    ImGuiContext& g = *GImGui;
    const ImGuiStyle& style = g.Style;
    const ImGuiID id = window->GetID(label);

    const float slider_width = ImGui::CalcItemWidth() > 0 ? ImGui::CalcItemWidth() : 360.0f;
    const float slider_height = 20.0f;
    const float grab_radius = 8.0f;

    ImVec2 pos = window->DC.CursorPos;
    ImRect total_bb(pos, ImVec2(pos.x + slider_width, pos.y + slider_height));

    ImGui::ItemSize(total_bb, style.FramePadding.y);
    if (!ImGui::ItemAdd(total_bb, id)) return false;

    ImRect track_bb(ImVec2(pos.x + 10, pos.y + slider_height * 0.5f - 3.0f),
        ImVec2(pos.x + slider_width - 10, pos.y + slider_height * 0.5f + 3.0f));

    window->DrawList->AddRectFilledMultiColor(
        track_bb.Min, track_bb.Max,
        ImGui::GetColorU32(ImVec4(0.08f, 0.04f, 0.12f, 1.0f)),
        ImGui::GetColorU32(ImVec4(0.10f, 0.05f, 0.15f, 1.0f)),
        ImGui::GetColorU32(ImVec4(0.10f, 0.05f, 0.15f, 1.0f)),
        ImGui::GetColorU32(ImVec4(0.08f, 0.04f, 0.12f, 1.0f))
    );

    window->DrawList->AddRect(track_bb.Min, track_bb.Max,
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.3f)), 3.0f, 0, 1.0f);

    float grab_pos = pos.x + 10 + ((float)(*v - v_min) / (float)(v_max - v_min)) * (slider_width - 20);
    ImVec2 grab_center(grab_pos, pos.y + slider_height * 0.5f);

    bool hovered, held;
    bool clicked = ImGui::ButtonBehavior(total_bb, id, &hovered, &held);

    if (hovered || held) {
        g_Anim.slider_hover[id % 32] += ImGui::GetIO().DeltaTime * 8.0f;
        if (g_Anim.slider_hover[id % 32] > 1.0f) g_Anim.slider_hover[id % 32] = 1.0f;
    }
    else {
        g_Anim.slider_hover[id % 32] -= ImGui::GetIO().DeltaTime * 8.0f;
        if (g_Anim.slider_hover[id % 32] < 0.0f) g_Anim.slider_hover[id % 32] = 0.0f;
    }

    if (held || hovered) {
        ImGui::GetIO().WantCaptureMouse = true;

        if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && (hovered || held)) {
            float mouse_x = ImGui::GetIO().MousePos.x;
            float normalized = (mouse_x - (pos.x + 10)) / (slider_width - 20);
            normalized = (normalized < 0.0f) ? 0.0f : (normalized > 1.0f) ? 1.0f : normalized;
            *v = (int)(v_min + normalized * (v_max - v_min));
        }
    }

    float fill_width = ((float)(*v - v_min) / (float)(v_max - v_min)) * (slider_width - 20);

    ImVec2 fill_start = ImVec2(pos.x + 10, track_bb.Min.y);
    ImVec2 fill_end = ImVec2(pos.x + 10 + fill_width, track_bb.Max.y);

    window->DrawList->AddRectFilledMultiColor(
        fill_start, fill_end,
        ImGui::GetColorU32(ImVec4(0.50f, 0.20f, 0.80f, 0.9f)),
        ImGui::GetColorU32(ImVec4(0.80f, 0.40f, 1.00f, 0.9f)),
        ImGui::GetColorU32(ImVec4(0.80f, 0.40f, 1.00f, 0.9f)),
        ImGui::GetColorU32(ImVec4(0.50f, 0.20f, 0.80f, 0.9f))
    );

    ImU32 grab_color = held ? ImGui::GetColorU32(MenuColors::AccentHover) :
        hovered ? ImGui::GetColorU32(MenuColors::Accent) :
        ImGui::GetColorU32(MenuColors::SliderGrab);

    if (g_Anim.slider_hover[id % 32] > 0.0f) {
        float glow_radius = grab_radius + 4.0f + g_Anim.slider_hover[id % 32] * 2.0f;
        window->DrawList->AddCircleFilled(grab_center, glow_radius,
            ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.3f * g_Anim.slider_hover[id % 32])), 20);
    }

    window->DrawList->AddCircleFilled(grab_center, grab_radius, grab_color, 20);
    window->DrawList->AddCircle(grab_center, grab_radius,
        ImGui::GetColorU32(MenuColors::CheckboxBorder), 20, 1.5f);

    char value_buf[32];
    sprintf_s(value_buf, format, *v);
    ImVec2 text_size = ImGui::CalcTextSize(value_buf);
    ImVec2 text_pos(pos.x + slider_width + 12, pos.y + (slider_height - text_size.y) * 0.5f);

    window->DrawList->AddRectFilledMultiColor(
        ImVec2(text_pos.x - 6, text_pos.y - 4),
        ImVec2(text_pos.x + text_size.x + 6, text_pos.y + text_size.y + 4),
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.20f)),
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.15f)),
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.15f)),
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.20f))
    );

    window->DrawList->AddRect(
        ImVec2(text_pos.x - 6, text_pos.y - 4),
        ImVec2(text_pos.x + text_size.x + 6, text_pos.y + text_size.y + 4),
        ImGui::GetColorU32(ImVec4(0.70f, 0.30f, 1.00f, 0.4f)),
        3.0f, 0, 1.0f
    );

    window->DrawList->AddText(text_pos, ImGui::GetColorU32(MenuColors::Accent), value_buf);

    return clicked;
}

static void RenderCustomText(ImFont* font, float fontSize, ImVec2 position, ImVec4 color,
    const char* text, bool with_glow = false) {
    ImDrawList* draw_list = ImGui::GetWindowDrawList();

    if (with_glow) {
        ImVec4 glow_color(0.70f, 0.30f, 1.00f, 0.2f);
        for (int i = -2; i <= 2; i++) {
            for (int j = -2; j <= 2; j++) {
                if (i != 0 || j != 0) {
                    draw_list->AddText(font, fontSize, ImVec2(position.x + i, position.y + j),
                        ImGui::GetColorU32(glow_color), text);
                }
            }
        }
    }

    draw_list->AddText(font, fontSize, ImVec2(position.x + 1, position.y + 1),
        ImGui::GetColorU32(ImVec4(0, 0, 0, 0.4f)), text);

    draw_list->AddText(font, fontSize, position, ImGui::GetColorU32(color), text);
}

