/**
 * @fileoverview Parser primary expression handling
 */

import {
  ExpressionType,
  TokenType,
  type ExpressionNode
} from '../types/index.js';

/**
 * Complete implementation of parsePrimary method for OrdoJSParser
 */
export function parsePrimary(context: any): ExpressionNode {
  const start = context.current();

  if (context.match(TokenType.BOOLEAN)) {
    const value = context.previous().value === 'true';
    return {
      type: 'Expression',
      expressionType: ExpressionType.LITERAL,
      value,
      range: context.createRange(start.position, context.previous().position)
    };
  }

  if (context.match(TokenType.NUMBER)) {
    const value = parseFloat(context.previous().value);
    return {
      type: 'Expression',
      expressionType: ExpressionType.LITERAL,
      value,
      range: context.createRange(start.position, context.previous().position)
    };
  }

  if (context.match(TokenType.STRING)) {
    const value = context.previous().value;
    return {
      type: 'Expression',
      expressionType: ExpressionType.LITERAL,
      value,
      range: context.createRange(start.position, context.previous().position)
    };
  }

  if (context.match(TokenType.IDENTIFIER)) {
    const identifier = context.previous().value;
    return {
      type: 'Expression',
      expressionType: ExpressionType.IDENTIFIER,
      identifier,
      range: context.createRange(start.position, context.previous().position)
    };
  }

  if (context.match(TokenType.LEFT_PAREN)) {
    const expr = context.parseExpression();
    context.consume(TokenType.RIGHT_PAREN, "Expected ')' after expression");
    return expr;
  }

  // Handle array literals
  if (context.match(TokenType.LEFT_BRACKET)) {
    const elements: ExpressionNode[] = [];

    if (!context.check(TokenType.RIGHT_BRACKET)) {
      do {
        elements.push(context.parseExpression());
      } while (context.match(TokenType.COMMA));
    }

    context.consume(TokenType.RIGHT_BRACKET, "Expected ']' after array elements");
    const end = context.previous();

    return {
      type: 'Expression',
      expressionType: ExpressionType.ARRAY,
      arguments: elements,
      range: context.createRange(start.position, end.position)
    };
  }

  // Handle object literals
  if (context.match(TokenType.LEFT_BRACE)) {
    const properties: { key: string; value: ExpressionNode }[] = [];

    if (!context.check(TokenType.RIGHT_BRACE)) {
      do {
        const keyToken = context.consume(TokenType.IDENTIFIER, "Expected property name");
        context.consume(TokenType.COLON, "Expected ':' after property name");
        const value = context.parseExpression();
        properties.push({ key: keyToken.value, value });
      } while (context.match(TokenType.COMMA));
    }

    context.consume(TokenType.RIGHT_BRACE, "Expected '}' after object properties");
    const end = context.previous();

    return {
      type: 'Expression',
      expressionType: ExpressionType.OBJECT,
      value: properties,
      range: context.createRange(start.position, end.position)
    };
  }

  throw context.createError("Expected expression", ["literal", "identifier", "parenthesized expression"], context.peek().value);
}
