//
// Created by zhang on 2024/12/28.
//
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <windows.h>
#include <math.h>
#include "./include/function.h"
#include "./include/curses.h"
#include "./include/ui.h"
#include "./include/extern.h"
#include "./include/sqlite3.h"

// 定义窗口宽度和高度
#define WIN_HEIGHT 30
#define WIN_WIDTH  60

//定义每一行最多显示多少列数据
#define PAGE_SIZE 10

extern char Username[15];
extern char class[15];
struct bottom {
    int x, y;
    int width, height;
    char test[30];
    int private;
};

typedef struct Node {
    char *str1;          // 存储第一个字符串
    char *str2;          // 存储第二个字符串
    int num;             // 存储整数
    struct Node *next;   // 指向下一个节点的指针
} Node;

void free_list(Node *head) {
    Node *temp;
    while (head != NULL) {
        temp = head;
        head = head->next;
        free(temp->str1);  // 释放第一个字符串
        free(temp->str2);  // 释放第二个字符串
        free(temp);        // 释放节点本身
    }
}

bool list_search(Node *head,int x) {
    Node *temp = head;
    while (temp != NULL) {
        if(temp->num==x)return 1;
        temp = temp->next;
    }
    return 0;
}

Node* create_node(const char *str1, const char *str2, int num) {
    Node *new_node = (Node *)malloc(sizeof(Node));  // 分配内存
    if (new_node == NULL) {
        printf("Memory allocation failed\n");
        return NULL;
    }

    new_node->str1 = strdup(str1);  // 复制第一个字符串
    new_node->str2 = strdup(str2);  // 复制第二个字符串
    new_node->num = num;            // 设置整数
    new_node->next = NULL;           // 初始化 next 为 NULL

    return new_node;
}

void insert_node(Node **head, const char *str1, const char *str2, int num) {
    Node *new_node = create_node(str1, str2, num);  // 创建新节点
    if (new_node == NULL) {
        return;  // 如果创建节点失败，直接返回
    }

    if (*head == NULL) {
        *head = new_node;  // 如果链表为空，将新节点作为头节点
    } else {
        Node *temp = *head;
        while (temp->next != NULL) {
            temp = temp->next;  // 找到链表的最后一个节点
        }
        temp->next = new_node;  // 将新节点插入到链表末尾
    }
}

void draw_bottom(WINDOW *win, struct bottom *bot) {
    mvwprintw(win, bot->y, bot->x, "%s", bot->test);
}

struct bottom *creat_bottom(WINDOW *win, int x, int y, int width, int height, char *test[]) {
    struct bottom *bot = malloc(sizeof(struct bottom));
    bot->y = x;
    bot->x = y;
    bot->width = width;
    bot->height = height;
    strcpy(bot->test, test);
    //mvwprintw(win,x,y,"%s",test);
    return bot;
}

bool click_bottom(MEVENT event, struct bottom bottom, int sx, int sy) {
    return event.x - sx >= bottom.x && event.x - sx < bottom.x + bottom.width && event.y - sy >= bottom.y &&
           event.y - sy < bottom.y + bottom.height;
}

int Welcome_ui() {
    MEVENT event;
    int startx, starty;
    initscr();                // 初始化curses
    cbreak();                 // 禁用行缓冲
    noecho();                 // 不显示输入字符
    curs_set(0);              // 隐藏光标
    keypad(stdscr, TRUE);     // 启用键盘按键的特殊处理
    mousemask(ALL_MOUSE_EVENTS, NULL);  // 启用鼠标事件
    timeout(100);             // 设置输入超时，防止程序卡死
    // 获取屏幕的尺寸
    // 计算按钮的显示位置
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *welcome_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(welcome_win, TRUE);
    wborder(welcome_win, '|', '|', '-', '-', '+', '+', '+', '+');
    // 标题
    mvwprintw(welcome_win, 1, 1, "Welcome to math calculate system!");
    struct bottom *login = creat_bottom(welcome_win, 4, 1, 5, 1, "Login");
    draw_bottom(welcome_win, login);
    struct bottom *signin = creat_bottom(welcome_win, 8, 1, 6, 1, "Signin");
    draw_bottom(welcome_win, signin);
    struct bottom *exit = creat_bottom(welcome_win, 12, 1, 4, 1, "Exit");
    draw_bottom(welcome_win, exit);
    wrefresh(welcome_win);
    while (1) {
        int rc = wgetch(welcome_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
                if (click_bottom(event, *login, start_x, start_y)) {
                    free(login);
                    free(signin);
                    free(exit);
                    endwin();
                    return 2;
                }
                if (click_bottom(event, *signin, start_x, start_y)) {
                    free(login);
                    free(signin);
                    free(exit);
                    endwin();
                    return 3;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(login);
                    free(signin);
                    free(exit);
                    endwin();
                    return 0;
                }
            }
        }
    }
}

void
draw_login_window(WINDOW *win, struct bottom *login, struct bottom *signin, struct bottom *user, struct bottom *psword,
                  struct bottom *exit) {
    // 清空窗口并绘制边框
    wclear(win);
    box(win, 0, 0);

    // 标题
    mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Login Menu");

    // 用户名输入框
    mvwprintw(win, 3, 4, "Username:");

    // 密码输入框
    mvwprintw(win, 6, 4, "Password:");
    //绘制剩余内容
    draw_bottom(win, login);
    draw_bottom(win, signin);
    draw_bottom(win, exit);
    draw_bottom(win, user);
    draw_bottom(win, psword);
    wrefresh(win); // 刷新窗口
}

void
draw_stu_type_window(WINDOW *win, struct bottom *ok, struct bottom *name_b, struct bottom *class_b,
                     struct bottom *majority_b, struct bottom *exit) {
    // 清空窗口并绘制边框
    wclear(win);
    box(win, 0, 0);

    // 标题
    mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Please input your message.");

    // 用户名输入框
    mvwprintw(win, 3, 4, "Name:");

    // 密码输入框
    mvwprintw(win, 6, 4, "Class:");
    //绘制剩余内容
    mvwprintw(win, 9, 4, "Majority:");
    draw_bottom(win, ok);
    draw_bottom(win, name_b);
    draw_bottom(win, exit);
    draw_bottom(win, class_b);
    draw_bottom(win, majority_b);
    wrefresh(win); // 刷新窗口
}


void
draw_signin_window(WINDOW *win, struct bottom *signin, struct bottom *user, struct bottom *psword,
                   struct bottom *exit) {
    // 清空窗口并绘制边框
    wclear(win);
    box(win, 0, 0);

    // 标题
    mvwprintw(win, 1, (WIN_WIDTH - 10) / 2, "Signin");

    // 用户名输入框
    mvwprintw(win, 3, 4, "Username:");

    // 密码输入框
    mvwprintw(win, 6, 4, "Password:");
    //绘制剩余内容
    draw_bottom(win, signin);
    draw_bottom(win, exit);
    draw_bottom(win, user);
    draw_bottom(win, psword);
    wrefresh(win); // 刷新窗口
}

void
draw_StudentDesktop_window(WINDOW *win, struct bottom *bt1, struct bottom *bt2, struct bottom *bt3,
                           struct bottom *bt4) {
    // 清空窗口并绘制边框
    wclear(win);
    box(win, 0, 0);

    // 标题
    mvwprintw(win, 1, 1, "Welcome! dear %s", Username);

    //绘制剩余内容

    draw_bottom(win, bt1);
    draw_bottom(win, bt2);
    draw_bottom(win, bt3);
    draw_bottom(win, bt4);

    wrefresh(win); // 刷新窗口
}

void
draw_TeacherDesktop_window(WINDOW *win, struct bottom *bt1, struct bottom *bt2, struct bottom *bt3,
                           struct bottom *bt4) {
    // 清空窗口并绘制边框
    wclear(win);
    box(win, 0, 0);

    // 标题
    mvwprintw(win, 1, 1, "Welcome! Doctor %s", Username);

    //绘制剩余内容

    draw_bottom(win, bt1);
    draw_bottom(win, bt2);
    draw_bottom(win, bt3);
    draw_bottom(win, bt4);

    wrefresh(win); // 刷新窗口
}

void get_input(WINDOW *win, int y, int x, char *buffer, int max_len, struct bottom *bot, int sx, int sy) {
    MEVENT event;
    int ch, pos = 0;
    char *test = bot->test;
    while (pos < max_len && buffer[pos] != '\0')pos++;
    while (1) {
        ch = wgetch(win);
        if (ch == KEY_BACKSPACE || ch == 8) { // 处理退格键
            if (pos > 0) {
                pos--;
                buffer[pos] = '\0';
                if(bot->private!=2)test[pos + 1] = '_';
                else test[pos]='\0';
                mvwprintw(win,1,8,"                              ");
                draw_bottom(win, bot);
                wrefresh(win);
            }
        } else if (ch == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (!click_bottom(event, *bot, sx, sy)) {
                    return;
                }
            }
        } else if (pos < max_len - 1) {
            if (bot->private == 1) {
                if (ch >= 33 && ch <= 126) {}
                else {
                    mvwprintw(win, 12, 5, "Incorrect input");
                    wrefresh(win);
                    continue;
                }
            } else if (bot->private == 0) {
                if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9') {}
                else {
                    mvwprintw(win, 12, 5, "Incorrect input");
                    wrefresh(win);
                    continue;
                }
            } else if (bot->private == 2) {
                if (ch >= '0' && ch <= '9' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' ||ch == ')') {}
                else {
                    mvwprintw(win, 12, 5, "Incorrect input");
                    wrefresh(win);
                    continue;
                }
            }
            buffer[pos++] = ch;
            if (bot->private == 0)test[pos] = ch;
            else if(bot->private == 1)test[pos] = '*';
            else if(bot->private == 2)test[pos-1]=ch;
            draw_bottom(win, bot);
            wrefresh(win);
        }
        if(ch=='\n')return;
    }
}

void get_input_ez(WINDOW *win, int y, int x, char *buffer, int max_len) {
    mvwprintw(win,y,x,"input here:");
    int ch, pos = 0;
    memset(buffer, 0, max_len); // 清空缓冲区

    while ((ch = wgetch(win)) != '\n') { // 按回车结束输入
        if (ch == 8 || ch == 127) { // 处理退格键
            if (pos > 0) {
                pos--;           // 移动到前一个字符位置
                buffer[pos] = '\0'; // 删除字符
                mvwprintw(win,y, x+11, "%s ", buffer);
                wrefresh(win);
                mvwprintw(win,y, x+11, "%s", buffer);
            }
        } else if (pos < max_len - 1 && ch >= 32 && ch <= 126) { // 可打印字符
            buffer[pos++] = ch; // 将字符加入输入内容
            buffer[pos] = '\0'; // 添加字符串结束符
            mvwprintw(win,y, x+11, "%s", buffer); // 在窗口中实时显示输入
        }
    }
}

int *display_t_test_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
                          struct bottom *right, struct bottom *exit,struct bottom *create) {
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;
    int row_count = 0;
    char *sql_query="select test_name,Creater,problems_count,ID from tests";
    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return 0;
    }
    int *id=malloc(PAGE_SIZE*sizeof(int));
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 3, 1, "Name        Creater          problem_count      operate   ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_count < PAGE_SIZE) {
        const char *name = (const char *) sqlite3_column_text(stmt, 0);
        const char *creater = (const char *) sqlite3_column_text(stmt, 1);
        int problem_c =  sqlite3_column_int(stmt, 2);
        int now_id= sqlite3_column_int(stmt,3);
        *(id+row_count)=now_id;
        // 输出当前行
        mvwprintw(win, (current_row * 2) - 5, 1, "%-11s %-16s %-24d", name, creater, problem_c);
        start_color();
        init_pair(1, COLOR_BLACK, COLOR_WHITE);
        wattron(win, COLOR_PAIR(1));
        mvwprintw(win, (current_row * 2) - 5, 49, "delete");
        wattroff(win, COLOR_PAIR(1));
        row_count++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, exit);
    draw_bottom(win,create);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return id;
}

int *display_stu_test_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
                         struct bottom *right, struct bottom *exit,int *t_l) {
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;
    int row_count = 0;
    char *sql_query="select test_name,Creater,problems_count,ID from tests";
    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return 0;
    }
    int *id=malloc(PAGE_SIZE*sizeof(int));
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    *t_l=total_rows;
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 3, 1, "Name        Creater          problem_count      operate   ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_count < PAGE_SIZE) {
        const char *name = (const char *) sqlite3_column_text(stmt, 0);
        const char *creater = (const char *) sqlite3_column_text(stmt, 1);
        int problem_c =  sqlite3_column_int(stmt, 2);
        int now_id= sqlite3_column_int(stmt,3);
        *(id+row_count)=now_id;
        // 输出当前行
        mvwprintw(win, (current_row * 2) - 5, 1, "%-11s %-16s %-24d", name, creater, problem_c);
        start_color();
        init_pair(1, COLOR_BLACK, COLOR_WHITE);
        wattron(win, COLOR_PAIR(1));
        mvwprintw(win, (current_row * 2) - 5, 49, "enter");
        wattroff(win, COLOR_PAIR(1));
        row_count++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, exit);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return id;
}
int Login_ui() {
    MEVENT event;
    char *errmsg[30];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *login_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(login_win, TRUE);
    char *username[15];      //储存用户名
    memset(username, '\0', 15); // 清空缓冲区
    char *password[15];      //储存密码
    memset(password, '\0', 15); // 清空缓冲区
    struct bottom *login = creat_bottom(login_win, 10, 4, 5, 1, "Login");
    struct bottom *signin = creat_bottom(login_win, 10, 14, 5, 1, "Signin");
    struct bottom *exit = creat_bottom(login_win, 10, 25, 5, 1, "Exit");
    struct bottom *users = creat_bottom(login_win, 4, 4, 16, 1, "[______________]");
    struct bottom *psword = creat_bottom(login_win, 7, 4, 16, 1, "[______________]");
    psword->private = 1;
    users->private = 0;
    int willdraw = 1;
    while (1) {
        if (willdraw)draw_login_window(login_win, login, signin, users, psword, exit);
        int rc = wgetch(login_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
                if (willdraw)
                    if (click_bottom(event, *login, start_x, start_y)) {
                        int recall;
                        Login(username, password, &recall, errmsg);
                        if (recall == -1) {
                            wclear(login_win);
                            mvwprintw(login_win, 5, 5, "%s", errmsg);
                            exit->x = 5;
                            exit->y = 8;
                            draw_bottom(login_win, exit);
                            wrefresh(login_win);
                            willdraw = 0;
                            continue;
                        } else {
                            free(login);
                            free(signin);
                            free(exit);
                            free(users);
                            free(psword);
                            endwin();
                            return recall;
                        }
                    }
                if (willdraw)
                    if (click_bottom(event, *signin, start_x, start_y)) {
                        free(login);
                        free(signin);
                        free(exit);
                        free(users);
                        free(psword);
                        endwin();
                        return SIGNIN_UI;
                    }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(login);
                    free(signin);
                    free(exit);
                    free(users);
                    free(psword);
                    endwin();
                    return willdraw == 1 ? WELCOME_UI : LOGIN_UI;
                }
                if (willdraw)
                    if (click_bottom(event, *users, start_x, start_y)) {
                        get_input(login_win, 4, 6, username, 15, users, start_x, start_y);
                        continue;
                    }
                if (willdraw)
                    if (click_bottom(event, *psword, start_x, start_y)) {
                        get_input(login_win, 7, 6, password, 15, psword, start_x, start_y);
                        continue;
                    }
            }
        }
    }
}

int Signin_ui() {
    MEVENT event;
    char *errmsg[100];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *signin_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(signin_win, TRUE);
    char *username[15];      //储存用户名
    memset(username, '\0', 15); // 清空缓冲区
    char *password[15];      //储存密码
    memset(password, '\0', 15); // 清空缓冲区
    struct bottom *signin = creat_bottom(signin_win, 10, 4, 5, 1, "Signin");
    struct bottom *exit = creat_bottom(signin_win, 10, 25, 5, 1, "Exit");
    struct bottom *users = creat_bottom(signin_win, 4, 4, 16, 1, "[______________]");
    struct bottom *psword = creat_bottom(signin_win, 7, 4, 16, 1, "[______________]");
    psword->private = 0;
    users->private = 0;
    int willdraw = 1;
    while (1) {
        if (willdraw == 1)draw_signin_window(signin_win, signin, users, psword, exit);
        int rc = wgetch(signin_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
                if (willdraw == 1)
                    if (click_bottom(event, *signin, start_x, start_y)) {
                        int recall;
                        Signin(username, password, &recall, errmsg);
                        if (recall != 0) {
                            wclear(signin_win);
                            mvwprintw(signin_win, 5, 5, "%s", errmsg);
                            exit->x = 5;
                            exit->y = 8;
                            draw_bottom(signin_win, exit);
                            wrefresh(signin_win);
                            willdraw = 2;
                            continue;
                        } else {
                            wclear(signin_win);
                            mvwprintw(signin_win, 5, 5, "Accepted");
                            exit->x = 5;
                            exit->y = 8;
                            draw_bottom(signin_win, exit);
                            wrefresh(signin_win);
                            willdraw = 0;
                            continue;
                        }
                    }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(signin);
                    free(exit);
                    free(users);
                    free(psword);
                    endwin();
                    return willdraw == 2 ? SIGNIN_UI : WELCOME_UI;
                }
                if (willdraw == 1)
                    if (click_bottom(event, *users, start_x, start_y)) {
                        get_input(signin_win, 4, 6, username, 15, users, start_x, start_y);
                        continue;
                    }
                if (willdraw == 1)
                    if (click_bottom(event, *psword, start_x, start_y)) {
                        get_input(signin_win, 7, 6, password, 15, psword, start_x, start_y);
                        continue;
                    }
            }
        }
    }
}

int stu_type_ui() {
    int recall = stu_type_check();
    if (recall == -1)myexit();
    if (recall == 1)return 0;
    MEVENT event;
    char *errmsg[30];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *stu_type_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(stu_type_win, TRUE);
    char *name[15];      //储存用户名
    memset(name, '\0', 15); // 清空缓冲区
    char *majority[15];      //储存用户名
    memset(majority, '\0', 15); // 清空缓冲区
    char *class[15];      //储存密码
    memset(class, '\0', 15); // 清空缓冲区
    struct bottom *ok = creat_bottom(stu_type_win, 13, 4, 5, 1, "OK");
    struct bottom *exit = creat_bottom(stu_type_win, 13, 25, 5, 1, "Exit");
    struct bottom *name_b = creat_bottom(stu_type_win, 4, 4, 16, 1, "[______________]");
    struct bottom *class_b = creat_bottom(stu_type_win, 7, 4, 16, 1, "[______________]");
    struct bottom *majority_b = creat_bottom(stu_type_win, 10, 4, 16, 1, "[______________]");
    name_b->private = 0;
    class_b->private = 0;
    majority_b->private = 0;
    int willdraw = 1;
    while (1) {
        if (willdraw)draw_stu_type_window(stu_type_win, ok, name_b, class_b, majority_b, exit);
        int rc = wgetch(stu_type_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                //mvwprintw(welcome_win, 3, 1, "Mouse at (%d, %d), button %d", event.x-start_x, event.y-start_y, event.bstate);
                if (willdraw)
                    if (click_bottom(event, *ok, start_x, start_y)) {
                        int recall;
                        stu_type_insert(name, class, majority, &recall, errmsg);
                        if (recall == -1) {
                            wclear(stu_type_win);
                            mvwprintw(stu_type_win, 5, 5, "%s", errmsg);
                            exit->x = 5;
                            exit->y = 8;
                            draw_bottom(stu_type_win, exit);
                            wrefresh(stu_type_win);
                            willdraw = 0;
                            continue;
                        } else {
                            free(ok);
                            free(name_b);
                            free(exit);
                            free(class_b);
                            free(majority_b);
                            endwin();
                            return 0;
                        }
                    }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(ok);
                    free(exit);
                    free(name_b);
                    free(class_b);
                    free(majority_b);
                    endwin();
                    return -1;
                }
                if (willdraw)
                    if (click_bottom(event, *name_b, start_x, start_y)) {
                        get_input(stu_type_win, 4, 6, name, 15, name_b, start_x, start_y);
                        continue;
                    }
                if (willdraw)
                    if (click_bottom(event, *class_b, start_x, start_y)) {
                        get_input(stu_type_win, 7, 6, class, 15, class_b, start_x, start_y);
                        continue;
                    }
                if (willdraw)
                    if (click_bottom(event, *majority_b, start_x, start_y)) {
                        get_input(stu_type_win, 4, 6, majority, 15, majority_b, start_x, start_y);
                        continue;
                    }
            }
        }
    }

}

int StudentsDesktop_ui() {
    int recall = stu_type_ui();
    if (recall == -1) {
        memset(Username, 0, 15);
        return WELCOME_UI;
    }
    MEVENT event;
    char *errmsg[30];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *StudentsDesktop_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(StudentsDesktop_win, TRUE);
    struct bottom *test = creat_bottom(StudentsDesktop_win, 3, 4, 6, 1, "1.Test");
    struct bottom *hissc = creat_bottom(StudentsDesktop_win, 6, 4, 15, 1, "2.History Score");
    struct bottom *exercise = creat_bottom(StudentsDesktop_win, 9, 4, 10, 1, "3.Exercise");
    struct bottom *exit = creat_bottom(StudentsDesktop_win, 12, 4, 6, 1, "4.Exit");
    while (1) {
        draw_StudentDesktop_window(StudentsDesktop_win, test, hissc, exercise, exit);
        int rc = wgetch(StudentsDesktop_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *test, start_x, start_y)) {
                    int recall;

                    stu_test_ui(&recall, errmsg, class);
                    if (recall != 0) {
                        wclear(StudentsDesktop_win);
                        mvwprintw(StudentsDesktop_win, 1, 1, errmsg);
                        sqlite3_sleep(2000);
                    }
                    continue;
                }
                if (click_bottom(event, *hissc, start_x, start_y)) {
                    stu_his_sc_ui();
                    continue;
                }
                if (click_bottom(event, *exercise, start_x, start_y)) {
                    stu_exercise_ui();
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(test);
                    free(hissc);
                    free(exit);
                    free(exercise);
                    endwin();
                    memset(Username, 0, 15);
                    return WELCOME_UI;
                }
            }
        }
    }
}

void stu_exercise_ui() {

}

void display_stu_score_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *exit, struct bottom *search,int *row_count){
    char *sql_query="select majority,class,name,test_name,score from stu where user=? and test_name like ?";
    int *id=malloc(PAGE_SIZE*sizeof(int));
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;

    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return;
    }
    char query[100];
    memset(query,0,sizeof(query));
    snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
    sqlite3_bind_text(stmt, 1, Username, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, query, -1, SQLITE_STATIC);
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    *row_count=total_rows;
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 1, 1, "Search:");
    mvwprintw(win, 3, 1, "majority      class      name       test_name       score ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    int row_c=0;
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
        const char *majority = (const char *) sqlite3_column_text(stmt, 0);
        const char *class = (const char *) sqlite3_column_text(stmt, 1);
        const char *name = (const char *) sqlite3_column_text(stmt, 2);
        const char *test_name = (const char *) sqlite3_column_text(stmt, 3);
        int score = sqlite3_column_int(stmt, 4);
        // 输出当前行
        mvwprintw(win, (current_row * 2) - 5, 1, "%-13s %-10s %-10s %-15s %-5d",majority,class,name,test_name,score);
        row_c++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, exit);
    draw_bottom(win, search);
    draw_bottom(win, add);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return;
}

void display_t_score_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *exit, struct bottom *search,int *row_count){
    char *sql_query="select majority,class,name,test_name,score from stu where test_name like ?";
    int *id=malloc(PAGE_SIZE*sizeof(int));
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;

    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return;
    }
    char query[100];
    memset(query,0,sizeof(query));
    snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
    sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    *row_count=total_rows;
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 1, 1, "Search:");
    mvwprintw(win, 3, 1, "majority      class      name       test_name       score ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    int row_c=0;
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
        const char *majority = (const char *) sqlite3_column_text(stmt, 0);
        const char *class = (const char *) sqlite3_column_text(stmt, 1);
        const char *name = (const char *) sqlite3_column_text(stmt, 2);
        const char *test_name = (const char *) sqlite3_column_text(stmt, 3);
        int score = sqlite3_column_int(stmt, 4);
        // 输出当前行
        mvwprintw(win, (current_row * 2) - 5, 1, "%-13s %-10s %-10s %-15s %-5d",majority,class,name,test_name,score);
        row_c++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, exit);
    draw_bottom(win, search);
    draw_bottom(win, add);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return;
}

void stu_his_sc_ui() {
    MEVENT event;
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *stu_score_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(stu_score_win, TRUE);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    const char *sql_query;  // 查询 SQL
    struct bottom *left = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *exit = creat_bottom(stu_score_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
    struct bottom *search = creat_bottom(stu_score_win, 1, 8, 20, 1, "");
    memset(search->test,0,30);
    search->private = 2;
    char searchq[100];
    memset(searchq, 0, 100);
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        return;
    }
    int *id;
    sqlite3_stmt *stmt;
    int row_count = 0;
    while (1) {
        // 清空窗口内容
        werase(stu_score_win);
        box(stu_score_win, 0, 0);
        // 调用函数输出当前的滚动窗口内容
        display_stu_score_page(stu_score_win, db, offset, left, right, exit, search,&row_count);

        int rc = wgetch(stu_score_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    delwin(stu_score_win);
                    return;
                }
                if (click_bottom(event, *search, start_x, start_y)) {
                    get_input(stu_score_win, 4, 6, searchq, 15, search, start_x, start_y);
                    offset = 0;
                    continue;
                }
            }
        }
    }
}

void t_his_sc_ui() {
    MEVENT event;
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *t_score_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(t_score_win, TRUE);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    const char *sql_query;  // 查询 SQL
    struct bottom *left = creat_bottom(t_score_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(t_score_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *exit = creat_bottom(t_score_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
    struct bottom *search = creat_bottom(t_score_win, 1, 8, 20, 1, "");
    memset(search->test,0,30);
    search->private = 2;
    char searchq[100];
    memset(searchq, 0, 100);
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        return;
    }
    int *id;
    sqlite3_stmt *stmt;
    int row_count = 0;
    while (1) {
        // 清空窗口内容
        werase(t_score_win);
        box(t_score_win, 0, 0);
        // 调用函数输出当前的滚动窗口内容
        display_t_score_page(t_score_win, db, offset, left, right, exit, search,&row_count);

        int rc = wgetch(t_score_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    delwin(t_score_win);
                    return;
                }
                if (click_bottom(event, *search, start_x, start_y)) {
                    get_input(t_score_win, 4, 6, searchq, 15, search, start_x, start_y);
                    offset = 0;
                    continue;
                }
            }
        }
    }
}

void enter(WINDOW *win,sqlite3 *db,int id,int start_x,int start_y){
    int offset=0;
    int correct_conuts=0;
    int total_rows = 0;
    double answer;
    struct bottom *exit = creat_bottom(win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
    while(1){
        wclear(win);
        box(win, 0, 0);
        sqlite3_stmt *stmt;
        int rc;
        char *sql_query="select text,answer from test_include where test_index=?";
        // 准备 SQL 语句
        rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
        if (rc != SQLITE_OK) {
            mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
            wrefresh(win);
            return;
        }
        sqlite3_bind_int(stmt,1,id);
        // 计算总行数
        total_rows=0;
        while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
            total_rows++;
        }
        sqlite3_reset(stmt);  // 重置stmt以便重新执行查询
        // 跳到指定的偏移位置
        for (int i = 0; i < offset; i++) {
            sqlite3_step(stmt);  // 跳过前面的行
        }
        // 从指定的偏移位置开始，显示10行
        if((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
            const char *name = (const char *) sqlite3_column_text(stmt, 0);
            answer = sqlite3_column_double(stmt, 1);
            int now_id= sqlite3_column_int(stmt,2);
            // 输出当前行
            mvwprintw(win, 15, 15, "%-22s", name);
        }

        // 打印分页信息
        mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Problem: %d/%d", offset + 1,total_rows);
        draw_bottom(win, exit);
        mvwprintw(win, 17, 15, "Please input your answer:", offset + 1,total_rows);
        // 刷新窗口
        wrefresh(win);

        double ans;
        cbreak();  // 禁用行缓冲
        noecho();  // 禁用自动回显
        curs_set(1); // 显示光标
        mvwscanw(win,18,15,"%lf",&ans);

        mvwprintw(win,18,15,"Your answer:%.3lf",ans);
        mvwprintw(win,19,15,"standard answer:%.3lf",answer);

        if(abs(ans-answer)<0.01){
            mvwprintw(win,20,15,"Accepted");
            correct_conuts++;
        }
        else{
            mvwprintw(win,20,15,"Wrong answer");
        }
        wrefresh(win);
        sqlite3_finalize(stmt);
        sqlite3_sleep(2000);
        offset++;
        if(offset==total_rows)break;
    }
    wclear(win);
    mvwprintw(win,15,15,"The text has finished.");
    int score=(double)correct_conuts/(double)total_rows*100;
    mvwprintw(win,16,15,"Your Score is:%d",score);wrefresh(win);
    sqlite3_sleep(5000);
    sqlite3_stmt *stmt;
    int rc;
    char *sql_select="select test_name from tests where ID=?;";
    rc = sqlite3_prepare_v2(db, sql_select, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        return;
    }
    char *db_test_name;
    // 绑定查询参数
    sqlite3_bind_int(stmt, 1, id);
    rc = sqlite3_step(stmt);
    if (rc == SQLITE_ROW) {

        db_test_name =  sqlite3_column_text(stmt, 0);
    }
    else{
        sqlite3_finalize(stmt);
        free(exit);
        return;
    }
    char *sql_query = "insert into stu (majority,class,name,test_name,test_index,score,user) select majority,class,name,?,?,?,user from students where user=?;";
    // 编译 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        sqlite3_finalize(stmt);
        sqlite3_close(db);
        return;
    }

    sqlite3_bind_text(stmt,1,db_test_name,-1,SQLITE_STATIC);
    sqlite3_bind_int(stmt,2,id);
    sqlite3_bind_int(stmt,3,score);
    sqlite3_bind_text(stmt,4,Username,-1,SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        sqlite3_finalize(stmt);
        free(exit);
        return;
    }
    sqlite3_finalize(stmt);
    while(1) {
        MEVENT event;
        draw_bottom(win,exit);
        wrefresh(win);
        int rc = wgetch(win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(exit);
                    return;
                }
            }
        }
    }
}

void stu_test_ui(int *recall, char *errmsg, char *class) {
    MEVENT event;
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *stu_problem_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(stu_problem_win, TRUE);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    const char *sql_query;  // 查询 SQL
    struct bottom *left = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *exit = creat_bottom(stu_problem_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        *recall = -1;
        return;
    }
    int *id;
    sqlite3_stmt *stmt;
    int row_count = 0;
    while (1) {
        // 清空窗口内容
        werase(stu_problem_win);
        box(stu_problem_win, 0, 0);
        // 调用函数输出当前的滚动窗口内容
        id = display_stu_test_page(stu_problem_win, db, offset, left, right, exit,&row_count);

        int rc = wgetch(stu_problem_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    free(id);
                    sqlite3_close(db);
                    delwin(stu_problem_win);
                    return;
                }
                if (event.x - start_x >= 49 && event.x - start_x <= 53) {           //enter
                    int test_id=*(id+(((event.y-start_y)+5)/2-5));
                    enter(stu_problem_win,db,test_id,start_x,start_y);
                }
            }
        }
    }
}

void t_test_ui(int *recall, char *errmsg) {
    MEVENT event;
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *t_test_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(t_test_win, TRUE);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    const char *sql_query;  // 查询 SQL
    struct bottom *left = creat_bottom(t_test_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(t_test_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *exit = creat_bottom(t_test_win, WIN_HEIGHT - 3, 52, 2, 1, "Exit");
    struct bottom *create = creat_bottom(t_test_win,1,52,6,1,"Create");
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        strcpy(errmsg, "Error:database error");
        *recall = -1;
        return;
    }

    sqlite3_stmt *stmt;
    const char *sql = "SELECT COUNT(*) FROM tests;";
    int row_count = 0;

    // 准备 SQL 查询
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        strcpy(errmsg, "Error:database error");
        sqlite3_close(db);
        sqlite3_finalize(stmt);
        *recall = -1;
        return;
    }
    rc = sqlite3_step(stmt);
    if (rc == SQLITE_ROW) {
        // 获取 COUNT(*) 的值，列索引是 0
        row_count = sqlite3_column_int(stmt, 0);
    } else {
        strcpy(errmsg, "Error:database error");
        sqlite3_close(db);
        sqlite3_finalize(stmt);
        *recall = -1;
        return;
    }
    sqlite3_finalize(stmt);
    while (1) {
        // 清空窗口内容
        werase(t_test_win);
        box(t_test_win, 0, 0);

        // 调用函数输出当前的滚动窗口内容
        int *id=display_t_test_page(t_test_win, db, offset, left, right, exit,create);
        if(id==NULL){
            sqlite3_close(db);
            sqlite3_finalize(stmt);
            return;
        }
        int rc = wgetch(t_test_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    sqlite3_close(db);
                    *recall = 0;
                    return;
                }
                if(click_bottom(event,*create,start_x,start_y)){
                    create_ui();
                    continue;
                }
                if (event.x-start_x >= 49 && event.x-start_x <= 54) {           //delete
                    sql_query="delete from tests where ID=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
                    if (rc != SQLITE_OK) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
                    rc = sqlite3_step(stmt);
                    if (rc != SQLITE_DONE) {
                        sqlite3_finalize(stmt);
                        return;
                    }
                    sql_query="delete from test_include where test_index=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
                    if (rc != SQLITE_OK) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
                    rc = sqlite3_step(stmt);
                    if (rc != SQLITE_DONE) {
                        sqlite3_finalize(stmt);
                        return;
                    }
                    sqlite3_finalize(stmt);
                    continue;
                }
            }
        }
    }
}


int *display_t_problem_page(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,
                            struct bottom *right, struct bottom *exit, struct bottom *search, struct bottom *add,int *row_count) {
    char *sql_query="select text,answer,ID from timu where text like ?";
    int *id=malloc(PAGE_SIZE*sizeof(int));
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;

    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return 0;
    }
    char query[100];
    memset(query,0,sizeof(query));
    snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
    sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    *row_count=total_rows;
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 1, 1, "Search:");
    mvwprintw(win, 3, 1, "timu                   answer               operate       ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    int row_c=0;
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
        const char *name = (const char *) sqlite3_column_text(stmt, 0);
        double answer = sqlite3_column_double(stmt, 1);
        int now_id= sqlite3_column_int(stmt,2);
        *(id+row_c)=now_id;
        // 输出当前行
        if(floor(answer)==answer)mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %d", name, (int)answer);
        else mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %lf", name, answer);
        start_color();
        init_pair(1, COLOR_BLACK, COLOR_WHITE);
        wattron(win, COLOR_PAIR(1));
        mvwprintw(win, (current_row * 2) - 5, 42, "update");
        mvwprintw(win, (current_row * 2) - 5, 52, "delete");
        wattroff(win, COLOR_PAIR(1));
        row_c++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, exit);
    draw_bottom(win, search);
    draw_bottom(win, add);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return id;
}

int add_ui(){
    keypad(stdscr, FALSE); // 启用功能键（如退格键）
    curs_set(1);        // 显示光标
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *add_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    char test[9999];
    memset(test,0,9999);
    int pos = 0;
    char ch;
    while (1) { // 按下 Ctrl+G 结束输入
        mvwprintw(add_win,1,1,"input the text,enter means next row.Ctrl+G to exit.\n");
        wrefresh(add_win);
        ch= wgetch(add_win);
        if(ch==7) {
            delwin(add_win);
            break;
        }
        if(ch=='\n'){
            int recall;
            char *errmsg[100];
            add(test,&recall,errmsg);
            memset(test,0,sizeof(test));
            pos=0;
            if(recall==-1){
                wclear(add_win);
                mvwprintw(add_win,1,1,"Error:%s",errmsg);
                wrefresh(add_win);
                sqlite3_sleep(2000);
                continue;
            }
            else if(recall==1){
                wclear(add_win);continue;
            }
            else{
                wclear(add_win);
                mvwprintw(add_win,1,1,"Accept.");
                wrefresh(add_win);
                sqlite3_sleep(2000);
                continue;
            }
        }
        if (ch == 8 || ch == 127) { // 处理退格键
            if (pos > 0) {
                pos--;           // 移动到前一个字符位置
                test[pos] = '\0'; // 删除字符
                mvwprintw(add_win,3, 0, "%s ", test); // 用空格清除多余字符
                wrefresh(add_win);
                mvwprintw(add_win,3, 0, "%s", test); // 用空格清除多余字符
            }
        } else if ((ch >= 32 && ch <= 126||ch=='\n')) { // 处理可显示字符
            if (pos < 9999 - 1) {
                test[pos++] = ch; // 将字符加入输入内容
                test[pos] = '\0'; // 添加字符串结束符
                mvwprintw(add_win,3, 0, "%s", test); // 在窗口中实时显示输入
            }
        }
        wrefresh(add_win); // 更新窗口显示
    }
    curs_set(0);
    endwin();
    return T_PROBLEM_UI;
}

int t_problem_ui() {
    MEVENT event;
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *t_problem_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(t_problem_win, TRUE);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    const char *sql_query;  // 查询 SQL
    struct bottom *left = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *exit = creat_bottom(t_problem_win, WIN_HEIGHT - 3, 52, 4, 1, "Exit");
    struct bottom *add = creat_bottom(t_problem_win, 1, 54, 3, 1, "Add");
    struct bottom *search = creat_bottom(t_problem_win, 1, 8, 20, 1, "");
    memset(search->test,0,30);
    search->private = 2;
    char searchq[100];
    memset(searchq, 0, 100);
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        return TEACHER_UI;
    }
    int *id;
    sqlite3_stmt *stmt;
    int row_count = 0;
    while (1) {
        // 清空窗口内容
        werase(t_problem_win);
        box(t_problem_win, 0, 0);
        // 调用函数输出当前的滚动窗口内容
        id=display_t_problem_page(t_problem_win, db, offset, left, right, exit, search, add,&row_count);

        int rc = wgetch(t_problem_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    free(id);
                    sqlite3_close(db);
                    delwin(t_problem_win);
                    return TEACHER_UI;
                }
                if (click_bottom(event, *add, start_x, start_y)) {
                    free(left);
                    free(right);
                    free(exit);
                    free(id);
                    sqlite3_close(db);
                    delwin(t_problem_win);
                    return ADD_UI;
                }
                if (click_bottom(event, *search, start_x, start_y)) {
                    get_input(t_problem_win, 4, 6, searchq, 15, search, start_x, start_y);
                    offset=0;
                    continue;
                }
                if (event.x-start_x >= 52 && event.x-start_x <= 57) {           //delete
                    sql_query="delete from timu where ID=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
                    if (rc != SQLITE_OK) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
                    rc = sqlite3_step(stmt);
                    if (rc != SQLITE_DONE) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_finalize(stmt);
                    continue;
                }
                if (event.x-start_x >= 42 && event.x-start_x <= 47) {           //update

                    sql_query="update timu set text=? ,answer=? where ID=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
                    if (rc != SQLITE_OK) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    char input[9999];
                    memset(input,0,sizeof(input));
                    get_input_ez(t_problem_win, WIN_HEIGHT-2,1, input, 15);
                    double ans;
                    int recall=0;
                    sqlite3_bind_text(stmt, 1, input,-1,SQLITE_STATIC);
                    char errmsg[100];
                    calculate(input,&recall,errmsg,&ans);
                    if(recall==-1){
                        mvwprintw(t_problem_win,WIN_HEIGHT-2,1,"Incorrect input!");
                        sqlite3_sleep(1000);
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_bind_double(stmt, 2, ans);
                    sqlite3_bind_int(stmt, 3, *(id+(((event.y-start_y)+5)/2-5)));
                    rc = sqlite3_step(stmt);
                    if (rc != SQLITE_DONE) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_finalize(stmt);
                    continue;
                }
            }
        }
    }
}

int TeachersDesktop_ui() {
    MEVENT event;
    char *errmsg[30];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *TeacherDesktop_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(TeacherDesktop_win, TRUE);
    struct bottom *test = creat_bottom(TeacherDesktop_win, 3, 4, 14, 1, "1.Test desktop");
    struct bottom *problem = creat_bottom(TeacherDesktop_win, 6, 4, 17, 1, "2.Problem desktop");
    struct bottom *score = creat_bottom(TeacherDesktop_win, 9, 4, 13, 1, "3.Score check");
    struct bottom *exit = creat_bottom(TeacherDesktop_win, 12, 4, 6, 1, "4.Exit");
    while (1) {
        draw_TeacherDesktop_window(TeacherDesktop_win, test, problem, score, exit);
        int rc = wgetch(TeacherDesktop_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *test, start_x, start_y)) {
                    int recall=0;
                    t_test_ui(&recall,errmsg);
                }
                if (click_bottom(event, *score, start_x, start_y)) {
                    t_his_sc_ui();
                    continue;
                }
                if (click_bottom(event, *problem, start_x, start_y)) {
                    int recall;
                    return T_PROBLEM_UI;
                }
                if (click_bottom(event, *exit, start_x, start_y)) {
                    free(test);
                    free(score);
                    free(exit);
                    free(problem);
                    endwin();
                    memset(Username, 0, 15);
                    return WELCOME_UI;
                }
            }
        }
    }
}

int *display_t_problem_page_2(WINDOW *win, sqlite3 *db, int offset, struct bottom *left,struct bottom *right, struct bottom *ok, struct bottom *search,int *row_count,Node *head){
    char *sql_query="select text,answer,ID from timu where text like ?";
    int *id=malloc(PAGE_SIZE*sizeof(int));
    wclear(win);
    box(win, 0, 0);
    sqlite3_stmt *stmt;
    int rc;

    // 准备 SQL 语句
    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        mvwprintw(win, 0, 0, "Failed to prepare statement: %s", sqlite3_errmsg(db));
        wrefresh(win);
        return 0;
    }
    char query[100];
    memset(query,0,sizeof(query));
    snprintf(query, sizeof(query), "%%%s%%", search->test); // 构造 LIKE 查询参数
    sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC);
    // 计算总行数
    int total_rows = 0;
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        total_rows++;
    }
    *row_count=total_rows;
    sqlite3_reset(stmt);  // 重置stmt以便重新执行查询

    // 设置窗口的高度和宽度
    // 显示表格的头部
    mvwprintw(win, 1, 1, "Search:");
    mvwprintw(win, 3, 1, "timu                   answer               operate       ");
    mvwprintw(win, 4, 1, "----------------------------------------------------------");

    // 跳到指定的偏移位置
    for (int i = 0; i < offset; i++) {
        sqlite3_step(stmt);  // 跳过前面的行
    }
    int row_c=0;
    // 从指定的偏移位置开始，显示10行
    int current_row = 5;  // 数据开始显示的位置
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW && row_c < PAGE_SIZE) {
        const char *name = (const char *) sqlite3_column_text(stmt, 0);
        double answer = sqlite3_column_double(stmt, 1);
        int now_id= sqlite3_column_int(stmt,2);
        *(id+row_c)=now_id;
        // 输出当前行
        if(floor(answer)==answer)mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %d", name, (int)answer);
        else mvwprintw(win, (current_row * 2) - 5, 1, "%-22s %lf", name, answer);
        start_color();
        init_pair(1, COLOR_BLACK, COLOR_WHITE);
        if(!list_search(head,now_id))
        {
            wattron(win, COLOR_PAIR(1));
            mvwprintw(win, (current_row * 2) - 5, 45, "select");
            wattroff(win, COLOR_PAIR(1));
        }
        else mvwprintw(win, (current_row * 2) - 5, 45, "selected");
        row_c++;
        current_row++;
    }

    // 打印分页信息
    mvwprintw(win, WIN_HEIGHT - 3, (WIN_WIDTH - 9) / 2, "Page: %d/%d", (offset / PAGE_SIZE) + 1,
              max(1,(total_rows + PAGE_SIZE - 1) / PAGE_SIZE));
    draw_bottom(win, left);
    draw_bottom(win, right);
    draw_bottom(win, ok);
    draw_bottom(win, search);
    // 刷新窗口
    wrefresh(win);

    sqlite3_finalize(stmt);
    return id;
}

// 插入节点到链表末尾



void create_ui(){
    MEVENT event;
    char *errmsg[30];
    memset(errmsg, 0, 30);
    int start_y = (LINES - WIN_HEIGHT) / 2;
    int start_x = (COLS - WIN_WIDTH) / 2;
    WINDOW *create_win = newwin(WIN_HEIGHT, WIN_WIDTH, start_y, start_x);
    keypad(create_win, TRUE);

    box(create_win,0,0);
    mvwprintw(create_win,1,1,"Please input your test name:");
    char testname[300];
    get_input_ez(create_win,1,28,testname,300);
    wclear(create_win);
    int offset = 0;
    sqlite3 *db;
    const char *db_filename = "./data/msg.db";  // SQLite 数据库文件名
    // 打开数据库
    if (sqlite3_open(db_filename, &db) != SQLITE_OK) {
        return;
    }
    const char *sql_query;  // 查询 SQL
    int rc;

    sql_query="select * from tests where test_name=?";
    sqlite3_stmt *sqlsearch;
    rc = sqlite3_prepare_v2(db, sql_query, -1, &sqlsearch, 0);
    if (rc != SQLITE_OK) {
        strcpy(errmsg,"Error:database error.");
        sqlite3_close(db);
        return;
    }
    sqlite3_bind_text(sqlsearch, 1, testname, -1, SQLITE_STATIC);

    rc = sqlite3_step(sqlsearch);

    if(rc==SQLITE_ROW){
        wclear(create_win);
        mvwprintw(create_win,1,1,"Error:test name has been existed");
        sqlite3_sleep(1000);
        sqlite3_finalize(sqlsearch);
        sqlite3_close(db);
        delwin(create_win);
        return;
    }
    sqlite3_finalize(sqlsearch);

    struct bottom *left = creat_bottom(create_win, WIN_HEIGHT - 3, 20, 2, 1, "<-");
    struct bottom *right = creat_bottom(create_win, WIN_HEIGHT - 3, 40, 2, 1, "->");
    struct bottom *ok = creat_bottom(create_win, WIN_HEIGHT - 3, 52, 2, 1, "OK");
    struct bottom *search = creat_bottom(create_win, 1, 8, 20, 1, "");
    memset(search->test,0,30);
    search->private = 2;
    char searchq[100];
    memset(searchq, 0, 100);
    int *id;
    sqlite3_stmt *stmt;
    int row_count = 0;
    Node *head = NULL;  // 初始化链表为空
    while (1) {
        // 清空窗口内容
        werase(create_win);
        box(create_win, 0, 0);
        // 调用函数输出当前的滚动窗口内容
        id=display_t_problem_page_2(create_win, db, offset, left, right, ok, search,&row_count,head);
        int rc = wgetch(create_win);
        if (rc == KEY_MOUSE) {
            if (nc_getmouse(&event) == OK) {
                if (click_bottom(event, *left, start_x, start_y)) {
                    if (offset >= PAGE_SIZE) {
                        offset -= PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *right, start_x, start_y)) {
                    if (offset + PAGE_SIZE < row_count) {  // 总共有100条数据可以调整
                        offset += PAGE_SIZE;
                    }
                    continue;
                }
                if (click_bottom(event, *ok, start_x, start_y)) {
                    sql_query="insert into tests (test_name,Creater) values (?,?)";
                    sqlite3_stmt *insert;
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
                    if (rc != SQLITE_OK) {
                        wclear(create_win);
                        mvwprintw(create_win,1,1,"Error:data base error.");
                        sqlite3_finalize(insert);
                        sqlite3_close(db);
                        delwin(create_win);
                        return;
                    }
                    sqlite3_bind_text(insert, 1, testname, -1, SQLITE_STATIC);

                    sqlite3_bind_text(insert, 2, Username, -1, SQLITE_STATIC);

                    rc = sqlite3_step(insert);
                    if (rc != SQLITE_DONE) {
                        wclear(create_win);
                        sqlite3_finalize(insert);
                        sqlite3_close(db);return;
                    }
                    sql_query="select ID from tests where test_name=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
                    if (rc != SQLITE_OK) {
                        wclear(create_win);
                        sqlite3_finalize(insert);
                        sqlite3_close(db);return;
                    }
                    sqlite3_bind_text(insert, 1, testname, -1, SQLITE_STATIC);

                    rc = sqlite3_step(insert);

                    if(rc!=SQLITE_ROW){
                        free_list(head);
                        free(left);
                        free(right);
                        free(ok);
                        free(id);
                        sqlite3_finalize(insert);
                        sqlite3_close(db);
                        delwin(create_win);
                        return;
                    }
                    int test_id = sqlite3_column_int(insert,0);
                    sql_query="insert into test_include (text,answer,test_index) values(?,?,?);";
                    Node *temp = head;
                    int problem_counts=0;
                    while (temp != NULL) {
                        problem_counts++;
                        sqlite3_stmt *insert;
                        rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
                        if (rc != SQLITE_OK) {
                            wclear(create_win);
                            sqlite3_finalize(insert);
                            sqlite3_close(db);return;
                        }
                        sqlite3_bind_text(insert, 1, temp->str1, -1, SQLITE_STATIC);
                        sqlite3_bind_text(insert, 2, temp->str2, -1, SQLITE_STATIC);
                        sqlite3_bind_int(insert, 3, test_id);
                        rc = sqlite3_step(insert);
                        if(rc!=SQLITE_DONE){
                            wclear(create_win);
                            sqlite3_finalize(insert);
                            sqlite3_close(db);return;
                        }
                        temp = temp->next;
                    }
                    sql_query="update tests set problems_count =? where ID=?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &insert, 0);
                    if (rc != SQLITE_OK) {
                        wclear(create_win);
                        sqlite3_finalize(insert);
                        sqlite3_close(db);return;
                    }
                    sqlite3_bind_int(insert, 1, problem_counts);
                    sqlite3_bind_int(insert, 2, test_id);
                    rc = sqlite3_step(insert);
                    if(rc!=SQLITE_DONE){
                        wclear(create_win);
                        sqlite3_finalize(insert);
                        sqlite3_close(db);return;
                    }
                    sqlite3_finalize(insert);
                    free_list(head);
                    free(left);
                    free(right);
                    free(ok);
                    free(id);
                    sqlite3_close(db);
                    delwin(create_win);
                    return;
                }
                if (click_bottom(event, *search, start_x, start_y)) {
                    get_input(create_win, 4, 6, searchq, 15, search, start_x, start_y);
                    offset=0;
                    continue;
                }
                if (event.x-start_x >= 45 && event.x-start_x <= 50) {           //select
                    sql_query="select text,answer from timu where ID =?";
                    rc = sqlite3_prepare_v2(db, sql_query, -1, &stmt, 0);
                    if (rc != SQLITE_OK) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    sqlite3_bind_int(stmt, 1, *(id+(((event.y-start_y)+5)/2-5)));
                    rc = sqlite3_step(stmt);
                    if (rc != SQLITE_ROW) {
                        sqlite3_finalize(stmt);
                        continue;
                    }
                    char *text1 = sqlite3_column_text(stmt, 0);
                    char *answer1 = sqlite3_column_text(stmt,1);
                    if(list_search(head,*(id+(((event.y-start_y)+5)/2-5))))continue;
                    insert_node(&head,text1,answer1,*(id+(((event.y-start_y)+5)/2-5)));
                    continue;
                }
            }
        }
    }
}

