use anyhow::Result;
use crate::codegen::{BinOp, HirExpr, UnaryOp};

pub struct Parser {
    tokens: Vec<Token>,
    pos: usize,
}

#[derive(Debug, Clone)]
enum Token {
    Fn, Let, Const, If, Else, While, For, Return, Typeof, Break, Continue,
    Declare, Interface, New, Try, Catch, Finally, Throw, Import, From, As,
    Export, In,
    Ident(String),
    Number(f64),
    String(String),
    Bool(bool),
    Null, Undefined,
    
    LParen, RParen,
    LBrace, RBrace,
    LBracket, RBracket,
    
    Plus, Minus, Star, Slash, Percent,
    EqEq, EqEqEq, NotEq, NotEqEq, Lt, Le, Gt, Ge,
    AndAnd, OrOr,
    Not,
    Assign, PlusAssign, MinusAssign, StarAssign, SlashAssign,
    PlusPlus, MinusMinus,
    Question, Arrow,
    
    Comma, Semicolon, Colon, Dot,
    Pipe, Ampersand,
    
    TemplateParts(Vec<String>),
    
    Eof,
}

impl Parser {
    pub fn new(source: &str) -> Self {
        let tokens = Self::tokenize(source);
        Self { tokens, pos: 0 }
    }
    
    fn tokenize(source: &str) -> Vec<Token> {
        let mut tokens = Vec::new();
        let mut chars = source.chars().peekable();
        
        while let Some(&c) = chars.peek() {
            match c {
                ' ' | '\t' | '\n' | '\r' => {
                    chars.next();
                }
                '(' => { tokens.push(Token::LParen); chars.next(); }
                ')' => { tokens.push(Token::RParen); chars.next(); }
                '{' => { tokens.push(Token::LBrace); chars.next(); }
                '}' => { tokens.push(Token::RBrace); chars.next(); }
                '[' => { tokens.push(Token::LBracket); chars.next(); }
                ']' => { tokens.push(Token::RBracket); chars.next(); }
                ',' => { tokens.push(Token::Comma); chars.next(); }
                ';' => { tokens.push(Token::Semicolon); chars.next(); }
                ':' => { tokens.push(Token::Colon); chars.next(); }
                '.' => { tokens.push(Token::Dot); chars.next(); }
                '+' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::PlusAssign);
                    } else if chars.peek() == Some(&'+') {
                        chars.next();
                        tokens.push(Token::PlusPlus);
                    } else {
                        tokens.push(Token::Plus);
                    }
                }
                '-' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::MinusAssign);
                    } else if chars.peek() == Some(&'-') {
                        chars.next();
                        tokens.push(Token::MinusMinus);
                    } else {
                        tokens.push(Token::Minus);
                    }
                }
                '*' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::StarAssign);
                    } else {
                        tokens.push(Token::Star);
                    }
                }
                '/' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::SlashAssign);
                    } else if chars.peek() == Some(&'/') {
                        while let Some(&ch) = chars.peek() {
                            if ch == '\n' {
                                chars.next();
                                break;
                            }
                            chars.next();
                        }
                    } else if chars.peek() == Some(&'*') {
                        chars.next();
                        loop {
                            if let Some(&ch) = chars.peek() {
                                chars.next();
                                if ch == '*' && chars.peek() == Some(&'/') {
                                    chars.next();
                                    break;
                                }
                            } else {
                                break;
                            }
                        }
                    } else {
                        tokens.push(Token::Slash);
                    }
                }
                '%' => { tokens.push(Token::Percent); chars.next(); }
                '=' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        if chars.peek() == Some(&'=') {
                            chars.next();
                            tokens.push(Token::EqEqEq);
                        } else {
                            tokens.push(Token::EqEq);
                        }
                    } else if chars.peek() == Some(&'>') {
                        chars.next();
                        tokens.push(Token::Arrow);
                    } else {
                        tokens.push(Token::Assign);
                    }
                }
                '!' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        if chars.peek() == Some(&'=') {
                            chars.next();
                            tokens.push(Token::NotEqEq);
                        } else {
                            tokens.push(Token::NotEq);
                        }
                    } else {
                        tokens.push(Token::Not);
                    }
                }
                '<' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::Le);
                    } else {
                        tokens.push(Token::Lt);
                    }
                }
                '>' => {
                    chars.next();
                    if chars.peek() == Some(&'=') {
                        chars.next();
                        tokens.push(Token::Ge);
                    } else {
                        tokens.push(Token::Gt);
                    }
                }
                '&' => {
                    chars.next();
                    if chars.peek() == Some(&'&') {
                        chars.next();
                        tokens.push(Token::AndAnd);
                    } else {
                        tokens.push(Token::Ampersand);
                    }
                }
                '|' => {
                    chars.next();
                    if chars.peek() == Some(&'|') {
                        chars.next();
                        tokens.push(Token::OrOr);
                    } else {
                        tokens.push(Token::Pipe);
                    }
                }
                '?' => {
                    chars.next();
                    tokens.push(Token::Question);
                }
                '`' => {
                    chars.next();
                    let mut parts: Vec<String> = Vec::new();
                    let mut current_str = String::new();
                    while let Some(&ch) = chars.peek() {
                        if ch == '`' {
                            chars.next();
                            break;
                        }
                        if ch == '$' {
                            chars.next();
                            if chars.peek() == Some(&'{') {
                                chars.next();
                                parts.push(std::mem::take(&mut current_str));
                                let mut expr_str = String::new();
                                let mut depth = 1;
                                while depth > 0 && chars.peek().is_some() {
                                    let c = chars.next().unwrap();
                                    if c == '{' { depth += 1; }
                                    if c == '}' { depth -= 1; }
                                    if depth > 0 { expr_str.push(c); }
                                }
                                parts.push(expr_str);
                            } else {
                                current_str.push('$');
                            }
                        } else if ch == '\\' {
                            chars.next();
                            if let Some(&next) = chars.peek() {
                                chars.next();
                                match next {
                                    'n' => current_str.push('\n'),
                                    't' => current_str.push('\t'),
                                    'r' => current_str.push('\r'),
                                    '\\' => current_str.push('\\'),
                                    '`' => current_str.push('`'),
                                    '$' => current_str.push('$'),
                                    _ => current_str.push(next),
                                }
                            }
                        } else {
                            current_str.push(ch);
                            chars.next();
                        }
                    }
                    if !current_str.is_empty() || parts.is_empty() {
                        parts.push(current_str);
                    }
                    tokens.push(Token::TemplateParts(parts));
                }
                '"' | '\'' => {
                    let quote = c;
                    chars.next();
                    let mut s = String::new();
                    while let Some(&ch) = chars.peek() {
                        if ch == quote {
                            chars.next();
                            break;
                        }
                        if ch == '\\' {
                            chars.next();
                            if let Some(&next) = chars.peek() {
                                chars.next();
                                match next {
                                    'n' => s.push('\n'),
                                    't' => s.push('\t'),
                                    'r' => s.push('\r'),
                                    '\\' => s.push('\\'),
                                    '"' => s.push('"'),
                                    '\'' => s.push('\''),
                                    '0' => s.push('\0'),
                                    _ => s.push(next),
                                }
                            }
                        } else {
                            s.push(ch);
                            chars.next();
                        }
                    }
                    tokens.push(Token::String(s));
                }
                '0'..='9' => {
                    let mut num = String::new();
                    while let Some(&ch) = chars.peek() {
                        if ch.is_ascii_digit() || ch == '.' {
                            num.push(ch);
                            chars.next();
                        } else {
                            break;
                        }
                    }
                    tokens.push(Token::Number(num.parse().unwrap_or(0.0)));
                }
                'a'..='z' | 'A'..='Z' | '_' => {
                    let mut ident = String::new();
                    while let Some(&ch) = chars.peek() {
                        if ch.is_alphanumeric() || ch == '_' {
                            ident.push(ch);
                            chars.next();
                        } else {
                            break;
                        }
                    }
                    
                    let token = match ident.as_str() {
                        "function" => Token::Fn,
                        "let" => Token::Let,
                        "const" => Token::Const,
                        "if" => Token::If,
                        "else" => Token::Else,
                        "while" => Token::While,
                        "for" => Token::For,
                        "return" => Token::Return,
                        "typeof" => Token::Typeof,
                        "break" => Token::Break,
                        "continue" => Token::Continue,
                        "true" => Token::Bool(true),
                        "false" => Token::Bool(false),
                        "null" => Token::Null,
                        "undefined" => Token::Undefined,
                        "declare" => Token::Declare,
                        "interface" => Token::Interface,
                        "new" => Token::New,
                        "try" => Token::Try,
                        "catch" => Token::Catch,
                        "finally" => Token::Finally,
                        "throw" => Token::Throw,
                        "import" => Token::Import,
                        "from" => Token::From,
                        "as" => Token::As,
                        "export" => Token::Export,
                        "in" => Token::In,
                        _ => Token::Ident(ident),
                    };
                    tokens.push(token);
                }
                _ => {
                    chars.next();
                }
            }
        }
        
        tokens.push(Token::Eof);
        tokens
    }
    
    fn peek(&self) -> &Token {
        &self.tokens[self.pos]
    }
    
    fn advance(&mut self) -> Token {
        let token = self.tokens[self.pos].clone();
        if self.pos < self.tokens.len() - 1 {
            self.pos += 1;
        }
        token
    }
    
    fn expect(&mut self, expected: &Token) -> Result<()> {
        let token = self.advance();
        if std::mem::discriminant(&token) != std::mem::discriminant(expected) {
            anyhow::bail!("Expected {:?}, got {:?}", expected, token);
        }
        Ok(())
    }
    
    pub fn parse_module(&mut self) -> Result<Vec<HirExpr>> {
        let mut stmts = Vec::new();
        
        while !matches!(self.peek(), Token::Eof) {
            if let Some(stmt) = self.parse_stmt()? {
                stmts.push(stmt);
            }
        }
        
        Ok(stmts)
    }
    
    fn parse_stmt(&mut self) -> Result<Option<HirExpr>> {
        match self.peek() {
            Token::Fn => Ok(Some(self.parse_function()?)),
            Token::Declare => {
                self.skip_declare_stmt()?;
                Ok(None)
            }
            Token::Import => {
                self.skip_import_stmt()?;
                Ok(None)
            }
            Token::Export => {
                self.skip_export_stmt()?;
                Ok(None)
            }
            Token::Interface => {
                self.skip_interface_decl()?;
                Ok(None)
            }
            Token::Let | Token::Const => Ok(Some(self.parse_var()?)),
            Token::Return => Ok(Some(self.parse_return()?)),
            Token::Throw => Ok(Some(self.parse_throw()?)),
            Token::If => Ok(Some(self.parse_if()?)),
            Token::While => Ok(Some(self.parse_while()?)),
            Token::For => Ok(Some(self.parse_for()?)),
            Token::Try => Ok(Some(self.parse_try_catch()?)),
            Token::LBrace => Ok(Some(self.parse_block()?)),
            Token::Break => {
                self.advance();
                if matches!(self.peek(), Token::Semicolon) {
                    self.advance();
                }
                Ok(Some(HirExpr::Break))
            }
            Token::Continue => {
                self.advance();
                if matches!(self.peek(), Token::Semicolon) {
                    self.advance();
                }
                Ok(Some(HirExpr::Continue))
            }
            Token::Semicolon => {
                self.advance();
                Ok(None)
            }
            _ => {
                let expr = self.parse_expr()?;
                if matches!(self.peek(), Token::Semicolon) {
                    self.advance();
                }
                Ok(Some(expr))
            }
        }
    }
    
    fn skip_declare_stmt(&mut self) -> Result<()> {
        self.expect(&Token::Declare)?;
        self.skip_until_stmt_end();
        Ok(())
    }
    
    fn skip_import_stmt(&mut self) -> Result<()> {
        self.expect(&Token::Import)?;
        // import { a, b } from "module";
        // import * as name from "module";
        // import defaultExport from "module";
        // import "module";
        // import type { ... } from "module";
        
        if matches!(self.peek(), Token::String(_)) {
            // import "module";
            self.advance();
        } else {
            // 跳过到 from 或字符串字面量
            while !matches!(self.peek(), Token::From | Token::String(_) | Token::Semicolon | Token::Eof) {
                self.advance();
            }
            // 跳过 from
            if matches!(self.peek(), Token::From) {
                self.advance();
            }
            // 跳过模块路径字符串
            if matches!(self.peek(), Token::String(_)) {
                self.advance();
            }
        }
        // 跳过末尾分号
        if matches!(self.peek(), Token::Semicolon) {
            self.advance();
        }
        Ok(())
    }
    
    fn skip_export_stmt(&mut self) -> Result<()> {
        self.expect(&Token::Export)?;
        // export { ... } from "module";
        // export default ...
        // export const/let/function ...
        // export type ...
        self.skip_until_stmt_end();
        Ok(())
    }
    
    fn skip_interface_decl(&mut self) -> Result<()> {
        self.expect(&Token::Interface)?;
        if matches!(self.peek(), Token::Ident(_)) {
            self.advance();
        }
        if matches!(self.peek(), Token::LBrace) {
            self.advance();
            let mut depth = 1;
            while depth > 0 && !matches!(self.peek(), Token::Eof) {
                match self.peek() {
                    Token::LBrace => depth += 1,
                    Token::RBrace => depth -= 1,
                    _ => {}
                }
                self.advance();
            }
        }
        Ok(())
    }
    
    fn skip_until_stmt_end(&mut self) {
        loop {
            match self.peek() {
                Token::Semicolon | Token::Eof => {
                    if matches!(self.peek(), Token::Semicolon) {
                        self.advance();
                    }
                    break;
                }
                Token::LBrace => {
                    self.advance();
                    let mut depth = 1;
                    while depth > 0 && !matches!(self.peek(), Token::Eof) {
                        match self.peek() {
                            Token::LBrace => depth += 1,
                            Token::RBrace => depth -= 1,
                            _ => {}
                        }
                        self.advance();
                    }
                    break;
                }
                _ => {
                    self.advance();
                }
            }
        }
    }
    
    fn skip_type_annotation(&mut self) {
        if matches!(self.peek(), Token::Colon) {
            self.advance();
            self.skip_type();
        }
    }
    
    fn skip_type(&mut self) {
        loop {
            match self.peek() {
                Token::Ident(_) | Token::Number(_) => {
                    self.advance();
                    if !matches!(self.peek(), Token::LBracket | Token::Lt | Token::Pipe | Token::Ampersand) {
                        break;
                    }
                }
                Token::LBrace => {
                    self.advance();
                    while !matches!(self.peek(), Token::RBrace) && !matches!(self.peek(), Token::Eof) {
                        if matches!(self.peek(), Token::Ident(_) | Token::String(_)) {
                            self.advance();
                        }
                        if matches!(self.peek(), Token::Question) {
                            self.advance();
                        }
                        if matches!(self.peek(), Token::Colon) {
                            self.advance();
                            self.skip_type();
                        }
                        if matches!(self.peek(), Token::Comma) || matches!(self.peek(), Token::Semicolon) {
                            self.advance();
                        }
                        if matches!(self.peek(), Token::RBrace) {
                            break;
                        }
                    }
                    if matches!(self.peek(), Token::RBrace) {
                        self.advance();
                    }
                }
                Token::LBracket => {
                    self.advance();
                    if matches!(self.peek(), Token::RBracket) {
                        self.advance();
                    }
                }
                Token::Pipe | Token::Ampersand => {
                    self.advance();
                }
                Token::Lt => {
                    self.advance();
                    // 泛型类型: Array<string>, Record<string, number>
                    // 递归跳过泛型参数，逗号分隔
                    loop {
                        self.skip_type();
                        if matches!(self.peek(), Token::Comma) {
                            self.advance();
                        } else {
                            break;
                        }
                    }
                    if matches!(self.peek(), Token::Gt) {
                        self.advance();
                    }
                }
                Token::Fn | Token::Let | Token::Const | Token::If | Token::Else 
                | Token::While | Token::For | Token::Return | Token::Try | Token::Catch 
                | Token::Finally | Token::Throw | Token::RBrace 
                | Token::Semicolon | Token::Comma | Token::Eof => break,
                _ => break,
            }
        }
    }
    
    fn parse_function(&mut self) -> Result<HirExpr> {
        self.expect(&Token::Fn)?;
        let name = match self.advance() {
            Token::Ident(n) => n,
            _ => anyhow::bail!("Expected function name"),
        };
        
        self.expect(&Token::LParen)?;
        let mut params = Vec::new();
        while !matches!(self.peek(), Token::RParen) {
            if let Token::Ident(p) = self.advance() {
                params.push(p);
                self.skip_type_annotation();
            }
            if matches!(self.peek(), Token::Comma) {
                self.advance();
            }
        }
        self.expect(&Token::RParen)?;
        
        self.skip_type_annotation();
        
        let body = self.parse_block_stmts()?;
        
        Ok(HirExpr::Function { name, params, body })
    }
    
    fn parse_var(&mut self) -> Result<HirExpr> {
        let is_mut = matches!(self.advance(), Token::Let);
        let name = match self.advance() {
            Token::Ident(n) => n,
            _ => anyhow::bail!("Expected variable name"),
        };
        
        self.skip_type_annotation();
        
        let init = if matches!(self.peek(), Token::Assign) {
            self.advance();
            Some(Box::new(self.parse_expr()?))
        } else {
            None
        };
        
        if matches!(self.peek(), Token::Semicolon) {
            self.advance();
        }
        
        Ok(HirExpr::Var { name, init, is_mut })
    }
    
    fn parse_return(&mut self) -> Result<HirExpr> {
        self.expect(&Token::Return)?;
        let val = if !matches!(self.peek(), Token::Semicolon | Token::RBrace) {
            Some(Box::new(self.parse_expr()?))
        } else {
            None
        };
        if matches!(self.peek(), Token::Semicolon) {
            self.advance();
        }
        Ok(HirExpr::Return(val))
    }
    
    fn parse_throw(&mut self) -> Result<HirExpr> {
        self.expect(&Token::Throw)?;
        let val = if !matches!(self.peek(), Token::Semicolon | Token::RBrace) {
            Some(Box::new(self.parse_expr()?))
        } else {
            None
        };
        if matches!(self.peek(), Token::Semicolon) {
            self.advance();
        }
        Ok(HirExpr::Throw(val))
    }
    
    fn parse_try_catch(&mut self) -> Result<HirExpr> {
        self.expect(&Token::Try)?;
        let try_body = self.parse_block_stmts()?;
        
        let catch_param = if matches!(self.peek(), Token::Catch) {
            self.advance();
            if matches!(self.peek(), Token::LParen) {
                self.advance();
                let param = if let Token::Ident(name) = self.peek().clone() {
                    self.advance();
                    self.skip_type_annotation();
                    Some(name)
                } else {
                    self.skip_type_annotation();
                    None
                };
                self.expect(&Token::RParen)?;
                param
            } else {
                None
            }
        } else {
            None
        };
        
        let catch_body = if catch_param.is_some() || matches!(self.peek(), Token::LBrace) {
            Some(self.parse_block_stmts()?)
        } else {
            None
        };
        
        let finally_body = if matches!(self.peek(), Token::Finally) {
            self.advance();
            Some(self.parse_block_stmts()?)
        } else {
            None
        };
        
        Ok(HirExpr::TryCatch {
            try_body,
            catch_param,
            catch_body,
            finally_body,
        })
    }
    
    fn parse_if(&mut self) -> Result<HirExpr> {
        self.expect(&Token::If)?;
        self.expect(&Token::LParen)?;
        let cond = Box::new(self.parse_expr()?);
        self.expect(&Token::RParen)?;
        
        let then_body = self.parse_block_stmts()?;
        
        let else_body = if matches!(self.peek(), Token::Else) {
            self.advance();
            if matches!(self.peek(), Token::If) {
                vec![self.parse_if()?]
            } else {
                self.parse_block_stmts()?
            }
        } else {
            vec![]
        };
        
        Ok(HirExpr::If { cond, then_body, else_body: if else_body.is_empty() { None } else { Some(else_body) } })
    }
    
    fn parse_while(&mut self) -> Result<HirExpr> {
        self.expect(&Token::While)?;
        self.expect(&Token::LParen)?;
        let cond = Box::new(self.parse_expr()?);
        self.expect(&Token::RParen)?;
        
        let body = self.parse_block_stmts()?;
        
        Ok(HirExpr::While { cond, body })
    }
    
    fn parse_for(&mut self) -> Result<HirExpr> {
        self.expect(&Token::For)?;
        self.expect(&Token::LParen)?;
        
        // 检查是否为 for...in 或 for...of 循环
        // for (const key in data) { ... }
        // for (const item of array) { ... }
        let is_for_in_of = if matches!(self.peek(), Token::Let | Token::Const) {
            // 保存位置，向前看是否有 in/of
            let saved_pos = self.pos;
            self.advance(); // skip let/const
            if matches!(self.peek(), Token::Ident(_)) {
                self.advance(); // skip ident
                let result = matches!(self.peek(), Token::In) || 
                    matches!(self.peek(), Token::Ident(_)) && {
                        if let Token::Ident(s) = self.peek() { s == "of" } else { false }
                    };
                self.pos = saved_pos;
                result
            } else {
                self.pos = saved_pos;
                false
            }
        } else {
            false
        };
        
        if is_for_in_of {
            // for (const/let key in/of expr) { body }
            let _init = self.parse_var()?;
            // 跳过 in 或 of
            if matches!(self.peek(), Token::In) {
                self.advance();
            } else if matches!(self.peek(), Token::Ident(_)) {
                if let Token::Ident(s) = self.peek().clone() {
                    if s == "of" {
                        self.advance();
                    }
                }
            }
            let _iterable = self.parse_expr()?;
            self.expect(&Token::RParen)?;
            let body = self.parse_block_stmts()?;
            // for-in/of 简化为空循环（不生成遍历代码）
            Ok(HirExpr::For { 
                init: None, 
                cond: Some(Box::new(HirExpr::Boolean(false))), 
                update: None, 
                body 
            })
        } else {
            // 标准 for 循环
            let init = if matches!(self.peek(), Token::Let | Token::Const) {
                Some(Box::new(self.parse_var()?))
            } else if !matches!(self.peek(), Token::Semicolon) {
                let expr = self.parse_expr()?;
                if matches!(self.peek(), Token::Semicolon) {
                    self.advance();
                }
                Some(Box::new(expr))
            } else {
                None
            };
            if init.is_none() {
                self.expect(&Token::Semicolon)?;
            }
            
            let cond = if !matches!(self.peek(), Token::Semicolon) {
                Some(Box::new(self.parse_expr()?))
            } else {
                None
            };
            self.expect(&Token::Semicolon)?;
        
        let update = if !matches!(self.peek(), Token::RParen) {
            Some(Box::new(self.parse_expr()?))
        } else {
            None
        };
        self.expect(&Token::RParen)?;
        
        let body = self.parse_block_stmts()?;
        
        Ok(HirExpr::For { init, cond, update, body })
        }
    }
    
    fn parse_block(&mut self) -> Result<HirExpr> {
        self.expect(&Token::LBrace)?;
        let stmts = self.parse_block_stmts()?;
        Ok(HirExpr::Block(stmts))
    }
    
    fn parse_block_stmts(&mut self) -> Result<Vec<HirExpr>> {
        self.expect(&Token::LBrace)?;
        let mut stmts = Vec::new();
        while !matches!(self.peek(), Token::RBrace) {
            if let Some(stmt) = self.parse_stmt()? {
                stmts.push(stmt);
            }
        }
        self.expect(&Token::RBrace)?;
        Ok(stmts)
    }
    
    fn parse_expr(&mut self) -> Result<HirExpr> {
        self.parse_assignment()
    }
    
    fn parse_assignment(&mut self) -> Result<HirExpr> {
        let left = self.parse_ternary()?;
        
        match self.peek() {
            Token::Assign => {
                self.advance();
                let right = self.parse_assignment()?;
                Ok(HirExpr::Assign {
                    target: Box::new(left),
                    value: Box::new(right),
                })
            }
            Token::PlusAssign => {
                self.advance();
                let right = self.parse_assignment()?;
                let value = HirExpr::Binary {
                    op: BinOp::Add,
                    left: Box::new(left.clone()),
                    right: Box::new(right),
                };
                Ok(HirExpr::Assign {
                    target: Box::new(left),
                    value: Box::new(value),
                })
            }
            Token::MinusAssign => {
                self.advance();
                let right = self.parse_assignment()?;
                let value = HirExpr::Binary {
                    op: BinOp::Sub,
                    left: Box::new(left.clone()),
                    right: Box::new(right),
                };
                Ok(HirExpr::Assign {
                    target: Box::new(left),
                    value: Box::new(value),
                })
            }
            Token::StarAssign => {
                self.advance();
                let right = self.parse_assignment()?;
                let value = HirExpr::Binary {
                    op: BinOp::Mul,
                    left: Box::new(left.clone()),
                    right: Box::new(right),
                };
                Ok(HirExpr::Assign {
                    target: Box::new(left),
                    value: Box::new(value),
                })
            }
            Token::SlashAssign => {
                self.advance();
                let right = self.parse_assignment()?;
                let value = HirExpr::Binary {
                    op: BinOp::Div,
                    left: Box::new(left.clone()),
                    right: Box::new(right),
                };
                Ok(HirExpr::Assign {
                    target: Box::new(left),
                    value: Box::new(value),
                })
            }
            _ => Ok(left)
        }
    }
    
    fn parse_ternary(&mut self) -> Result<HirExpr> {
        let cond = self.parse_or()?;
        
        if matches!(self.peek(), Token::Question) {
            self.advance();
            let then_expr = self.parse_expr()?;
            self.expect(&Token::Colon)?;
            let else_expr = self.parse_ternary()?;
            
            Ok(HirExpr::Ternary {
                cond: Box::new(cond),
                then_expr: Box::new(then_expr),
                else_expr: Box::new(else_expr),
            })
        } else {
            Ok(cond)
        }
    }
    
    fn parse_or(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_and()?;
        
        while matches!(self.peek(), Token::OrOr) {
            self.advance();
            let right = self.parse_and()?;
            left = HirExpr::Binary {
                op: BinOp::Or,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_and(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_equality()?;
        
        while matches!(self.peek(), Token::AndAnd) {
            self.advance();
            let right = self.parse_equality()?;
            left = HirExpr::Binary {
                op: BinOp::And,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_equality(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_comparison()?;
        
        loop {
            let op = match self.peek() {
                Token::EqEqEq | Token::EqEq => BinOp::Eq,
                Token::NotEqEq | Token::NotEq => BinOp::Ne,
                _ => break,
            };
            self.advance();
            let right = self.parse_comparison()?;
            left = HirExpr::Binary {
                op,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_comparison(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_additive()?;
        
        loop {
            let op = match self.peek() {
                Token::Lt => BinOp::Lt,
                Token::Le => BinOp::Le,
                Token::Gt => BinOp::Gt,
                Token::Ge => BinOp::Ge,
                _ => break,
            };
            self.advance();
            let right = self.parse_additive()?;
            left = HirExpr::Binary {
                op,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_additive(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_multiplicative()?;
        
        loop {
            let op = match self.peek() {
                Token::Plus => BinOp::Add,
                Token::Minus => BinOp::Sub,
                _ => break,
            };
            self.advance();
            let right = self.parse_multiplicative()?;
            left = HirExpr::Binary {
                op,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_multiplicative(&mut self) -> Result<HirExpr> {
        let mut left = self.parse_unary()?;
        
        loop {
            let op = match self.peek() {
                Token::Star => BinOp::Mul,
                Token::Slash => BinOp::Div,
                Token::Percent => BinOp::Mod,
                _ => break,
            };
            self.advance();
            let right = self.parse_unary()?;
            left = HirExpr::Binary {
                op,
                left: Box::new(left),
                right: Box::new(right),
            };
        }
        
        Ok(left)
    }
    
    fn parse_unary(&mut self) -> Result<HirExpr> {
        if matches!(self.peek(), Token::Typeof) {
            self.advance();
            let operand = self.parse_unary()?;
            return Ok(HirExpr::Typeof(Box::new(operand)));
        }
        
        let op = match self.peek() {
            Token::Not => UnaryOp::Not,
            Token::Minus => UnaryOp::Neg,
            _ => return self.parse_primary(),
        };
        self.advance();
        let operand = self.parse_unary()?;
        Ok(HirExpr::Unary {
            op,
            operand: Box::new(operand),
        })
    }
    
    fn parse_primary(&mut self) -> Result<HirExpr> {
        match self.peek().clone() {
            Token::Number(n) => {
                self.advance();
                Ok(HirExpr::Number(n))
            }
            Token::String(s) => {
                self.advance();
                Ok(HirExpr::String(s))
            }
            Token::TemplateParts(parts) => {
                self.advance();
                if parts.len() == 1 {
                    Ok(HirExpr::String(parts[0].clone()))
                } else {
                    let mut result: Option<HirExpr> = None;
                    let mut i = 0;
                    while i < parts.len() {
                        if i % 2 == 0 {
                            let str_part = HirExpr::String(parts[i].clone());
                            result = Some(match result {
                                None => str_part,
                                Some(prev) => HirExpr::Binary {
                                    op: BinOp::Add,
                                    left: Box::new(prev),
                                    right: Box::new(str_part),
                                },
                            });
                        } else {
                            let expr_source = &parts[i];
                            let mut sub_parser = Parser::new(expr_source);
                            let expr = sub_parser.parse_expr()?;
                            result = Some(match result {
                                None => expr,
                                Some(prev) => HirExpr::Binary {
                                    op: BinOp::Add,
                                    left: Box::new(prev),
                                    right: Box::new(expr),
                                },
                            });
                        }
                        i += 1;
                    }
                    Ok(result.unwrap_or(HirExpr::String(String::new())))
                }
            }
            Token::Bool(b) => {
                self.advance();
                Ok(HirExpr::Boolean(b))
            }
            Token::Null => {
                self.advance();
                Ok(HirExpr::Null)
            }
            Token::Undefined => {
                self.advance();
                Ok(HirExpr::Undefined)
            }
            Token::Ident(name) => {
                // 检查是否为单参数箭头函数: x => ...
                if self.tokens.len() > self.pos + 1 && matches!(self.tokens[self.pos + 1], Token::Arrow) {
                    self.advance(); // skip ident
                    return self.parse_arrow_body(vec![name]);
                }
                
                self.advance();
                
                let mut expr = HirExpr::Identifier(name);
                
                loop {
                    match self.peek() {
                        Token::LParen => {
                            self.advance();
                            let mut args = Vec::new();
                            while !matches!(self.peek(), Token::RParen) {
                                args.push(self.parse_expr()?);
                                if matches!(self.peek(), Token::Comma) {
                                    self.advance();
                                }
                            }
                            self.expect(&Token::RParen)?;
                            expr = HirExpr::Call {
                                callee: Box::new(expr),
                                args,
                            };
                        }
                        Token::LBracket => {
                            self.advance();
                            let index = self.parse_expr()?;
                            self.expect(&Token::RBracket)?;
                            expr = HirExpr::Index {
                                object: Box::new(expr),
                                index: Box::new(index),
                            };
                        }
                        Token::Dot => {
                            self.advance();
                            let prop_name = match self.peek().clone() {
                                Token::Ident(name) => {
                                    self.advance();
                                    name
                                }
                                _ => anyhow::bail!("Expected property name after '.'"),
                            };
                            expr = HirExpr::Property {
                                object: Box::new(expr),
                                name: prop_name,
                            };
                        }
                        Token::PlusPlus => {
                            self.advance();
                            let one = HirExpr::Number(1.0);
                            expr = HirExpr::Assign {
                                target: Box::new(expr.clone()),
                                value: Box::new(HirExpr::Binary {
                                    op: BinOp::Add,
                                    left: Box::new(expr),
                                    right: Box::new(one),
                                }),
                            };
                        }
                        Token::MinusMinus => {
                            self.advance();
                            let one = HirExpr::Number(1.0);
                            expr = HirExpr::Assign {
                                target: Box::new(expr.clone()),
                                value: Box::new(HirExpr::Binary {
                                    op: BinOp::Sub,
                                    left: Box::new(expr),
                                    right: Box::new(one),
                                }),
                            };
                        }
                        _ => break,
                    }
                }
                
                Ok(expr)
            }
            Token::LParen => {
                // 检查是否为箭头函数: () => ... 或 (params) => ...
                let is_arrow = self.is_arrow_function();
                if is_arrow {
                    self.parse_arrow_function()
                } else {
                    self.advance();
                    let expr = self.parse_expr()?;
                    self.expect(&Token::RParen)?;
                    Ok(expr)
                }
            }
            Token::LBracket => {
                self.advance();
                let mut elements = Vec::new();
                while !matches!(self.peek(), Token::RBracket) {
                    elements.push(self.parse_expr()?);
                    if matches!(self.peek(), Token::Comma) {
                        self.advance();
                    }
                }
                self.expect(&Token::RBracket)?;
                Ok(HirExpr::Array(elements))
            }
            Token::LBrace => {
                self.advance();
                let mut properties = Vec::new();
                while !matches!(self.peek(), Token::RBrace) {
                    let key = match self.peek().clone() {
                        Token::Ident(name) => {
                            self.advance();
                            name
                        }
                        Token::String(s) => {
                            self.advance();
                            s
                        }
                        _ => anyhow::bail!("Expected property name"),
                    };
                    self.expect(&Token::Colon)?;
                    let value = self.parse_expr()?;
                    properties.push((key, value));
                    if matches!(self.peek(), Token::Comma) {
                        self.advance();
                    }
                }
                self.expect(&Token::RBrace)?;
                Ok(HirExpr::Object(properties))
            }
            _ => anyhow::bail!("Unexpected token: {:?}", self.peek()),
        }
    }
    
    fn is_arrow_function(&self) -> bool {
        // 前瞻检查 (params) => 模式
        let mut depth = 0;
        let mut i = self.pos;
        while i < self.tokens.len() {
            match &self.tokens[i] {
                Token::LParen => depth += 1,
                Token::RParen => {
                    depth -= 1;
                    if depth == 0 {
                        // 检查 ) 后是否为 =>
                        return i + 1 < self.tokens.len() && matches!(self.tokens[i + 1], Token::Arrow);
                    }
                }
                _ => {}
            }
            i += 1;
        }
        false
    }
    
    fn parse_arrow_function(&mut self) -> Result<HirExpr> {
        // (params) => body
        self.expect(&Token::LParen)?;
        let mut params = Vec::new();
        while !matches!(self.peek(), Token::RParen) {
            if let Token::Ident(name) = self.peek().clone() {
                self.advance();
                params.push(name);
                self.skip_type_annotation();
            }
            if matches!(self.peek(), Token::Comma) {
                self.advance();
            }
        }
        self.expect(&Token::RParen)?;
        self.parse_arrow_body(params)
    }
    
    fn parse_arrow_body(&mut self, params: Vec<String>) -> Result<HirExpr> {
        // => body
        self.expect(&Token::Arrow)?;
        
        let body = if matches!(self.peek(), Token::LBrace) {
            // 块体: => { stmts }
            self.parse_block_stmts()?
        } else {
            // 表达式体: => expr，等价于 { return expr; }
            let expr = self.parse_expr()?;
            vec![HirExpr::Return(Some(Box::new(expr)))]
        };
        
        // 生成匿名函数名
        let name = format!("__arrow_{}", self.pos);
        Ok(HirExpr::Function { name, params, body })
    }
}

pub fn parse(source: &str) -> Result<Vec<HirExpr>> {
    let mut parser = Parser::new(source);
    parser.parse_module()
}
