#import "Basic";
#import "Windows";
#import "Windows_Utf8";
#import "File";
#import "String";

// Win32 declarations are provided by win32.jai loaded in the main workspace.

Dialog_State :: struct {
    edit_hwnd: HWND;
    ok_hwnd: HWND;
    cancel_hwnd: HWND;
    dialog_done: bool;
    url_saved: bool;
}

dialog_proc :: (hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #c_call {
    ctx: #Context;
    push_context ctx {
        state := cast(*Dialog_State) GetWindowLongPtrW(hwnd, GWLP_USERDATA);

        if msg == {
            case WM_CREATE; {
                create_struct := cast(*CREATESTRUCTW) lparam;
                state = cast(*Dialog_State) create_struct.lpCreateParams;
                SetWindowLongPtrW(hwnd, GWLP_USERDATA, cast(LONG_PTR) state);

                hFont := GetStockObject(DEFAULT_GUI_FONT);

                static_label := CreateWindowExW(
                    0,
                    utf8_to_wide("STATIC"),
                    utf8_to_wide("Enter Sing-box Config URL:"),
                    WS_CHILD | WS_VISIBLE | SS_LEFT,
                    20, 20, 410, 20,
                    hwnd,
                    null,
                    null,
                    null
                );
                SendMessageW(static_label, WM_SETFONT, cast(WPARAM) hFont, TRUE);

                state.edit_hwnd = CreateWindowExW(
                    WS_EX_CLIENTEDGE,
                    utf8_to_wide("EDIT"),
                    utf8_to_wide(""),
                    WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL,
                    20, 45, 410, 25,
                    hwnd,
                    null,
                    null,
                    null
                );
                SendMessageW(state.edit_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);

                // Populate with existing URL if present
                existing_url, ok := read_entire_file("url.txt");
                if ok {
                    trimmed := trim(existing_url);
                    wide_url := utf8_to_wide(trimmed);
                    SetWindowTextW(state.edit_hwnd, wide_url);
                    free(existing_url);
                }

                state.ok_hwnd = CreateWindowExW(
                    0,
                    utf8_to_wide("BUTTON"),
                    utf8_to_wide("OK"),
                    WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
                    220, 85, 100, 30,
                    hwnd,
                    cast(HMENU) IDOK,
                    null,
                    null
                );
                SendMessageW(state.ok_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);

                state.cancel_hwnd = CreateWindowExW(
                    0,
                    utf8_to_wide("BUTTON"),
                    utf8_to_wide("Cancel"),
                    WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
                    330, 85, 100, 30,
                    hwnd,
                    cast(HMENU) IDCANCEL,
                    null,
                    null
                );
                SendMessageW(state.cancel_hwnd, WM_SETFONT, cast(WPARAM) hFont, TRUE);

                SetFocus(state.edit_hwnd);
                return 0;
            }
            case WM_COMMAND; {
                control_id := LOWORD(wparam);
                if control_id == IDOK {
                    length := GetWindowTextLengthW(state.edit_hwnd);
                    if length > 0 {
                        buffer := cast(*u16) alloc((length + 1) * size_of(u16));
                        defer free(buffer);
                        
                        GetWindowTextW(state.edit_hwnd, buffer, length + 1);
                        url_utf8 := wide_to_utf8(buffer);
                        defer free(url_utf8);

                        trimmed_url := trim(url_utf8);
                        if trimmed_url {
                            write_entire_file("url.txt", trimmed_url);
                            state.url_saved = true;
                        }
                    } else {
                        DeleteFileW(utf8_to_wide("url.txt"));
                        state.url_saved = true;
                    }
                    DestroyWindow(hwnd);
                    return 0;
                } else if control_id == IDCANCEL {
                    DestroyWindow(hwnd);
                    return 0;
                }
            }
            case WM_CLOSE; {
                DestroyWindow(hwnd);
                return 0;
            }
            case WM_DESTROY; {
                if state {
                    state.dialog_done = true;
                }
                PostThreadMessageW(GetCurrentThreadId(), WM_NULL, 0, 0);
                return 0;
            }
        }
        return DefWindowProcW(hwnd, msg, wparam, lparam);
    }
}

show_config_url_dialog :: (parent_hwnd: HWND) -> bool {
    hInstance := GetModuleHandleW(null);
    class_name := utf8_to_wide("SingboxConfigUrlDialogClass");

    wclass: WNDCLASSEXW;
    wclass.cbSize = size_of(WNDCLASSEXW);
    wclass.style = CS_HREDRAW | CS_VREDRAW;
    wclass.lpfnWndProc = dialog_proc;
    wclass.hInstance = hInstance;
    wclass.hCursor = LoadCursorW(null, IDC_ARROW);
    wclass.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1);
    wclass.lpszClassName = class_name;

    RegisterClassExW(*wclass);
    defer UnregisterClassW(class_name, hInstance);

    screen_w := GetSystemMetrics(SM_CXSCREEN);
    screen_h := GetSystemMetrics(SM_CYSCREEN);
    dialog_w: s32 = 460;
    dialog_h: s32 = 170;
    dialog_x := (screen_w - dialog_w) / 2;
    dialog_y := (screen_h - dialog_h) / 2;

    state: Dialog_State;

    dialog_hwnd := CreateWindowExW(
        WS_EX_DLGMODALFRAME,
        class_name,
        utf8_to_wide("Configure Sing-box URL"),
        WS_POPUP | WS_CAPTION | WS_SYSMENU,
        dialog_x, dialog_y, dialog_w, dialog_h,
        parent_hwnd,
        null,
        hInstance,
        *state
    );

    if !dialog_hwnd return false;

    if parent_hwnd {
        EnableWindow(parent_hwnd, FALSE);
    }

    ShowWindow(dialog_hwnd, SW_SHOW);
    UpdateWindow(dialog_hwnd);

    while !state.dialog_done {
        msg: MSG;
        if GetMessageW(*msg, null, 0, 0) {
            if !IsDialogMessageW(dialog_hwnd, *msg) {
                TranslateMessage(*msg);
                DispatchMessageW(*msg);
            }
        } else {
            PostQuitMessage(cast(s32) msg.wParam);
            break;
        }
    }

    if parent_hwnd {
        EnableWindow(parent_hwnd, TRUE);
        SetFocus(parent_hwnd);
    }

    return state.url_saved;
}
