// import { parseAndGetSyntaxErrors } from './utils/parser'
import { IError, ErrorListener } from './errorListener'

import { CharStreams, CommonTokenStream } from 'antlr4ts';
import { openqasmLexer } from '../antlr/openqasmLexer';
import { openqasmParser, QopContext, StatementContext } from '../antlr/openqasmParser';
import { Interval } from 'antlr4ts/misc/Interval';

interface SymbolInfo {
  name: string;
  type: 'qreg' | 'creg' | 'gate';
  size?: number;
  line: number;
  column: number;
}

function getOriginalText(code: string, startIndex: number, endIndex: number) {
  const inputStream = CharStreams.fromString(code);
  return inputStream.getText(new Interval(startIndex, endIndex));
}


export default class LanguageService {
  private symbols: Map<string, SymbolInfo> = new Map();
  private indentSize = 2; // 缩进大小

  // 验证代码，返回错误列表
  public validate(code: string): IError[] {
    // const errors = parseAndGetSyntaxErrors(code);
    const errorListener = new ErrorListener();
    const syntaxErrors = this.getLexicalAndSyntaxErrors(code, errorListener);
    const semanticErrors = this.getSemanticErrors(code);
    return [...syntaxErrors, ...semanticErrors];
  }

  // 格式化代码
  public format(code: string): string {
    const ast = this.parseCode(code);
    if (!ast) return code; // 如果解析失败，返回原始代码

    const inputStream = CharStreams.fromString(code);
    const lexer = new openqasmLexer(inputStream);
    const allTokens = lexer.getAllTokens();

    // 收集所有注释及其位置
    const comments = allTokens
      .filter(t => {
        const name = lexer.vocabulary.getSymbolicName(t.type);
        return name === 'COMMENT' || name === 'LINE_COMMENT';
      })
      .map(t => ({
        text: t.text || '',  // 确保 text 不会是 undefined
        line: t.line,
        type: lexer.vocabulary.getSymbolicName(t.type),
        startIndex: t.startIndex,
        stopIndex: t.stopIndex
      }));

    let result = '';
    let indentLevel = 0;
    let currentLine = 1;

    try {
      // 格式化版本声明
      const version = ast.version();
      // 插入版本声明之前的注释
      result = this.insertCommentsBeforeLine(comments, currentLine, 0, result);
      result += 'OPENQASM ' + version.REAL().text + ';\n';
      currentLine++;

      // 格式化include语句
      const includeStmt = ast.includeStatement();
      if (includeStmt) {
        // 插入include语句之前的注释
        result = this.insertCommentsBeforeLine(comments, currentLine, 0, result);
        result += 'include ' + includeStmt.STRING_LITERAL().text + ';\n';
        currentLine++;
      }
      // 添加一个空行分隔头部声明
      result += '\n';
      currentLine++;

      // 格式化所有语句
      ast.statement().forEach(stmt => {
        // 插入当前语句之前的注释
        result = this.insertCommentsBeforeLine(comments, stmt.start.line, indentLevel, result);
        // 处理声明语句
        if (stmt.decl()) {
          const decl = stmt.decl()!;
          result += this.getIndent(indentLevel) + getOriginalText(code, decl.start.startIndex, decl.stop!.stopIndex) + '\n';
          currentLine = decl.stop!.line + 1;
        }
        // 处理门声明
        else if (stmt.gatedecl()) {
          const gateDecl = stmt.gatedecl()!;
          result += this.getIndent(indentLevel) + gateDecl.text.trim() + '\n';
          indentLevel++;
          currentLine = gateDecl.start.line + 1;

          // 处理门操作列表
          if (stmt.goplist()) {
            const gopList = stmt.goplist()!;
            gopList.children?.forEach(gop => {
              // 插入门操作之前的注释
              result = this.insertCommentsBeforeLine(comments, gop.sourceInterval.a, indentLevel, result);
              result += this.getIndent(indentLevel) + gop.text.trim() + '\n';
              currentLine = gop.sourceInterval.b + 1;
            });
          }

          indentLevel--;
          result += this.getIndent(indentLevel) + '}\n';
          currentLine++;
        }
        // 处理量子操作
        else if (stmt.qop()) {
          const qop = stmt.qop()!;

          // 处理测量操作
          if (qop.text.startsWith('measure')) {
            result += this.formatMeasureOp(qop, indentLevel, code);
          }
          // 处理其他量子操作
          else {
            result += this.formatQuantumOp(qop, indentLevel, code);
          }
          currentLine = qop.stop!.line + 1;
        }
        // 处理条件语句
        else if (stmt.text.startsWith('if')) {
          result += this.getIndent(indentLevel) + this.formatIfStatement(stmt) + '\n';
          currentLine = stmt.stop!.line + 1;
        }
        // 处理barrier语句
        else if (stmt.text.startsWith('barrier')) {
          result += this.getIndent(indentLevel) + 'barrier ' +
            this.formatArgumentList(stmt.text.substring(7).trim()) + ';\n';
          currentLine = stmt.stop!.line + 1;
        }
      });

      // 插入文件末尾的注释
      result = this.insertRemainingComments(comments, indentLevel, result);

    } catch (e) {
      console.log("格式化错误:", e);
      return code; // 如果格式化失败，返回原始代码
    }

    return result;
  }

  // 在指定行之前插入注释
  private insertCommentsBeforeLine(
    comments: Array<{ text: string; line: number; type: string | undefined; startIndex: number; stopIndex: number }>,
    targetLine: number,
    indentLevel: number,
    code: string
  ): string {
    let result = code;
    while (comments.length > 0 && comments[0].line < targetLine) {
      const comment = comments.shift()!;
      if (comment.type === 'LINE_COMMENT') {
        result += this.getIndent(indentLevel) + comment.text + '\n';
      } else {
        // 多行注释，保持原有格式
        const commentLines = comment.text.split('\n');
        commentLines.forEach((line, index) => {
          if (index === 0) {
            result += this.getIndent(indentLevel) + line + '\n';
          } else {
            result += this.getIndent(indentLevel) + line.trimLeft() + '\n';
          }
        });
      }
    }
    return result;
  }

  // 插入剩余的注释
  private insertRemainingComments(
    comments: Array<{ text: string; line: number; type: string | undefined; startIndex: number; stopIndex: number }>,
    indentLevel: number,
    code: string
  ): string {
    let result = code;
    comments.forEach(comment => {
      if (comment.type === 'LINE_COMMENT') {
        result += this.getIndent(indentLevel) + comment.text + '\n';
      } else {
        const commentLines = comment.text.split('\n');
        commentLines.forEach((line, index) => {
          if (index === 0) {
            result += this.getIndent(indentLevel) + line + '\n';
          } else {
            result += this.getIndent(indentLevel) + line.trimLeft() + '\n';
          }
        });
      }
    });
    return result;
  }

  // 格式化测量操作
  private formatMeasureOp(qop: QopContext, indentLevel: number, code: string): string {
    const text = getOriginalText(code, qop.start.startIndex, qop.stop!.stopIndex)
    const args = text.match(/measure\s+(.*?)\s*->\s*(.*?);/);
    if (!args) return this.getIndent(indentLevel) + text.trim() + '\n';

    return this.getIndent(indentLevel) + 'measure ' +
      this.formatArgument(args[1]) + ' -> ' +
      this.formatArgument(args[2]) + ';\n';
  }

  // 格式化量子操作
  private formatQuantumOp(qop: QopContext, indentLevel: number, code: string): string {
    if (!qop.uop()) return this.getIndent(indentLevel) + getOriginalText(code, qop.start.startIndex, qop.stop!.stopIndex) + '\n';

    const uop = qop.uop()!;
    const text = getOriginalText(code, uop.start.startIndex, uop.stop!.stopIndex)

    // 处理U门
    if (text.startsWith('U')) {
      const match = text.match(/U\s*\((.*?)\)\s*(.*?);/);
      if (!match) return this.getIndent(indentLevel) + text.trim() + '\n';

      return this.getIndent(indentLevel) + 'U(' +
        this.formatExpressionList(match[1]) + ') ' +
        this.formatArgument(match[2]) + ';\n';
    }
    // 处理CX门
    else if (text.startsWith('CX')) {
      const match = text.match(/CX\s+(.*?)\s*,\s*(.*?);/);
      if (!match) return this.getIndent(indentLevel) + text.trim() + '\n';

      return this.getIndent(indentLevel) + 'CX ' +
        this.formatArgument(match[1]) + ', ' +
        this.formatArgument(match[2]) + ';\n';
    }
    // 处理其他门
    else {
      const match = text.match(/([a-zA-Z0-9_]+)\s*(?:\((.*?)\))?\s*(.*?);/);
      if (!match) return this.getIndent(indentLevel) + text.trim() + '\n';

      let formatted = this.getIndent(indentLevel) + match[1];
      if (match[2]) {
        formatted += '(' + this.formatExpressionList(match[2]) + ')';
      }
      formatted += ' ' + this.formatArgumentList(match[3]) + ';\n';
      return formatted;
    }
  }

  // 格式化if语句
  private formatIfStatement(stmt: StatementContext): string {
    const match = stmt.text.match(/if\s*\(\s*(.*?)\s*==\s*(.*?)\s*\)\s*(.*)/);
    if (!match) return stmt.text.trim();

    return 'if (' + match[1].trim() + ' == ' + match[2].trim() + ') ' +
      match[3].trim();
  }

  // 格式化参数列表
  private formatArgumentList(args: string): string {
    return args.split(',')
      .map(arg => this.formatArgument(arg))
      .join(', ');
  }

  // 格式化单个参数
  private formatArgument(arg: string): string {
    const match = arg.match(/([a-zA-Z0-9_]+)(?:\[(\d+)\])?/);
    if (!match) return arg.trim();

    if (match[2]) {
      return match[1].trim() + '[' + match[2] + ']';
    }
    return match[1].trim();
  }

  // 格式化表达式列表
  private formatExpressionList(exps: string): string {
    return exps.split(',')
      .map(exp => this.formatExpression(exp))
      .join(', ');
  }

  // 格式化单个表达式
  private formatExpression(exp: string): string {
    // 移除多余的空格
    exp = exp.trim();

    // 在操作符两边添加单个空格
    exp = exp.replace(/\s*([+\-*/^])\s*/g, ' $1 ');

    // 移除括号内侧的空格
    exp = exp.replace(/\(\s+/g, '(').replace(/\s+\)/g, ')');

    return exp;
  }

  // 获取缩进字符串
  private getIndent(level: number): string {
    return ' '.repeat(level * this.indentSize);
  }

  // 解析代码，返回AST
  private parseCode(code: string, errorListener?: ErrorListener) {
    try {
      const inputStream = CharStreams.fromString(code);
      const lexer = new openqasmLexer(inputStream);

      if (errorListener) {
        lexer.removeErrorListeners();
        lexer.addErrorListener(errorListener);
      }

      const tokenStream = new CommonTokenStream(lexer);
      const parser = new openqasmParser(tokenStream);

      if (errorListener) {
        parser.removeErrorListeners();
        parser.addErrorListener(errorListener);
      }

      // 调用你的语法的起始规则
      return parser.mainprog()
    } catch (e) {
      console.error("解析错误:", e);
      return null;
    }
  }

  // 获取词法和语法错误
  private getLexicalAndSyntaxErrors(code: string, errorListener: ErrorListener): IError[] {
    this.parseCode(code, errorListener);
    return errorListener.getErrors();
  }

  // 获取语义错误
  private getSemanticErrors(code: string): IError[] {
    const ast = this.parseCode(code);
    console.log('ast', ast)
    if (!ast) return [];

    const errors: IError[] = [];
    this.symbols.clear();

    try {
      // 遍历所有声明语句
      ast.statement().forEach(stmt => {
        // 检查寄存器声明
        if (stmt.decl()) {
          const decl = stmt.decl()!;
          const declText = decl.text;
          // 解析声明文本
          const qregMatch = declText.match(/qreg+([a-z][A-Za-z0-9_]*)\s*\[\s*(\d+)\s*\]/);
          const cregMatch = declText.match(/creg+([a-z][A-Za-z0-9_]*)\s*\[\s*(\d+)\s*\]/);

          if (qregMatch) {
            const [, name, sizeStr] = qregMatch;
            const size = parseInt(sizeStr);

            // 检查重复声明
            if (this.symbols.has(name)) {
              errors.push({
                startLineNumber: decl.start.line,
                endLineNumber: decl.start.line,
                startColumn: decl.start.charPositionInLine,
                endColumn: decl.start.charPositionInLine + name.length,
                message: `量子寄存器 '${name}' 已被声明`,
                severity: 8,
                code: "duplicate_declaration"
              });
            } else if (size <= 0) {
              errors.push({
                startLineNumber: decl.start.line,
                endLineNumber: decl.start.line,
                startColumn: decl.start.charPositionInLine,
                endColumn: decl.start.charPositionInLine + name.length,
                message: `量子寄存器 '${name}' 的大小必须大于0`,
                severity: 8,
                code: "invalid_size"
              });
            } else {
              this.symbols.set(name, {
                name,
                type: 'qreg',
                size,
                line: decl.start.line,
                column: decl.start.charPositionInLine
              });
            }
          } else if (cregMatch) {
            const [, name, sizeStr] = cregMatch;
            const size = parseInt(sizeStr);

            if (this.symbols.has(name)) {
              errors.push({
                startLineNumber: decl.start.line,
                endLineNumber: decl.start.line,
                startColumn: decl.start.charPositionInLine,
                endColumn: decl.start.charPositionInLine + name.length,
                message: `经典寄存器 '${name}' 已被声明`,
                severity: 8,
                code: "duplicate_declaration"
              });
            } else if (size <= 0) {
              errors.push({
                startLineNumber: decl.start.line,
                endLineNumber: decl.start.line,
                startColumn: decl.start.charPositionInLine,
                endColumn: decl.start.charPositionInLine + name.length,
                message: `经典寄存器 '${name}' 的大小必须大于0`,
                severity: 8,
                code: "invalid_size"
              });
            } else {
              this.symbols.set(name, {
                name,
                type: 'creg',
                size,
                line: decl.start.line,
                column: decl.start.charPositionInLine
              });
            }
          }
        }

        // 检查量子操作
        if (stmt.qop()) {
          const qop = stmt.qop()!;

          // 检查测量操作
          if (qop.text.startsWith('measure')) {
            const args = qop.argument();
            if (args && args.length >= 2) {
              const qreg = args[0].text.split('[')[0];
              const creg = args[1].text.split('[')[0];

              // 检查量子寄存器
              if (!this.symbols.has(qreg)) {
                errors.push({
                  startLineNumber: qop.start.line,
                  endLineNumber: qop.start.line,
                  startColumn: qop.start.charPositionInLine,
                  endColumn: qop.start.charPositionInLine + qreg.length,
                  message: `未声明的量子寄存器 '${qreg}'`,
                  severity: 8,
                  code: "undefined_qreg"
                });
              } else if (this.symbols.get(qreg)!.type !== 'qreg') {
                errors.push({
                  startLineNumber: qop.start.line,
                  endLineNumber: qop.start.line,
                  startColumn: qop.start.charPositionInLine,
                  endColumn: qop.start.charPositionInLine + qreg.length,
                  message: `'${qreg}' 不是量子寄存器`,
                  severity: 8,
                  code: "invalid_register_type"
                });
              }

              // 检查经典寄存器
              if (!this.symbols.has(creg)) {
                errors.push({
                  startLineNumber: qop.start.line,
                  endLineNumber: qop.start.line,
                  startColumn: qop.start.charPositionInLine,
                  endColumn: qop.start.charPositionInLine + creg.length,
                  message: `未声明的经典寄存器 '${creg}'`,
                  severity: 8,
                  code: "undefined_creg"
                });
              } else if (this.symbols.get(creg)!.type !== 'creg') {
                errors.push({
                  startLineNumber: qop.start.line,
                  endLineNumber: qop.start.line,
                  startColumn: qop.start.charPositionInLine,
                  endColumn: qop.start.charPositionInLine + creg.length,
                  message: `'${creg}' 不是经典寄存器`,
                  severity: 8,
                  code: "invalid_register_type"
                });
              }
            }
          }

          // 检查其他量子操作（U门、CX门等）
          if (qop.uop()) {
            const uop = qop.uop()!;
            const args = uop.argument();

            if (args) {
              args.forEach(arg => {
                const regName = arg.text.split('[')[0];

                // 检查未声明的寄存器
                if (!this.symbols.has(regName)) {
                  errors.push({
                    startLineNumber: arg.start.line,
                    endLineNumber: arg.start.line,
                    startColumn: arg.start.charPositionInLine,
                    endColumn: arg.start.charPositionInLine + regName.length,
                    message: `未声明的寄存器 '${regName}'`,
                    severity: 8,
                    code: "undefined_register"
                  });
                } else {
                  // 检查索引范围
                  const match = arg.text.match(/\[(\d+)\]/);
                  if (match) {
                    const index = parseInt(match[1]);
                    const symbol = this.symbols.get(regName)!;
                    if (index >= symbol.size!) {
                      errors.push({
                        startLineNumber: arg.start.line,
                        endLineNumber: arg.start.line,
                        startColumn: arg.start.charPositionInLine,
                        endColumn: arg.start.charPositionInLine + arg.text.length,
                        message: `索引 ${index} 超出寄存器 '${regName}' 的范围 [0, ${symbol.size! - 1}]`,
                        severity: 8,
                        code: "index_out_of_range"
                      });
                    }
                  }
                }
              });
            }
          }
        }
      });
    } catch (e) {
      console.error("语义分析错误:", e);
    }

    return errors;
  }
}
