use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{BufRead, BufReader, Write, stdout};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant};
use std::sync::mpsc;

use rand::seq::SliceRandom;
use crossterm::{
    cursor::{self, SetCursorStyle},
    event::{self, Event, KeyCode, KeyEventKind, KeyModifiers},
    execute,
    style::{Color, Print, ResetColor, SetForegroundColor},
    terminal::{self, ClearType, disable_raw_mode, enable_raw_mode},
    QueueableCommand,
};

// ==========================================
//               配置常量
// ==========================================
const SERVER_ADDR: &str = "0.0.0.0:7878";
const DEFAULT_ROUNDS: usize = 10;
const MAX_NUM: i32 = 10;
const MIN_PLAYER_NAME_LEN: usize = 1;
const MAX_PLAYER_NAME_LEN: usize = 20;
const MAX_EXPR_LEN: usize = 100;
const MAX_PLAYERS: usize = 20;
const RATE_LIMIT_MSGS_PER_SEC: u32 = 10;
const RATE_LIMIT_WINDOW_MS: u64 = 1000;

// ==========================================
//           客户端数据结构
// ==========================================

struct ClientState {
    messages: Vec<String>,
    input_buffer: Vec<char>,
    cursor_idx: usize,
    height: u16,
    width: u16,
    current_round_id: usize,
}

impl ClientState {
    fn new() -> Self {
        let (w, h) = terminal::size().unwrap_or((80, 24));
        Self {
            messages: Vec::new(),
            input_buffer: Vec::new(),
            cursor_idx: 0,
            height: h,
            width: w,
            current_round_id: 0,
        }
    }

    fn add_message(&mut self, msg: String) {
        for line in msg.lines() {
            self.messages.push(line.to_string());
        }
        if self.messages.len() > 500 {
            self.messages.drain(0..100);
        }
    }
}

// ==========================================
//           服务端数据结构
// ==========================================

#[derive(PartialEq)]
enum GameStatus {
    Waiting,
    Playing,
    Ended,
}

struct GameState {
    status: GameStatus,
    scores: HashMap<String, i32>,
    players: HashSet<String>,
    passed_players: HashSet<String>,
    current_puzzle: Option<Vec<i32>>,
    puzzle_id: usize,
    session_id: u32,
    puzzle_pool: Vec<Vec<i32>>,
    total_rounds: usize,
}

struct PlayerRateLimit {
    messages: Vec<Instant>,
}

impl PlayerRateLimit {
    fn new() -> Self {
        Self { messages: Vec::new() }
    }

    fn check_rate_limit(&mut self) -> bool {
        let now = Instant::now();
        let window_start = now - Duration::from_millis(RATE_LIMIT_WINDOW_MS);
        self.messages.retain(|&t| t > window_start);
        
        if self.messages.len() >= RATE_LIMIT_MSGS_PER_SEC as usize {
            false
        } else {
            self.messages.push(now);
            true
        }
    }
}

// ==========================================
//               主入口
// ==========================================

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        print_usage();
        return;
    }

    match args[1].as_str() {
        "server" => {
            let mut total_rounds = DEFAULT_ROUNDS;
            if args.len() >= 3 {
                if let Ok(n) = args[2].parse::<usize>() {
                    if n > 10 && n < 100 {
                        total_rounds = n;
                    } else {
                        println!("Warning: Round number {} is out of range (10-100), using default: {}", n, DEFAULT_ROUNDS);
                    }
                }
            }
            let bind_addr = if args.len() >= 3 && args[2].parse::<usize>().is_err() {
                args[2].clone()
            } else if args.len() >= 4 {
                args[3].clone()
            } else {
                SERVER_ADDR.to_string()
            };
            run_server(total_rounds, &bind_addr);
        }
        "client" => {
            if args.len() < 4 {
                println!("Usage: ./game24_net client <Name> <IP:Port>");
                return;
            }
            run_client(&args[2], &args[3]);
        }
        _ => print_usage(),
    }
}

fn print_usage() {
    println!("{}", "╔═══════════════════════════════════════╗");
    println!("{}", "║   24 Point Network Game (Clean UI)    ║");
    println!("{}", "╚═══════════════════════════════════════╝");
    println!();
    println!("{} {}", "Server:", "./game24_net server [rounds] [IP:Port]");
    println!("{} {}", "Default address:", SERVER_ADDR);
    println!();
    println!("{} {}", "Client:", "./game24_net client <Name> <IP:Port>");
}

// ==========================================
//               服务端逻辑
// ==========================================

fn run_server(total_rounds: usize, bind_addr: &str) {
    println!("Server starting on {} with {} rounds...", bind_addr, total_rounds);
    let pool = generate_full_puzzle_pool();
    
    let listener = match TcpListener::bind(bind_addr) {
        Ok(l) => l,
        Err(e) => {
            eprintln!("Error: Failed to bind port {}: {}", bind_addr, e);
            return;
        }
    };
    let clients: Arc<Mutex<Vec<TcpStream>>> = Arc::new(Mutex::new(Vec::new()));
    
    let game_state = Arc::new(Mutex::new(GameState {
        status: GameStatus::Waiting,
        scores: HashMap::new(),
        players: HashSet::new(),
        passed_players: HashSet::new(),
        current_puzzle: None,
        puzzle_id: 0,
        session_id: 0,
        puzzle_pool: pool,
        total_rounds,
    }));

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let clients_inner = clients.clone();
                let state_inner = game_state.clone();
                if let Ok(s_clone) = stream.try_clone() {
                    if let Ok(mut guard) = clients_inner.lock() {
                        guard.push(s_clone);
                    }
                }
                thread::spawn(move || {
                    handle_client(stream, state_inner, clients_inner);
                });
            }
            Err(e) => println!("Error: Connection error: {}", e),
        }
    }
}

fn validate_player_name(name: &str) -> Result<(), String> {
    if name.len() < MIN_PLAYER_NAME_LEN {
        return Err(format!("Player name must be at least {} character(s)", MIN_PLAYER_NAME_LEN));
    }
    if name.len() > MAX_PLAYER_NAME_LEN {
        return Err(format!("Player name must be at most {} characters", MAX_PLAYER_NAME_LEN));
    }
    if !name.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') {
        return Err("Player name can only contain letters, numbers, underscores, and hyphens".to_string());
    }
    Ok(())
}

fn handle_client(mut stream: TcpStream, state: Arc<Mutex<GameState>>, clients: Arc<Mutex<Vec<TcpStream>>>) {
    let rate_limiter = Arc::new(Mutex::new(PlayerRateLimit::new()));
    let stream_clone = match stream.try_clone() {
        Ok(s) => s,
        Err(_) => return,
    };
    let mut reader = BufReader::new(stream_clone);
    let mut line = String::new();
    let addr = stream.peer_addr().unwrap();

    if reader.read_line(&mut line).is_err() { return; }
    let player_name = line.trim().to_string();
    if player_name.is_empty() { return; }

    if let Err(e) = validate_player_name(&player_name) {
        let _ = writeln!(stream, "MSG: Error: {}. Please choose another name.", e);
        return;
    }

    {
        let gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
        if gs.players.len() >= MAX_PLAYERS {
            drop(gs);
            let _ = writeln!(stream, "MSG: Error: Server is full.");
            return;
        }
        if gs.players.contains(&player_name) {
            drop(gs);
            let _ = writeln!(stream, "MSG: Error: Name taken.");
            return;
        }
    }

    println!("[{}] joined from {}", player_name, addr);

    {
        let mut gs = state.lock().unwrap();
        gs.players.insert(player_name.clone());
        gs.scores.entry(player_name.clone()).or_insert(0);
        let status_msg = if gs.status == GameStatus::Waiting {
            format!("MSG:Welcome [{}]! Waiting in Lobby... (Type /start to begin, /help for commands)", player_name)
        } else {
            format!("MSG:Welcome [{}]! Spectating game... (Type /help for commands)", player_name)
        };
        drop(gs); 
        broadcast(&clients, &status_msg);
    }

    loop {
        line.clear();
        match reader.read_line(&mut line) {
            Ok(0) => break,
            Ok(_) => {
                let input = line.trim();
                if input.is_empty() { continue; }

                {
                    let mut rl = match rate_limiter.lock() { Ok(rl) => rl, Err(_) => continue };
                    if !rl.check_rate_limit() {
                        drop(rl);
                        let _ = writeln!(stream, "MSG: Rate limit exceeded.");
                        continue;
                    }
                }

                if input.len() > MAX_EXPR_LEN + 10 {
                    let _ = writeln!(stream, "MSG: Input too long.");
                    continue;
                }

                if input == "/start" {
                    try_start_game(&state, &clients);
                } else if input == "/pass" {
                    handle_pass(&player_name, &state, &clients);
                } else if input == "/help" {
                    handle_help(&mut stream, &player_name);
                } else if input == "/score" {
                    handle_score(&mut stream, &player_name, &state);
                } else if input == "/players" {
                    handle_players(&mut stream, &state);
                } else if input.starts_with("ANS:") {
                    let parts: Vec<&str> = input.splitn(3, ':').collect();
                    if parts.len() == 3 {
                        if let Ok(rid) = parts[1].parse::<usize>() {
                            if parts[2].len() > MAX_EXPR_LEN { continue; }
                            process_answer(&player_name, rid, parts[2], &state, &clients);
                        }
                    }
                }
            }
            Err(_) => break,
        }
    }

    {
        let mut gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
        gs.players.remove(&player_name);
        gs.scores.remove(&player_name); 

        if gs.players.is_empty() {
            gs.status = GameStatus::Waiting;
            gs.puzzle_id = 0;
            gs.session_id = gs.session_id.wrapping_add(1); 
            println!("All players left. Resetting (Session {}).", gs.session_id);
        }
    }
    broadcast(&clients, &format!("MSG: Player [{}] left.", player_name));
}

fn try_start_game(state: &Arc<Mutex<GameState>>, clients: &Arc<Mutex<Vec<TcpStream>>>) {
    let mut gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
    if gs.status != GameStatus::Waiting { return; }

    gs.status = GameStatus::Playing;
    let names: Vec<String> = gs.players.iter().cloned().collect();
    for p in names { gs.scores.insert(p, 0); }
    gs.puzzle_id = 0;
    
    let mut rng = rand::rng(); 
    gs.puzzle_pool.shuffle(&mut rng);

    drop(gs);
    broadcast(clients, "MSG: \n=== GAME START ===\n");
    start_next_round(state, clients);
}

fn start_next_round(state: &Arc<Mutex<GameState>>, clients: &Arc<Mutex<Vec<TcpStream>>>) {
    let mut gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
    let total_rounds = gs.total_rounds;
    
    if gs.puzzle_id >= total_rounds {
        gs.status = GameStatus::Ended;
        let mut summary = String::from("MSG: \n=== GAME OVER ===\n\nLeaderboard:\n");
        let mut sorted: Vec<(&String, &i32)> = gs.scores.iter().collect();
        sorted.sort_by(|a, b| b.1.cmp(a.1));
        for (name, score) in sorted.iter() {
            summary.push_str(&format!("{}: {} pts\n", name, score));
        }
        summary.push_str("\nType /start to play again.");
        gs.status = GameStatus::Waiting;
        drop(gs);
        broadcast(clients, &summary);
        return;
    }

    gs.puzzle_id += 1;
    gs.passed_players.clear();

    if gs.puzzle_pool.is_empty() {
        gs.puzzle_pool = generate_full_puzzle_pool();
        let mut rng = rand::rng();
        gs.puzzle_pool.shuffle(&mut rng);
    }
    let nums = match gs.puzzle_pool.pop() {
        Some(n) => n,
        None => return,
    };
    
    gs.current_puzzle = Some(nums.clone());
    let pid = gs.puzzle_id;
    let msg = format!("PUZZLE:{}:{}:{}:{}:{}", pid, nums[0], nums[1], nums[2], nums[3]);
    
    drop(gs);
    broadcast(clients, &format!("MSG: === Round {}/{} ===", pid, total_rounds));
    broadcast(clients, &msg);
}

fn handle_pass(player: &str, state: &Arc<Mutex<GameState>>, clients: &Arc<Mutex<Vec<TcpStream>>>) {
    let mut gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
    if gs.status != GameStatus::Playing { return; }
    if gs.passed_players.contains(player) { return; }
    
    gs.passed_players.insert(player.to_string());
    let pass = gs.passed_players.len();
    let total = gs.players.len();
    let msg = format!("MSG: [{}] passed ({}/{})", player, pass, total);
    let skip = pass >= total;
    drop(gs);
    broadcast(clients, &msg);

    if skip {
        broadcast(clients, "MSG: [SKIP] All passed.");
        start_next_round(state, clients);
    }
}

fn handle_help(stream: &mut TcpStream, player: &str) {
    let mut help_msg = String::new();
    help_msg.push_str("MSG: \n=== Help ===\n");
    help_msg.push_str("/start, /pass, /help, /score, /players\n");
    help_msg.push_str("Goal: Make 24 using + - * / ^ and ()\n");
    help_msg.push_str("Controls: UP arrow for '^', '.' wraps expression in ().\n");
    help_msg.push_str("Note: Wrong answers do not deduct points.\n");
    help_msg.push_str(&format!("Current player: [{}]\n", player));
    let _ = writeln!(stream, "{}", help_msg);
}

fn handle_score(stream: &mut TcpStream, player: &str, state: &Arc<Mutex<GameState>>) {
    let gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
    let score = gs.scores.get(player).copied().unwrap_or(0);
    let _ = writeln!(stream, "MSG: Your Score: {} points\n", score);
}

fn handle_players(stream: &mut TcpStream, state: &Arc<Mutex<GameState>>) {
    let players_list = {
        let gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
        let mut list: Vec<(String, i32)> = gs.players.iter()
            .map(|p| (p.clone(), *gs.scores.get(p).unwrap_or(&0)))
            .collect();
        list.sort_by(|a, b| a.0.cmp(&b.0));
        list
    };
    
    let mut msg = String::from("MSG: === PLAYERS ===\n");
    if players_list.is_empty() {
        msg.push_str("(No players online)\n");
    } else {
        for (idx, (player, score)) in players_list.iter().enumerate() {
            msg.push_str(&format!("{}. {} (Score: {})\n", idx + 1, player, score));
        }
    }
    let _ = writeln!(stream, "{}", msg);
}

fn process_answer(player: &str, round_id: usize, expr: &str, state: &Arc<Mutex<GameState>>, clients: &Arc<Mutex<Vec<TcpStream>>>) {
    let mut gs = match state.lock() { Ok(gs) => gs, Err(_) => return };
    if gs.puzzle_id != round_id || gs.status != GameStatus::Playing { return; }

    let puzzle = match &gs.current_puzzle { Some(p) => p.clone(), None => return };

    if !validate_numbers_usage(&puzzle, expr) {
        let s = gs.scores.get(player).unwrap_or(&0);
        let msg = format!("MSG: [{}] Invalid numbers! (Score: {})", player, s);
        drop(gs);
        broadcast(clients, &msg);
        return;
    }

    match eval_expression(expr) {
        Ok(val) => {
            if (val - 24.0).abs() < 1e-5 {
                *gs.scores.entry(player.to_string()).or_insert(0) += 1;
                let s = gs.scores.get(player).unwrap_or(&0);
                let msg = format!("MSG: [WIN] [{}] Correct! {} (+1, Score: {})", player, expr, s);
                gs.current_puzzle = None;
                drop(gs);
                broadcast(clients, &msg);
                start_next_round(state, clients);
            } else {
                let s = gs.scores.get(player).unwrap_or(&0);
                let msg = format!("MSG: [{}] Wrong ({:.2}) (Score: {})", player, val, s);
                drop(gs);
                broadcast(clients, &msg);
            }
        }
        Err(_) => {
            drop(gs);
            broadcast(clients, &format!("MSG: [{}] Syntax error", player));
        }
    }
}

fn broadcast(clients: &Arc<Mutex<Vec<TcpStream>>>, msg: &str) {
    let clones: Vec<(usize, TcpStream)> = match clients.lock() {
        Ok(g) => g.iter().enumerate().filter_map(|(i, s)| s.try_clone().ok().map(|c| (i, c))).collect(),
        Err(_) => return,
    };
    let mut failed = Vec::new();
    for (i, mut s) in clones {
        if writeln!(&mut s, "{}", msg).is_err() {
            failed.push(i);
        }
    }
    if !failed.is_empty() {
        if let Ok(mut g) = clients.lock() {
            for i in failed.into_iter().rev() {
                if i < g.len() { g.remove(i); }
            }
        }
    }
}

fn generate_full_puzzle_pool() -> Vec<Vec<i32>> {
    let mut pool = Vec::new();
    for i in 1..=MAX_NUM {
        for j in i..=MAX_NUM {
            for k in j..=MAX_NUM {
                for l in k..=MAX_NUM {
                    let nums = vec![i, j, k, l];
                    if solve_24_check(&nums) { pool.push(nums); }
                }
            }
        }
    }
    pool
}

fn solve_24_check(nums: &[i32]) -> bool {
    let f_nums: Vec<f64> = nums.iter().map(|&x| x as f64).collect();
    solve_rec(&f_nums)
}

fn solve_rec(list: &[f64]) -> bool {
    if list.len() == 1 { return (list[0] - 24.0).abs() < 1e-5; }
    for i in 0..list.len() {
        for j in 0..list.len() {
            if i == j { continue; }
            let mut next = Vec::with_capacity(list.len()-1);
            for k in 0..list.len() { if k!=i && k!=j { next.push(list[k]); } }
            let (a, b) = (list[i], list[j]);
            let ops = [a+b, a-b, b-a, a*b];
            for &val in &ops {
                next.push(val);
                if solve_rec(&next) { return true; }
                next.pop();
            }
            if b.abs() > 1e-5 {
                next.push(a/b);
                if solve_rec(&next) { return true; }
                next.pop();
            }
            if a.abs() > 1e-5 {
                next.push(b/a);
                if solve_rec(&next) { return true; }
                next.pop();
            }
        }
    }
    false
}

// ==========================================
//           ✨ 客户端逻辑 (TUI 分屏版)
// ==========================================

fn run_client(name: &str, addr: &str) {
    let mut stream = match TcpStream::connect(addr) {
        Ok(s) => s,
        Err(e) => {
            eprintln!("Error: Failed to connect to {}: {}", addr, e);
            return;
        }
    };

    if let Err(e) = writeln!(stream, "{}", name) {
        eprintln!("Error: Failed to send player name: {}", e);
        return;
    }

    enable_raw_mode().expect("Failed to enable raw mode");
    let mut stdout = stdout();

    // 初始化：切换屏幕，隐藏光标，设置块状光标
    execute!(
        stdout, 
        terminal::EnterAlternateScreen, 
        cursor::Hide,
        SetCursorStyle::BlinkingBlock
    ).ok();

    let (tx, rx) = mpsc::channel::<String>();
    let stream_recv = stream.try_clone().expect("Failed to clone stream");

    thread::spawn(move || {
        let reader = BufReader::new(stream_recv);
        for line in reader.lines() {
            match line {
                Ok(l) => { if tx.send(l).is_err() { break; } }
                Err(_) => { let _ = tx.send("MSG:Error: Connection lost.".to_string()); break; }
            }
        }
    });

    let mut state = ClientState::new();
    let mut running = true;
    let mut needs_redraw = true; 
    
    state.add_message(format!("Connected to {} as [{}].", addr, name));
    state.add_message("Type /help for commands. Press Esc to quit.".to_string());

    while running {
        if needs_redraw {
            draw_ui(&mut stdout, &state);
            needs_redraw = false;
        }

        let mut new_msg_count = 0;
        while let Ok(msg) = rx.try_recv() {
            handle_server_message(&mut state, msg);
            new_msg_count += 1;
        }
        if new_msg_count > 0 { needs_redraw = true; }

        if event::poll(Duration::from_millis(50)).unwrap_or(false) {
            loop {
                if let Ok(Event::Key(key)) = event::read() {
                    if key.kind == KeyEventKind::Press {
                        match key.code {
                            KeyCode::Esc => running = false,
                            KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => running = false,
                            
                            KeyCode::Home => {
                                state.cursor_idx = 0;
                                needs_redraw = true;
                            }
                            KeyCode::End => {
                                state.cursor_idx = state.input_buffer.len();
                                needs_redraw = true;
                            }

                            KeyCode::Left => {
                                if state.cursor_idx > 0 {
                                    state.cursor_idx -= 1;
                                    needs_redraw = true;
                                }
                            }
                            KeyCode::Right => {
                                if state.cursor_idx < state.input_buffer.len() {
                                    state.cursor_idx += 1;
                                    needs_redraw = true;
                                }
                            }
                            
                            // [修改点 3] 方向键上等于输入乘方符号 "^"
                            KeyCode::Up => {
                                state.input_buffer.insert(state.cursor_idx, '^');
                                state.cursor_idx += 1;
                                needs_redraw = true;
                            }

                            // [修改点 2] 键盘输入 "." 的时候自动将当前式子括起来并把光标移到最后
                            KeyCode::Char('.') => {
                                let content: String = state.input_buffer.iter().collect();
                                state.input_buffer = format!("({})", content).chars().collect();
                                state.cursor_idx = state.input_buffer.len();
                                needs_redraw = true;
                            }

                            // [修改点 1] 限制输入只能是相关算式 (或命令)
                            KeyCode::Char(c) => {
                                // 判断是否是命令模式（以 / 开头，或者当前为空且输入的是 /）
                                let is_command = state.input_buffer.starts_with(&['/']) || (state.input_buffer.is_empty() && c == '/');
                                
                                // 允许的数学字符
                                let is_math_char = c.is_digit(10) || "+-*/^()".contains(c);

                                if is_command || is_math_char {
                                    state.input_buffer.insert(state.cursor_idx, c);
                                    state.cursor_idx += 1;
                                    needs_redraw = true;
                                }
                            }
                            KeyCode::Backspace => {
                                if state.cursor_idx > 0 {
                                    state.input_buffer.remove(state.cursor_idx - 1);
                                    state.cursor_idx -= 1;
                                    needs_redraw = true;
                                }
                            }
                            KeyCode::Enter => {
                                let input: String = state.input_buffer.iter().collect();
                                let input = input.trim().to_string();
                                
                                state.input_buffer.clear();
                                state.cursor_idx = 0;
                                needs_redraw = true;
                                
                                if !input.is_empty() {
                                    if input.starts_with('/') {
                                        let _ = writeln!(stream, "{}", input);
                                    } else {
                                        if state.current_round_id > 0 {
                                            let _ = writeln!(stream, "ANS:{}:{}", state.current_round_id, input);
                                        } else {
                                            state.add_message("MSG: Wait for round start.".to_string());
                                            needs_redraw = true;
                                        }
                                    }
                                }
                            }
                            _ => {}
                        }
                    }
                } else if let Ok(Event::Resize(w, h)) = event::read() {
                    state.width = w;
                    state.height = h;
                    needs_redraw = true;
                }

                if !event::poll(Duration::from_millis(0)).unwrap_or(false) {
                    break;
                }
            }
        }
    }

    execute!(
        stdout, 
        cursor::Show, 
        terminal::LeaveAlternateScreen,
        SetCursorStyle::DefaultUserShape
    ).ok();
    
    disable_raw_mode().ok();
    println!("Game exited.");
}

fn handle_server_message(state: &mut ClientState, raw_msg: String) {
    if raw_msg.starts_with("PUZZLE:") {
        let parts: Vec<&str> = raw_msg.split(':').collect();
        if parts.len() >= 6 {
            if let Ok(rid) = parts[1].parse() {
                state.current_round_id = rid;
            }
            let puzzle_text = format!("✨ PUZZLE: {} {} {} {}", parts[2], parts[3], parts[4], parts[5]);
            state.add_message("".to_string()); 
            state.add_message("--------------------------------".to_string());
            state.add_message(puzzle_text);
            state.add_message("--------------------------------".to_string());
        }
    } else if raw_msg.starts_with("MSG:") {
        let content = &raw_msg[4..];
        state.add_message(content.to_string());
    } else {
        state.add_message(raw_msg);
    }
}

fn draw_ui(stdout: &mut std::io::Stdout, state: &ClientState) {
    let input_y = state.height - 1;
    let separator_y = state.height - 2;
    let message_area_height = (state.height as usize).saturating_sub(2);

    // 1. 绘制消息区域
    let skip_count = state.messages.len().saturating_sub(message_area_height);
    for i in 0..message_area_height {
        let _ = stdout.queue(cursor::MoveTo(0, i as u16));
        if let Some(msg) = state.messages.get(skip_count + i) {
            let _ = stdout.queue(Print(msg));
            let _ = stdout.queue(terminal::Clear(ClearType::UntilNewLine));
        } else {
            let _ = stdout.queue(terminal::Clear(ClearType::UntilNewLine));
        }
    }

    // 2. 绘制分隔线
    let _ = stdout.queue(cursor::MoveTo(0, separator_y));
    let _ = stdout.queue(SetForegroundColor(Color::Cyan));
    let separator = "─".repeat(state.width as usize);
    let _ = stdout.queue(Print(separator));
    let _ = stdout.queue(ResetColor);

    // 3. 绘制输入框
    let _ = stdout.queue(cursor::MoveTo(0, input_y));
    let _ = stdout.queue(terminal::Clear(ClearType::CurrentLine)); 
    let _ = stdout.queue(Print("> ")); 
    
    let display_input: String = state.input_buffer.iter().collect();
    let _ = stdout.queue(Print(&display_input));

    // 4. 设置光标位置
    let cursor_x = 2 + state.cursor_idx as u16;
    let cursor_x = cursor_x.min(state.width - 1);
    
    let _ = stdout.queue(cursor::MoveTo(cursor_x, input_y));
    let _ = stdout.queue(cursor::Show);

    let _ = stdout.flush();
}

// ==========================================
//           表达式计算与验证
// ==========================================

fn validate_numbers_usage(puzzle: &[i32], input: &str) -> bool {
    let mut nums = Vec::new();
    let mut cur = String::new();
    for c in input.chars() {
        if c.is_digit(10) { cur.push(c); } 
        else if !cur.is_empty() {
            if let Ok(n) = cur.parse::<i32>() { nums.push(n); }
            cur.clear();
        }
    }
    if !cur.is_empty() { if let Ok(n) = cur.parse::<i32>() { nums.push(n); } }
    if nums.len() != 4 { return false; }
    let mut p = puzzle.to_vec(); p.sort(); nums.sort(); p == nums
}

fn eval_expression(expr: &str) -> Result<f64, String> {
    let s: String = expr.chars().filter(|c| !c.is_whitespace()).collect();
    let chars: Vec<char> = s.chars().collect();
    let mut pos = 0;
    parse_expr(&chars, &mut pos)
}
fn parse_expr(c: &[char], p: &mut usize) -> Result<f64, String> {
    let mut left = parse_term(c, p)?;
    while *p < c.len() {
        match c[*p] {
            '+' => { *p+=1; left += parse_term(c, p)?; },
            '-' => { *p+=1; left -= parse_term(c, p)?; },
            _ => break,
        }
    }
    Ok(left)
}
fn parse_term(c: &[char], p: &mut usize) -> Result<f64, String> {
    let mut left = parse_factor(c, p)?;
    while *p < c.len() {
        match c[*p] {
            '*' => { *p+=1; left *= parse_factor(c, p)?; },
            '/' => { *p+=1; let r = parse_factor(c, p)?; if r.abs()<1e-5 {return Err("Div0".into())} left/=r; },
            _ => break,
        }
    }
    Ok(left)
}
fn parse_factor(c: &[char], p: &mut usize) -> Result<f64, String> {
    let mut base = parse_prim(c, p)?;
    while *p < c.len() && c[*p] == '^' { *p+=1; base = base.powf(parse_prim(c, p)?); }
    Ok(base)
}
fn parse_prim(c: &[char], p: &mut usize) -> Result<f64, String> {
    if *p >= c.len() { return Err("EOF".into()); }
    match c[*p] {
        '(' => { *p+=1; let v = parse_expr(c, p)?; if *p>=c.len()||c[*p]!=')' {return Err("No )".into())} *p+=1; Ok(v) },
        x if x.is_digit(10) => {
            let s = *p; while *p<c.len() && (c[*p].is_digit(10)||c[*p]=='.') { *p+=1; }
            c[s..*p].iter().collect::<String>().parse().map_err(|_| "NumErr".into())
        }
        _ => Err("CharErr".into())
    }
}

// ==========================================
//                测试模块
// ==========================================

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validate_player_name() {
        assert!(validate_player_name("Player1").is_ok());
        assert!(validate_player_name("player_123").is_ok());
        assert!(validate_player_name("test-player").is_ok());
        assert!(validate_player_name("").is_err());
        let long_name = "a".repeat(MAX_PLAYER_NAME_LEN + 1);
        assert!(validate_player_name(&long_name).is_err());
        assert!(validate_player_name("player@123").is_err());
    }

    #[test]
    fn test_validate_numbers_usage() {
        let puzzle = vec![1, 2, 3, 4];
        assert!(validate_numbers_usage(&puzzle, "1+2+3+4"));
        assert!(validate_numbers_usage(&puzzle, "(1+2)*(3+4)"));
        assert!(!validate_numbers_usage(&puzzle, "1+2+3"));
        assert!(!validate_numbers_usage(&puzzle, "1+2+3+5"));
    }

    #[test]
    fn test_eval_expression() {
        assert_eq!(eval_expression("1+2+3+4").unwrap(), 10.0);
        assert_eq!(eval_expression("2*3*4").unwrap(), 24.0);
        assert!((eval_expression("(1+2)*(3+4)").unwrap() - 21.0).abs() < 1e-5);
        assert!(eval_expression("1/0").is_err());
    }

    #[test]
    fn test_rate_limit() {
        let mut rl = PlayerRateLimit::new();
        for _ in 0..RATE_LIMIT_MSGS_PER_SEC {
            assert!(rl.check_rate_limit());
        }
        assert!(!rl.check_rate_limit());
    }
}