package parser

import (
	"fmt"
	"matheval/ast"
	"matheval/token"
	"strconv"
)

// Parse converts a slice of tokens into an AST.
// Returns an error for malformed expressions.
func Parse(tokens []token.Token) (ast.Node, error) {
	p := &parser{tokens: tokens}
	node, err := p.expr()
	if err != nil {
		return nil, err
	}
	// Ensure all tokens have been consumed (only EOF remains).
	if p.current().Type != token.EOF {
		tok := p.current()
		return nil, fmt.Errorf("unexpected token %v at position %d", tok.Type, tok.Pos)
	}
	return node, nil
}

// ParseLine parses a full REPL line, returning either a function definition
// or an expression statement.
func ParseLine(tokens []token.Token) (ast.Statement, error) {
	if len(tokens) == 0 || tokens[0].Type == token.EOF {
		return nil, fmt.Errorf("empty input")
	}

	// Detect function definition: look for Equals token.
	// A function definition has the form: Ident LParen params RParen Equals body
	if isFuncDef(tokens) {
		return parseFuncDef(tokens)
	}

	// Otherwise, parse as expression.
	node, err := Parse(tokens)
	if err != nil {
		return nil, err
	}
	return &ast.ExprStmt{Expr: node}, nil
}

// isFuncDef checks if the token stream looks like a function definition.
// Pattern: Ident LParen ... RParen Equals ...
func isFuncDef(tokens []token.Token) bool {
	if len(tokens) < 5 {
		return false
	}
	if tokens[0].Type != token.Ident {
		return false
	}
	if tokens[1].Type != token.LParen {
		return false
	}
	// Find matching RParen, then check for Equals.
	depth := 0
	for i := 1; i < len(tokens); i++ {
		switch tokens[i].Type {
		case token.LParen:
			depth++
		case token.RParen:
			depth--
			if depth == 0 {
				// Next token must be Equals for this to be a func def.
				if i+1 < len(tokens) && tokens[i+1].Type == token.Equals {
					return true
				}
				return false
			}
		case token.EOF:
			return false
		}
	}
	return false
}

// parseFuncDef parses: Ident LParen param1, param2, ... RParen Equals body
func parseFuncDef(tokens []token.Token) (*ast.FuncDef, error) {
	p := &parser{tokens: tokens}

	// Function name.
	nameTok, err := p.expect(token.Ident)
	if err != nil {
		return nil, fmt.Errorf("expected function name: %w", err)
	}
	name := nameTok.Literal

	// Opening paren.
	if _, err := p.expect(token.LParen); err != nil {
		return nil, fmt.Errorf("expected '(' after function name: %w", err)
	}

	// Parameters: comma-separated identifiers.
	var params []string
	if p.current().Type != token.RParen {
		paramTok, err := p.expect(token.Ident)
		if err != nil {
			return nil, fmt.Errorf("expected parameter name: %w", err)
		}
		params = append(params, paramTok.Literal)

		for p.current().Type == token.Comma {
			p.advance() // consume comma
			paramTok, err := p.expect(token.Ident)
			if err != nil {
				return nil, fmt.Errorf("expected parameter name after ',': %w", err)
			}
			params = append(params, paramTok.Literal)
		}
	}

	// Closing paren.
	if _, err := p.expect(token.RParen); err != nil {
		return nil, fmt.Errorf("expected ')' after parameters: %w", err)
	}

	// Equals sign.
	if _, err := p.expect(token.Equals); err != nil {
		return nil, fmt.Errorf("expected '=' in function definition: %w", err)
	}

	// Body expression.
	body, err := p.expr()
	if err != nil {
		return nil, fmt.Errorf("error in function body: %w", err)
	}

	// Ensure all tokens consumed.
	if p.current().Type != token.EOF {
		tok := p.current()
		return nil, fmt.Errorf("unexpected token %v at position %d after function body", tok.Type, tok.Pos)
	}

	return &ast.FuncDef{
		Name:   name,
		Params: params,
		Body:   body,
	}, nil
}

// parser holds the state for a single parse operation.
type parser struct {
	tokens []token.Token
	pos    int
}

// current returns the token at the current position.
func (p *parser) current() token.Token {
	if p.pos >= len(p.tokens) {
		return token.Token{Type: token.EOF}
	}
	return p.tokens[p.pos]
}

// advance moves to the next token and returns the previous one.
func (p *parser) advance() token.Token {
	tok := p.current()
	p.pos++
	return tok
}

// expect consumes a token of the given type or returns an error.
func (p *parser) expect(typ token.Type) (token.Token, error) {
	tok := p.current()
	if tok.Type != typ {
		return tok, fmt.Errorf("expected %v but got %v at position %d", typ, tok.Type, tok.Pos)
	}
	p.advance()
	return tok, nil
}

// expr → term (('+' | '-') term)*
func (p *parser) expr() (ast.Node, error) {
	left, err := p.term()
	if err != nil {
		return nil, err
	}
	for p.current().Type == token.Plus || p.current().Type == token.Minus {
		op := p.advance()
		right, err := p.term()
		if err != nil {
			return nil, err
		}
		left = &ast.BinaryExpr{
			Op:    op.Type,
			Left:  left,
			Right: right,
		}
	}
	return left, nil
}

// term → factor (('*' | '/') factor)*
func (p *parser) term() (ast.Node, error) {
	left, err := p.factor()
	if err != nil {
		return nil, err
	}
	for p.current().Type == token.Star || p.current().Type == token.Slash {
		op := p.advance()
		right, err := p.factor()
		if err != nil {
			return nil, err
		}
		left = &ast.BinaryExpr{
			Op:    op.Type,
			Left:  left,
			Right: right,
		}
	}
	return left, nil
}

// factor → NUMBER | IDENT | IDENT '(' args ')' | '(' expr ')'
func (p *parser) factor() (ast.Node, error) {
	tok := p.current()
	switch tok.Type {
	case token.Number:
		p.advance()
		val, err := strconv.ParseFloat(tok.Literal, 64)
		if err != nil {
			return nil, fmt.Errorf("invalid number %q at position %d: %w", tok.Literal, tok.Pos, err)
		}
		return &ast.NumberLit{Value: val}, nil

	case token.Ident:
		p.advance()
		// If followed by '(', this is a function call.
		if p.current().Type == token.LParen {
			p.advance() // consume '('
			var args []ast.Node
			if p.current().Type != token.RParen {
				arg, err := p.expr()
				if err != nil {
					return nil, err
				}
				args = append(args, arg)
				for p.current().Type == token.Comma {
					p.advance() // consume ','
					arg, err := p.expr()
					if err != nil {
						return nil, err
					}
					args = append(args, arg)
				}
			}
			if _, err := p.expect(token.RParen); err != nil {
				return nil, fmt.Errorf("expected ')' after function arguments at position %d", p.current().Pos)
			}
			return &ast.FuncCall{Name: tok.Literal, Args: args}, nil
		}
		// Otherwise, it's a variable reference.
		return &ast.Ident{Name: tok.Literal}, nil

	case token.LParen:
		p.advance() // consume '('
		node, err := p.expr()
		if err != nil {
			return nil, err
		}
		if _, err := p.expect(token.RParen); err != nil {
			return nil, fmt.Errorf("missing closing parenthesis at position %d", p.current().Pos)
		}
		return node, nil

	default:
		return nil, fmt.Errorf("unexpected token %v at position %d", tok.Type, tok.Pos)
	}
}
