import 'dart:math';
import 'package:service_api/service_api.dart';
import '../models/math_quiz_models.dart';
import 'package:function_tree/function_tree.dart';

class MathQuizGenerator {
  final Random _random = Random();

  /// 난이도에 맞는 퍼즐을 생성합니다.
  MathQuizPuzzle generatePuzzle(MathQuizDifficulty level) {
    switch (level.layout) {
      case MathQuizLayout.singleLine:
        if (level.operationCount == 2) { // Lv 1-5
          return _generateSimpleEquation(level); // A + B = C
        } else { // operationCount == 3 (Lv 6-10)
          return _generateMultiOpEquation(level); // A + B * C = D
        }
      case MathQuizLayout.linkedL: // operationCount == 4 (Lv 11-15)
        return _generateLinkedEquations(level); // 2x2 그리드
      case MathQuizLayout.gridSquare: 
        if (level.operationCount == 9) { // Lv 10-12 (3x3)
          return _generate3x3GridEquation(level); 
        } else { // Lv 13-15 (4x4)
          return _generate4x4GridEquation(level);
        }
    }
  }

  /// [Lv 1-5] 숫자 2개 연산: (A op B = C)
  MathQuizPuzzle _generateSimpleEquation(MathQuizDifficulty level) {
    // (이전과 동일)
    final (int a, int b, int c, String op) = _createEquation(level.operators);
    final List<String> allParts = (op == '+')
        ? [a.toString(), op, b.toString(), '=', c.toString()]
        : (op == '-')
        ? [c.toString(), op, a.toString(), '=', b.toString()]
        : (op == '*')
        ? [a.toString(), op, b.toString(), '=', c.toString()]
        : [c.toString(), op, a.toString(), '=', b.toString()];
    List<int> candidateIndices;
    switch (level.blankType) {
      case MathQuizBlankType.numbersOnly: candidateIndices = [0, 2]; break;
      case MathQuizBlankType.operatorsOnly: candidateIndices = [1]; break;
      case MathQuizBlankType.numbersAndOperators: candidateIndices = [0, 1, 2]; break;
    }
    final int finalBlankCount = min(level.blankCount, candidateIndices.length);
    final List<int> blankIndices = (candidateIndices..shuffle(_random)).sublist(0, finalBlankCount);
    final List<String> solutions = [];
    final List<String> gridCells = List.of(allParts);
    for (int index in blankIndices) {
      solutions.add(allParts[index]); 
      gridCells[index] = '?'; 
    }
    final Set<String> optionsSet = solutions.toSet(); 
    while (optionsSet.length < 9) {
      optionsSet.add((_random.nextInt(9) + 1).toString());
    }
    optionsSet.addAll(level.operators.split(','));
    if (level.blankType != MathQuizBlankType.operatorsOnly) {
      optionsSet.add('='); 
    }
    final List<String> options = (optionsSet.toList()..shuffle(_random)).toList();
    return MathQuizPuzzle(
      gridCells: gridCells,
      gridCrossAxisCount: 5, // 5x1 그리드
      solutions: solutions,
      options: options,
    );
  }

  /// [Lv 6-10] 숫자 3개 연산: (A op1 B op2 C = D)
  MathQuizPuzzle _generateMultiOpEquation(MathQuizDifficulty level) {
    // 1. 식 생성 (연산자 우선순위 포함)
    final (int a, int b, int c, String op1, String op2, int result) = _createMultiOpEquation(level.operators);
    final List<String> allParts = [a.toString(), op1, b.toString(), op2, c.toString(), '=', result.toString()];
    // 2. 빈칸 생성
    final int blankCount = level.blankCount;
    List<int> candidateIndices;
    switch (level.blankType) {
      case MathQuizBlankType.numbersOnly: candidateIndices = [0, 2, 4]; break;
      case MathQuizBlankType.operatorsOnly: candidateIndices = [1, 3]; break;
      case MathQuizBlankType.numbersAndOperators: candidateIndices = [0, 1, 2, 3, 4]; break;
    }
    final int finalBlankCount = min(blankCount, candidateIndices.length);
    final List<int> blankIndices = (candidateIndices..shuffle(_random)).sublist(0, finalBlankCount);
    final List<String> solutions = [];
    final List<String> gridCells = List.of(allParts);
    for (int index in blankIndices) {
      solutions.add(allParts[index]); 
      gridCells[index] = '?'; 
    }
    // 3. 옵션 생성
    final Set<String> optionsSet = solutions.toSet(); 
    while (optionsSet.length < 9) {
      optionsSet.add((_random.nextInt(9) + 1).toString());
    }
    optionsSet.addAll(level.operators.split(','));
    optionsSet.add('=');
    // 4. 그리드 모델로 반환
    return MathQuizPuzzle(
      gridCells: gridCells,
      gridCrossAxisCount: 7, // 7x1 그리드
      solutions: solutions,
      options: (optionsSet.toList()..shuffle(_random)).toList(),
    );
  }

  /// [Lv 11-15] 숫자 4개 연산: (2x2 그리드 'ㄱ', 'ㄴ')
  MathQuizPuzzle _generateLinkedEquations(MathQuizDifficulty level) {
    // (동적 생성 로직)
    while (true) {
      final int a = _random.nextInt(9) + 1;
      final int b = _random.nextInt(9) + 1;
      final int c = _random.nextInt(9) + 1;
      final int d = _random.nextInt(9) + 1;
      final ops = level.operators.split(',');
      final String op1 = (ops..shuffle(_random)).first;
      final String op2 = (ops..shuffle(_random)).first;
      final String op3 = (ops..shuffle(_random)).first;
      final String op4 = (ops..shuffle(_random)).first;
      final int? r1 = _calculate(a, b, op1); 
      final int? r2 = _calculate(c, d, op2); 
      final int? r3 = _calculate(a, c, op3); 
      final int? r4 = _calculate(b, d, op4); 
      if (r1 == null || r2 == null || r3 == null || r4 == null) continue;
      if (r1 < -99 || r2 < -99 || r3 < -99 || r4 < -99 || r1 > 999 || r2 > 999 || r3 > 999 || r4 > 999) continue;
      
      final List<String> allParts = [
        a.toString(), op1, b.toString(), "=", r1.toString(),
        op3,          " ", op4,          " ", "=",
        c.toString(), op2, d.toString(), "=", r2.toString(),
        "=",          " ", "=",          " ", "=",
        r3.toString(), " ", r4.toString(), " ", " ",
      ];
      final List<String> solutions = [];
      final List<String> gridCells = List.of(allParts);
      List<int> numberIndices = [0, 2, 10, 12]; // A,B,C,D
      List<int> operatorIndices = [1, 5, 7, 11]; // op1,op3,op4,op2
      List<int> blankIndices = [];
      switch (level.blankType) {
        case MathQuizBlankType.numbersOnly:
          blankIndices = (numberIndices..shuffle(_random)).sublist(0, min(level.blankCount, numberIndices.length));
          break;
        case MathQuizBlankType.operatorsOnly:
          blankIndices = (operatorIndices..shuffle(_random)).sublist(0, min(level.blankCount, operatorIndices.length));
          break;
        case MathQuizBlankType.numbersAndOperators:
          blankIndices = (numberIndices + operatorIndices..shuffle(_random)).sublist(0, level.blankCount);
          break;
      }
      blankIndices.sort();
      for (int index in blankIndices) {
        solutions.add(allParts[index]); 
        gridCells[index] = '?'; 
      }
      final Set<String> optionsSet = solutions.toSet(); 
      while (optionsSet.length < 9) {
        optionsSet.add((_random.nextInt(9) + 1).toString());
      }
      optionsSet.addAll(level.operators.split(','));
      optionsSet.add('=');
      
      return MathQuizPuzzle(
        gridCells: gridCells,
        gridCrossAxisCount: 5, // 5x5 그리드
        solutions: solutions,
        options: (optionsSet.toList()..shuffle(_random)).toList(),
      );
    } // end while(true)
  }

  /// [수정됨] 레벨 10-12 (3x3 Grid) - 템플릿 목록 사용
  MathQuizPuzzle _generate3x3GridEquation(MathQuizDifficulty level) {
    // 1. 3x3 템플릿 목록에서 랜덤 선택
    final template = _get3x3Templates()..shuffle();
    final selectedTemplate = template.first;
    
    final List<String> allParts = selectedTemplate.gridCells;
    final List<int> numberIndices = selectedTemplate.numberIndices;
    final List<int> operatorIndices = selectedTemplate.operatorIndices;

    // 2. 난이도(level.blankType)에 따라 빈칸('?') 생성
    final List<String> finalSolutions = [];
    final List<String> gridCells = List.of(allParts);
    
    List<int> blankIndices = [];
    switch (level.blankType) {
      case MathQuizBlankType.numbersOnly:
        blankIndices = (numberIndices..shuffle(_random)).sublist(0, min(level.blankCount, numberIndices.length));
        break;
      case MathQuizBlankType.operatorsOnly:
        blankIndices = (operatorIndices..shuffle(_random)).sublist(0, min(level.blankCount, operatorIndices.length));
        break;
      case MathQuizBlankType.numbersAndOperators:
        blankIndices = (numberIndices + operatorIndices..shuffle(_random)).sublist(0, level.blankCount);
        break;
    }
    
    // 3. 빈칸 적용
    blankIndices.sort();
    for (int index in blankIndices) {
      finalSolutions.add(allParts[index]); 
      gridCells[index] = '?'; 
    }
    
    // 4. 옵션 생성
    final Set<String> optionsSet = finalSolutions.toSet(); // 👈 [오류 수정]
    while (optionsSet.length < 9) {
      optionsSet.add((_random.nextInt(9) + 1).toString());
    }
    optionsSet.addAll(level.operators.split(','));
    optionsSet.add('=');
    
    final List<String> options = (optionsSet.toList()..shuffle(_random)).toList();

    return MathQuizPuzzle(
      gridCells: gridCells,
      gridCrossAxisCount: 7, // 3x3 퍼즐 (7x7 그리드)
      solutions: finalSolutions,
      options: options, // 👈 [오류 수정]
    );
  }

  /// [수정됨] 레벨 13-15 (4x4 Grid) - 템플릿 목록 사용
  MathQuizPuzzle _generate4x4GridEquation(MathQuizDifficulty level) {
    // 1. 4x4 템플릿 목록에서 랜덤 선택
    final template = _get4x4Templates()..shuffle();
    final selectedTemplate = template.first;
    
    final List<String> allParts = selectedTemplate.gridCells;
    final List<int> numberIndices = selectedTemplate.numberIndices;
    final List<int> operatorIndices = selectedTemplate.operatorIndices;

    // 2. 난이도(level.blankType)에 따라 빈칸('?') 생성
    final List<String> finalSolutions = [];
    final List<String> gridCells = List.of(allParts);
    
    List<int> blankIndices = [];
    switch (level.blankType) {
      case MathQuizBlankType.numbersOnly:
        blankIndices = (numberIndices..shuffle(_random)).sublist(0, min(level.blankCount, numberIndices.length));
        break;
      case MathQuizBlankType.operatorsOnly:
        blankIndices = (operatorIndices..shuffle(_random)).sublist(0, min(level.blankCount, operatorIndices.length));
        break;
      case MathQuizBlankType.numbersAndOperators:
        blankIndices = (numberIndices + operatorIndices..shuffle(_random)).sublist(0, level.blankCount);
        break;
    }
    
    // 3. 빈칸 적용
    blankIndices.sort();
    for (int index in blankIndices) {
      finalSolutions.add(allParts[index]); 
      gridCells[index] = '?'; 
    }
    
    // 4. 옵션 생성
    final Set<String> optionsSet = finalSolutions.toSet(); // 👈 [오류 수정]
    while (optionsSet.length < 9) {
      optionsSet.add((_random.nextInt(9) + 1).toString());
    }
    optionsSet.addAll(level.operators.split(','));
    optionsSet.add('=');
    
    final List<String> options = (optionsSet.toList()..shuffle(_random)).toList();

    return MathQuizPuzzle(
      gridCells: gridCells,
      gridCrossAxisCount: 9, // 4x4 퍼즐 (9x9 그리드)
      solutions: finalSolutions,
      options: options, // 👈 [오류 수정]
    );
  }

  /// [HELPER] (A, B, C, op) 튜플 생성 (사칙연산 지원)
  (int, int, int, String) _createEquation(String operators, {int? firstTerm, int maxResult = 9}) {
    // (이전과 동일)
    final List<String> ops = operators.split(',');
    final String op = ops[_random.nextInt(ops.length)];
    int a, b, c;
    switch (op) {
      case '+': 
        a = firstTerm ?? _random.nextInt(maxResult - 1) + 1; 
        b = _random.nextInt(maxResult - a) + 1; 
        c = a + b;
        return (a, b, c, op);
      case '-': 
        c = firstTerm ?? _random.nextInt(maxResult - 1) + 2; 
        a = _random.nextInt(c - 1) + 1; 
        b = c - a;
        return (a, b, c, op);
      case '*': 
        a = firstTerm ?? _random.nextInt(maxResult ~/ 2) + 2; 
        b = _random.nextInt(maxResult ~/ a) + 1; 
        c = a * b;
        return (a, b, c, op);
      case '/': 
        b = _random.nextInt(maxResult ~/ 2) + 1; 
        a = _random.nextInt(maxResult ~/ b) + 1;
        c = a * b; 
        if (c == 0 || a == 0) return _createEquation(operators, firstTerm: firstTerm, maxResult: maxResult); 
        return (a, b, c, op);
      default:
        return (1, 1, 2, '+');
    }
  }
  
  /// [HELPER] 숫자 3개 + 연산자 2개 (우선순위 적용!)
  (int, int, int, String, String, int) _createMultiOpEquation(String operators) {
    while(true) {
      final int a = _random.nextInt(9) + 1;
      final int b = _random.nextInt(9) + 1;
      final int c = _random.nextInt(9) + 1;
      final List<String> ops = operators.split(',');
      final String op1 = (ops..shuffle(_random)).first;
      final String op2 = (ops..shuffle(_random)).first;
      
      final String expression = "$a $op1 $b $op2 $c";
      if (expression.contains('/')) continue; 
      
      final num resultNum = expression.interpret();
      final int result = resultNum.toInt();
      
      if (result == resultNum && result >= -99 && result <= 999) { // [수정] 범위 확장
        return (a, b, c, op1, op2, result);
      }
    }
  }

  /// [HELPER] 두 숫자와 연산자로 계산 (실패 시 null 반환)
  int? _calculate(int a, int b, String op) {
    switch (op) {
      case '+': return a + b;
      case '-': return a - b;
      case '*': return a * b;
      case '/': 
        if (b == 0) return null; // 0으로 나누기
        if (a % b != 0) return null; // 나누어떨어지지 않음
        return a ~/ b; 
    }
    return 0; // 알 수 없는 연산자
  }

  /// [신규] 3x3 그리드 템플릿 목록 (8개)
  List<_GridTemplate> _get3x3Templates() {
    // [!] 템플릿의 수학적 유효성은 이미지 원본을 따르며, 보장되지 않습니다.
    return [
      // 5.53.19.png (top-left)
      _GridTemplate(gridCells:["5","*","3","-","1","=","17","+"," ","*"," ","-"," ","=","2","*","6","-","7","=","5","*"," ","+"," ","+"," ","=","4","+","1","+","1","=","18","="," ","="," ","="," ","=","21"," ","33"," ","22"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.19.png (top-right)
      _GridTemplate(gridCells:["1","+","1","+","5","=","17","/"," ","-"," ","+"," ","=","1","*","3","+","2","=","15","*"," ","+"," ","-"," ","=","6","-","4","+","2","=","0","="," ","="," ","="," ","=","12"," ","12"," ","13"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.19.png (bottom-left)
      _GridTemplate(gridCells:["9","+","5","+","5","=","19","/"," ","-"," ","+"," ","=","2","*","3","+","9","=","15","*"," ","+"," ","-"," ","=","6","-","7","+","1","=","0","="," ","="," ","="," ","=","12"," ","9"," ","16"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.19.png (bottom-right)
      _GridTemplate(gridCells:["7","*","4","-","9","=","39","*"," ","+"," ","*"," ","=","1","*","1","+","8","=","9","+"," ","*"," ","+"," ","=","3","-","4","+","5","=","4","="," ","="," ","="," ","=","11"," ","34"," ","23"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.33.png (top-left)
      _GridTemplate(gridCells:["9","-","5","/","1","=","7","*"," ","-"," ","+"," ","=","8","*","5","-","7","=","27","+"," ","+"," ","+"," ","=","4","+","3","-","7","=","2","="," ","="," ","="," ","=","62"," ","0"," ","12"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.33.png (top-right)
      _GridTemplate(gridCells:["8","*","2","+","6","=","16","*"," ","+"," ","/"," ","=","5","*","9","/","3","=","3","+"," ","+"," ","*"," ","=","7","+","1","+","1","=","19","="," ","="," ","="," ","=","9"," ","18"," ","16"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.33.png (bottom-left)
      _GridTemplate(gridCells:["1","+","7","+","9","=","17","*"," ","+"," ","-"," ","=","8","/","4","+","4","=","8","+"," ","*"," ","/"," ","=","7","*","3","+","3","=","17","="," ","="," ","="," ","=","13"," ","19"," ","6"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
      // 5.53.33.png (bottom-right)
      _GridTemplate(gridCells:["1","+","6","-","9","=","6","/"," ","-"," ","/"," ","=","2","-","7","/","1","=","0","-"," ","/"," ","*"," ","=","9","-","5","+","4","=","0","="," ","="," ","="," ","=","0"," ","6"," ","3"," "," "], numberIndices:[0,2,4,14,16,18,28,30,32], operatorIndices:[1,3,7,9,11,15,17,21,23,25,29,31]),
    ];
  }

  /// [신규] 4x4 그리드 템플릿 목록 (8개)
  List<_GridTemplate> _get4x4Templates() {
    // [!] 템플릿의 수학적 유효성은 이미지 원본을 따르며, 보장되지 않습니다.
    return [
      // 5.54.51.png (top-left)
      _GridTemplate(gridCells:["1","*","4","-","2","+","14","=","16","+"," ","*"," ","/"," ","-"," ","=","15","/","5","*","16","+","13","=","61","+"," ","-"," ","+"," ","+"," ","=","3","/","2","+","4","*","7","=","29","*"," ","+"," ","/"," ","*"," ","=","15","+","11","-","8","*","8","=","-38","="," ","="," ","="," ","="," ","=","102"," ","51"," ","54"," ","95"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.54.51.png (bottom-left)
      _GridTemplate(gridCells:["8","+","4","*","2","+","15","=","114","-"," ","+"," ","-"," ","-"," ","=","6","/","4","+","3","/","2","=","11","-"," ","-"," ","+"," ","-"," ","=","7","*","3","/","5","-","1","=","0","+"," ","-"," ","*"," ","+"," ","=","12","-","1","*","6","+","11","=","14","="," ","="," ","="," ","="," ","=","1"," ","0"," ","44"," ","18"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.54.37.png (top-left)
      _GridTemplate(gridCells:["10","/","2","*","3","+","9","=","24","*"," ","-"," ","*"," ","+"," ","=","2","+","13","*","5","-","7","=","74","+"," ","+"," ","-"," ","+"," ","=","5","*","6","+","1","-","7","=","5","+"," ","-"," ","+"," ","+"," ","=","12","-","11","+","2","*","8","=","49","="," ","="," ","="," ","="," ","=","173"," ","15"," ","17"," ","85"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.54.37.png (bottom-left)
      _GridTemplate(gridCells:["9","*","2","+","8","-","1","=","40","/"," ","/"," ","-"," ","*"," ","=","5","+","2","-","13","+","3","=","3","-"," ","*"," ","+"," ","-"," ","=","7","/","1","-","6","+","4","=","4","+"," ","+"," ","*"," ","+"," ","=","16","+","9","-","7","-","10","=","9","="," ","="," ","="," ","="," ","=","5"," ","29"," ","64"," ","13"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.54.29.png (top-left)
      _GridTemplate(gridCells:["1","-","5","-","4","+","14","=","8","*"," ","/"," ","*"," ","-"," ","=","7","+","2","*","1","-","11","=","14","-"," ","+"," ","+"," ","-"," ","=","2","/","1","*","7","-","6","=","21","+"," ","+"," ","-"," ","+"," ","=","15","*","10","+","1","+","7","=","173","="," ","="," ","="," ","="," ","=","12"," ","18"," ","21"," ","5"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.54.29.png (bottom-left)
      _GridTemplate(gridCells:["9","-","3","-","1","+","13","=","11","*"," ","*"," ","+"," ","+"," ","=","8","*","7","-","9","-","5","=","49","+"," ","+"," ","*"," ","+"," ","=","6","*","5","+","11","-","2","=","41","-"," ","-"," ","-"," ","/"," ","=","15","+","2","-","1","-","4","=","17","="," ","="," ","="," ","="," ","=","71"," ","67"," ","40"," ","18"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.55.00.png (top-left)
      _GridTemplate(gridCells:["9","*","8","-","6","+","7","=","141","*"," ","*"," ","/"," ","-"," ","=","2","+","6","*","5","-","10","=","27","-"," ","-"," ","+"," ","-"," ","=","3","+","1","-","3","*","1","=","3","*"," ","+"," ","+"," ","+"," ","=","11","+","7","*","2","+","8","=","25","="," ","="," ","="," ","="," ","=","19"," ","85"," ","20"," ","9"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
      // 5.55.00.png (bottom-left)
      _GridTemplate(gridCells:["4","-","1","-","2","+","14","=","3","+"," ","*"," ","*"," ","-"," ","=","9","-","1","+","3","-","4","=","7","*"," ","/"," ","-"," ","+"," ","=","6","-","1","+","7","+","1","=","17","+"," ","-"," ","+"," ","*"," ","=","8","*","2","+","1","+","16","=","65","="," ","="," ","="," ","="," ","=","38"," ","9"," ","144"," ","178"," "," "], numberIndices:[0,2,4,6,18,20,22,24,36,38,40,42,54,56,58,60], operatorIndices:[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,45,47,49,51,53,55,57,59,61,63,65,67,69,71]),
    ];
  }
}

/// [신규] 3x3/4x4 템플릿의 내부 구조
class _GridTemplate {
  final List<String> gridCells; 
  final List<int> numberIndices; 
  final List<int> operatorIndices; 

  _GridTemplate({
    required this.gridCells,
    required this.numberIndices,
    required this.operatorIndices,
  });
}