import Decimal from "decimal.js";
import { ElMessage } from "element-plus";

// class Counter {
//   private result: Decimal;

//   constructor() {
//     this.result = new Decimal(0);
//   }

//   // 加法
//   addition(val: number | string): this {
//     this.result = this.result.plus(new Decimal(val));
//     return this;
//   }

//   // 减法
//   subtraction(val: number | string): this {
//     this.result = this.result.minus(new Decimal(val));
//     return this;
//   }

//   // 乘法
//   multiplication(val: number | string): this {
//     this.result = this.result.times(new Decimal(val));
//     return this;
//   }

//   // 除法
//   division(val: number | string): this {
//     if (new Decimal(val).isZero()) {
//       throw new Error("除数不能为零");
//     }
//     this.result = this.result.dividedBy(new Decimal(val));
//     return this;
//   }

//   // 计算表达式
//   calculate(expression: string): this {
//     const tokens = this.tokenize(expression);
//     const parsedExpression = this.parse(tokens);
//     this.result = new Decimal(this.evaluate(parsedExpression));
//     return this;
//   }

//   // 获取结果
//   get(): number {
//     return this.result.toNumber(); // 返回普通数字
//   }

//   // 词法分析，将字符串分割为token
//   private tokenize(expression: string): Array<string> {
//     return expression.match(/(\d+(\.\d+)?|[-+*/()])/g) || [];
//   }

//   // 解析表达式
//   private parse(tokens: Array<string>): Array<Decimal | string> {
//     const output: Array<Decimal | string> = [];
//     const operators: Array<string> = [];
//     const precedence: { [key: string]: number } = {
//       "+": 1,
//       "-": 1,
//       "*": 2,
//       "/": 2
//     };

//     for (let i = 0; i < tokens.length; i++) {
//       const token = tokens[i];

//       // 检查连续运算符
//       if (i > 0 && this.isOperator(token) && this.isOperator(tokens[i - 1])) {
//         this.showWarning("公式错误");
//         return []; // 返回空数组表示错误
//       }

//       if (!isNaN(Number(token))) {
//         output.push(new Decimal(token));
//       } else if (token === "(") {
//         operators.push(token);
//       } else if (token === ")") {
//         while (operators.length && operators[operators.length - 1] !== "(") {
//           output.push(operators.pop()!);
//         }
//         operators.pop(); // 弹出 '('
//       } else {
//         while (
//           operators.length &&
//           precedence[operators[operators.length - 1]] >= precedence[token]
//         ) {
//           output.push(operators.pop()!);
//         }
//         operators.push(token);
//       }
//     }

//     while (operators.length) {
//       output.push(operators.pop()!);
//     }

//     return output;
//   }

//   // 判断是否为运算符
//   private isOperator(token: string): boolean {
//     return ["+", "-", "*", "/"].includes(token);
//   }

//   private showWarning(message: string): void {
//     ElMessage({
//       message: message,
//       type: "warning"
//     });
//   }

//   // 计算解析后的表达式
//   private evaluate(parsedExpression: Array<Decimal | string>): number {
//     const stack: Array<Decimal> = [];

//     for (const token of parsedExpression) {
//       if (token instanceof Decimal) {
//         stack.push(token);
//       } else {
//         const b = stack.pop()!;
//         const a = stack.pop()!;
//         switch (token) {
//           case "+":
//             stack.push(a.plus(b));
//             break;
//           case "-":
//             stack.push(a.minus(b));
//             break;
//           case "*":
//             stack.push(a.times(b));
//             break;
//           case "/":
//             if (b.isZero()) {
//               this.showWarning("除数不能为零");
//               throw new Error("除数不能为零");
//             }
//             stack.push(a.dividedBy(b));
//             break;
//         }
//       }
//     }

//     return stack[0].toNumber(); // 返回计算结果
//   }
// }
class Counter {
  private result: Decimal;

  constructor() {
    this.result = new Decimal(0);
  }

  // 加法
  addition(val: number | string): this {
    this.result = this.result.plus(new Decimal(val));
    return this;
  }

  // 减法
  subtraction(val: number | string): this {
    this.result = this.result.minus(new Decimal(val));
    return this;
  }

  // 乘法
  multiplication(val: number | string): this {
    this.result = this.result.times(new Decimal(val));
    return this;
  }

  // 除法
  division(val: number | string): this {
    if (new Decimal(val).isZero()) {
      throw new Error("除数不能为零");
    }
    this.result = this.result.dividedBy(new Decimal(val));
    return this;
  }

  // 计算表达式
  calculate(expression: string): this {
    const tokens = this.tokenize(expression);
    const parsedExpression = this.parse(tokens);
    this.result = new Decimal(this.evaluate(parsedExpression));
    return this;
  }

  // 获取结果
  get(): number {
    return this.result.toNumber(); // 返回普通数字
  }

  // 词法分析，将字符串分割为token
  private tokenize(expression: string): Array<string> {
    return expression.match(/-?\d+(\.\d+)?|[-+*/()]/g) || [];
  }

  // 解析表达式
  private parse(tokens: Array<string>): Array<Decimal | string> {
    const output: Array<Decimal | string> = [];
    const operators: Array<string> = [];
    const precedence: { [key: string]: number } = {
      "+": 1,
      "-": 1,
      "*": 2,
      "/": 2
    };

    for (let i = 0; i < tokens.length; i++) {
      const token = tokens[i];

      // 检查连续运算符
      if (i > 0 && this.isOperator(token) && this.isOperator(tokens[i - 1])) {
        this.showWarning("公式错误");
        return []; // 返回空数组表示错误
      }

      if (!isNaN(Number(token))) {
        output.push(new Decimal(token));
      } else if (token === "(") {
        operators.push(token);
      } else if (token === ")") {
        while (operators.length && operators[operators.length - 1] !== "(") {
          output.push(operators.pop()!);
        }
        operators.pop(); // 弹出 '('
      } else {
        while (
          operators.length &&
          precedence[operators[operators.length - 1]] >= precedence[token]
        ) {
          output.push(operators.pop()!);
        }
        operators.push(token);
      }
    }

    while (operators.length) {
      output.push(operators.pop()!);
    }

    return output;
  }

  // 判断是否为运算符
  private isOperator(token: string): boolean {
    return ["+", "-", "*", "/"].includes(token);
  }

  private showWarning(message: string): void {
    // 假设 ElMessage 是某个库的消息提示函数
    ElMessage({
      message: message,
      type: "warning"
    });
  }

  // 计算解析后的表达式
  private evaluate(parsedExpression: Array<Decimal | string>): number {
    const stack: Array<Decimal> = [];
    for (const token of parsedExpression) {
      if (token instanceof Decimal) {
        stack.push(token);
      } else {
        const b = stack.pop()!;
        const a = stack.pop()!;
        switch (token) {
          case "+":
            stack.push(a.plus(b));
            break;
          case "-":
            stack.push(a.minus(b));
            break;
          case "*":
            stack.push(a.times(b));
            break;
          case "/":
            if (b.isZero()) {
              this.showWarning("除数不能为零");
              throw new Error("除数不能为零");
            }
            stack.push(a.dividedBy(b));
            break;
        }
      }
    }

    return stack[0].toNumber(); // 返回计算结果
  }
}

// 使用示例
// const calculator = new Counter();
// calculator.calculate("3.5 + 2.3 * (2 - 8)");
// console.log(calculator.get()); // 输出结果
export const calculator = new Counter();
