import type { Item, ValidationResult } from './types';
import { parseExpression } from './parser';

/**
 * 校验表达式语法是否合法
 *
 * 检查项：空表达式、括号匹配、操作符/操作数相邻位置合理性
 */
export function validateExpression(expr: string, operandSet: Set<string>): ValidationResult {
  if (!expr?.trim()) return { valid: false, message: '表达式不能为空' };

  // 括号匹配
  let count = 0;
  for (const char of expr) {
    if (char === '(') count++;
    if (char === ')') count--;
    if (count < 0) return { valid: false, message: '括号不匹配' };
  }
  if (count !== 0) return { valid: false, message: '括号不匹配' };

  // 基本语法：检查操作符是否孤立（简单启发）
  const tokens = parseExpression(expr, operandSet);
  if (tokens.length === 0) return { valid: false, message: '无法解析表达式' };

  for (let i = 0; i < tokens.length - 1; i++) {
    const cur = tokens[i];
    const next = tokens[i + 1];

    if (cur.type === 'operand' && (next.type === 'number' || next.type === 'operand')) {
      return { valid: false, message: `监测变量 ${cur.value} 位置可能不正确` };
    }
    if (cur.type === 'operator' && (next.type === 'operator' || next.type === 'logic' || next.type === 'rightParen')) {
      return { valid: false, message: `运算符 ${cur.value} 后缺少操作数` };
    }
    if (cur.type === 'logic' && (next.type === 'logic' || next.type === 'rightParen')) {
      return { valid: false, message: `逻辑符 ${cur.value} 位置可能不正确` };
    }
    if (cur.type === 'number' && (next.type === 'operand' || next.type === 'number')) {
      return { valid: false, message: `数值 ${cur.value} 位置可能不正确` };
    }
  }

  return { valid: true };
}

/**
 * 判断 items 最外层（depth=0）是否同时存在 && 和 ||
 */
export function checkTopLevelMixed(items: Item[]): boolean {
  let depth = 0;
  let hasAnd = false;
  let hasOr = false;
  for (const item of items) {
    if (item.type === 'leftParen') {
      depth++;
    } else if (item.type === 'rightParen') {
      depth--;
    } else if (item.type === 'logic' && depth === 0) {
      if (item.value === '&&') hasAnd = true;
      else if (item.value === '||') hasOr = true;
    }
  }
  return hasAnd && hasOr;
}

/**
 * 基于 items 为混合优先级表达式自动添加括号
 *
 * 仅在最外层 || 分隔的段中，对未加括号且包含 && 的段添加括号
 */
export function addParenthesesForAnd(items: Item[]): string {
  if (!items.length) return items.map((i) => i.value).join(' ');

  // 1. 计算每个 token 在整体表达式中的嵌套深度
  const depths: number[] = [];
  let depth = 0;
  for (const t of items) {
    if (t.type === 'leftParen') {
      depths.push(depth);
      depth++;
    } else if (t.type === 'rightParen') {
      depth--;
      depths.push(depth);
    } else {
      depths.push(depth);
    }
  }

  // 2. 按最外层 (depth === 0) 的 || 切分成段
  const segments: Item[][] = [];
  let current: Item[] = [];
  for (let i = 0; i < items.length; i++) {
    if (items[i].type === 'logic' && items[i].value === '||' && depths[i] === 0) {
      if (current.length) segments.push(current);
      current = [];
    } else {
      current.push(items[i]);
    }
  }
  if (current.length) segments.push(current);

  // 3. 辅助：判断段是否已被一整对括号包裹
  const isEnclosed = (seg: Item[]): boolean => {
    if (seg.length < 2) return false;
    if (seg[0].type !== 'leftParen' || seg[seg.length - 1].type !== 'rightParen') return false;
    let bal = 0;
    for (let i = 1; i < seg.length - 1; i++) {
      if (seg[i].type === 'leftParen') bal++;
      else if (seg[i].type === 'rightParen') bal--;
      if (bal < 0) return false;
    }
    return bal === 0;
  };

  // 4. 辅助：判断段内是否存在最外层 (深度为0) 的 &&
  const hasTopLevelAnd = (seg: Item[]): boolean => {
    let d = 0;
    for (const t of seg) {
      if (t.type === 'leftParen') d++;
      else if (t.type === 'rightParen') d--;
      else if (t.type === 'logic' && t.value === '&&' && d === 0) return true;
    }
    return false;
  };

  // 5. 重建表达式，对需要的段添加括号
  return segments
    .map((seg) => {
      const str = seg.map((i) => i.value).join(' ');
      if (!isEnclosed(seg) && hasTopLevelAnd(seg)) {
        return `( ${str} )`;
      }
      return str;
    })
    .join(' || ');
}
