/*
 * ai_chat_demo.c -- 演示 eduwin_ai 模块
 * 带聊天界面的 C 语言大模型调用
 *
 * 使用前：在 ai_chat_demo.exe 同目录放 api_key.txt
 *        第一行写入你的 DeepSeek API Key
 *        或设置环境变量 DEEPSEEK_API_KEY
 */

#include "eduwin.h"

/* ── 控件句柄 ── */
static HWND g_win;        /* 主窗口 */
static HWND g_history;    /* 聊天历史（只读文本区） */
static HWND g_input;      /* 输入框 */
static HWND g_btn;        /* 发送按钮 */
static HWND g_status;     /* 状态栏 */
static HWND g_clear_btn;  /* 清空按钮 */

/* ── 原窗口过程（用于消息子类化） ── */
static WNDPROC g_old_wndproc = NULL;

/* ── 默认 API Key ── */
static const char *g_default_key = "";

/* ── 自定义消息（用于线程安全地更新 UI） ── */
#define WM_AI_REPLY  (WM_USER + 200)

/* ── 读取 api_key.txt 中的 Key ── */
static void load_api_key(HWND win)
{
    const char *key = NULL;
    FILE *fp = fopen("api_key.txt", "r");
    if (fp)
    {
        static char buf[256];
        if (fgets(buf, sizeof(buf), fp))
        {
            size_t len = strlen(buf);
            while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) buf[--len] = '\0';
            if (len > 0) key = buf;
        }
        fclose(fp);
    }

    if (!key || strlen(key) == 0)
        key = getenv("DEEPSEEK_API_KEY");

    if (!key || strlen(key) == 0)
        key = g_default_key;

    if (key && strlen(key) > 0)
    {
        ai_setup(key, "deepseek-chat", "https://api.deepseek.com/v1");
        set_text(g_status, L"✓ API 已就绪");
    }
    else
    {
        set_text(g_status, L"⚠ 未配置 API Key，请在 api_key.txt 中写入");
    }
}

/* ── 添加消息到聊天历史（在主线程调用） ── */
static void append_message(const char *role, const char *content)
{
    const WCHAR *wtext = get_text(g_history);
    if (!wtext) wtext = L"";

    char current[32768] = "";
    WideCharToMultiByte(CP_UTF8, 0, wtext, -1, current, sizeof(current), NULL, NULL);

    char line[4096];
    if (strcmp(role, "user") == 0)
        snprintf(line, sizeof(line), "🧑 你：%s\n\n", content);
    else
        snprintf(line, sizeof(line), "🤖 AI：%s\n\n", content);

    char buf[32768];
    snprintf(buf, sizeof(buf), "%s%s", current, line);

    WCHAR wbuf[32768];
    MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, 32768);
    set_text(g_history, wbuf);

    /* 滚动到底部 */
    SendMessage(g_history, EM_SETSEL, wcslen(wbuf), wcslen(wbuf));
    SendMessage(g_history, EM_SCROLLCARET, 0, 0);
}

/* ── 共享缓冲区（子线程写→主线程读） ── */
static char g_ai_reply[8192] = "";
static mutex_t *g_reply_lock;

/* ── 异步回调（在子线程调用） ── */
static void on_ai_reply(const char *reply, void *userdata)
{
    /* 把结果存到共享缓冲区，然后通知主线程 */
    mutex_lock(g_reply_lock);
    if (reply)
        strncpy(g_ai_reply, reply, sizeof(g_ai_reply) - 1);
    else
        strcpy(g_ai_reply, "[ERROR]");
    g_ai_reply[sizeof(g_ai_reply) - 1] = '\0';
    mutex_unlock(g_reply_lock);

    PostMessage(g_win, WM_AI_REPLY, 0, 0);
}

/* ── 子类化窗口过程 ── */
static LRESULT CALLBACK subclass_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (msg == WM_AI_REPLY)
    {
        /* 从共享缓冲区读取回复 */
        char reply[8192];
        mutex_lock(g_reply_lock);
        strncpy(reply, g_ai_reply, sizeof(reply) - 1);
        reply[sizeof(reply) - 1] = '\0';
        mutex_unlock(g_reply_lock);

        if (strcmp(reply, "[ERROR]") == 0)
            append_message("ai", "[请求失败，请检查网络或 API Key]");
        else
            append_message("ai", reply);

        /* 恢复控件 */
        set_enable(g_btn, 1);
        set_enable(g_input, 1);
        set_text(g_status, L"就绪");
        set_text(g_input, L"");
        SetFocus(g_input);
        return 0;
    }

    /* 其他消息交给原窗口过程处理 */
    return CallWindowProc(g_old_wndproc, hwnd, msg, wParam, lParam);
}

/* ── 发送消息 ── */
static void on_send(void *data)
{
    (void)data;

    const WCHAR *winput = get_text(g_input);
    if (!winput) return;

    char input[4096] = "";
    WideCharToMultiByte(CP_UTF8, 0, winput, -1, input, sizeof(input), NULL, NULL);

    if (strlen(input) == 0) return;

    /* 显示用户消息 */
    append_message("user", input);
    set_text(g_input, L"");

    /* 禁用控件 */
    set_enable(g_btn, 0);
    set_enable(g_input, 0);
    set_text(g_status, L"🤖 AI 思考中…");

    /* 异步调用 AI */
    ai_chat_async(input, on_ai_reply, NULL);
}

/* ── 清空聊天 ── */
static void on_clear(void *data)
{
    (void)data;
    set_text(g_history, L"");
    set_text(g_status, L"对话已清空");
    SetFocus(g_input);
}

int main(void)
{
    /* 初始化线程库和线程同步 */
    if (thread_init() != 0)
    {
        alert(L"错误", L"线程模块初始化失败");
        return 1;
    }
    g_reply_lock = mutex_create();

    if (init_app() != 0)
    {
        alert(L"错误", L"eduwin 初始化失败");
        return 1;
    }

    g_win = create_window(L"AI Chat — C 语言调用大模型（eduwin_ai demo）", 620, 520);
    if (!g_win)
    {
        alert(L"错误", L"创建窗口失败");
        return 1;
    }

    /* 设置窗口字体（微软雅黑，好看） */
    HFONT hFont = CreateFont(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
                              DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
                              CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                              DEFAULT_PITCH | FF_DONTCARE, L"Microsoft YaHei");
    if (hFont) SendMessage(g_win, WM_SETFONT, (WPARAM)hFont, TRUE);

    /* ── 布局 ── */
    int w = 620, h = 520;
    int m = 10;
    int status_h = 22;
    int input_h = 50;
    int btn_w = 70;

    /* 聊天历史 */
    g_history = create_textarea(g_win,
        L"━━━ AI Chat Demo ━━━\n"
        L"基于 eduwin_ai 模块 + WinHTTP + DeepSeek API\n"
        L"输入问题，点击「发送」或按 Ctrl+Enter\n\n",
        m, m, w - 2*m, h - m - status_h - input_h - 3*m);
    set_readonly(g_history, 1);

    /* 状态栏 */
    g_status = create_label(g_win, L"初始化…", m, h - m - status_h - input_h - m - 5,
                            w - 2*m, status_h);

    /* 清空按钮 */
    g_clear_btn = create_button(g_win, L"清空", m, h - m - input_h, 60, input_h);
    on_button_click(g_clear_btn, on_clear, NULL);

    /* 输入框 */
    g_input = create_text(g_win, L"输入问题，Ctrl+Enter 发送",
                          m + 65, h - m - input_h,
                          w - 2*m - 65 - btn_w - m, input_h);

    /* 发送按钮 */
    g_btn = create_button(g_win, L"发送", w - m - btn_w, h - m - input_h, btn_w, input_h);
    on_button_click(g_btn, on_send, NULL);

    /* 子类化窗口过程（捕捉自定义消息） */
    g_old_wndproc = (WNDPROC)SetWindowLongPtr(g_win, GWLP_WNDPROC, (LONG_PTR)subclass_wndproc);

    show_window(g_win);

    /* 加载 API Key */
    load_api_key(g_win);

    run_app();

    mutex_free(g_reply_lock);
    return 0;
}

