import 'package:asciineverdie/src/shared/animation/ascii_animation_type.dart';
import 'package:asciineverdie/src/shared/animation/canvas/ascii_cell.dart';
import 'package:asciineverdie/src/shared/animation/canvas/ascii_layer.dart';

/// Canvas용 특수 이벤트 애니메이션 합성기
///
/// 레벨업, 퀘스트 완료, Act 완료, 부활 등
class CanvasSpecialComposer {
  const CanvasSpecialComposer();

  /// 프레임 상수
  static const int frameWidth = 60;
  static const int frameHeight = 8;

  /// 레이어 기반 프레임 생성
  List<AsciiLayer> composeLayers(
    AsciiAnimationType type,
    int frameIndex,
    int globalTick,
  ) {
    return switch (type) {
      AsciiAnimationType.levelUp => _composeLevelUp(frameIndex, globalTick),
      AsciiAnimationType.questComplete => _composeQuestComplete(
        frameIndex,
        globalTick,
      ),
      AsciiAnimationType.actComplete => _composeActComplete(
        frameIndex,
        globalTick,
      ),
      AsciiAnimationType.resurrection => _composeResurrection(
        frameIndex,
        globalTick,
      ),
      _ => [AsciiLayer.empty()],
    };
  }

  /// 레벨업 애니메이션
  List<AsciiLayer> _composeLevelUp(int frameIndex, int globalTick) {
    final layers = <AsciiLayer>[
      _createEffectBackground(globalTick, '*'),
      _createCenteredSprite(_levelUpFrames[frameIndex % _levelUpFrames.length]),
    ];
    return layers;
  }

  /// 퀘스트 완료 애니메이션
  List<AsciiLayer> _composeQuestComplete(int frameIndex, int globalTick) {
    final layers = <AsciiLayer>[
      _createEffectBackground(globalTick, '+'),
      _createCenteredSprite(
        _questCompleteFrames[frameIndex % _questCompleteFrames.length],
      ),
    ];
    return layers;
  }

  /// Act 완료 애니메이션
  List<AsciiLayer> _composeActComplete(int frameIndex, int globalTick) {
    final layers = <AsciiLayer>[
      _createEffectBackground(globalTick, '~'),
      _createCenteredSprite(
        _actCompleteFrames[frameIndex % _actCompleteFrames.length],
      ),
    ];
    return layers;
  }

  /// 부활 애니메이션
  List<AsciiLayer> _composeResurrection(int frameIndex, int globalTick) {
    final layers = <AsciiLayer>[
      _createEffectBackground(globalTick, '.'),
      _createCenteredSprite(
        _resurrectionFrames[frameIndex % _resurrectionFrames.length],
      ),
    ];
    return layers;
  }

  /// 이펙트 배경 레이어 생성 (z=0)
  AsciiLayer _createEffectBackground(int globalTick, String effectChar) {
    final cells = List.generate(
      frameHeight,
      (_) => List.filled(frameWidth, AsciiCell.empty),
    );

    // 반짝이는 이펙트
    for (var y = 0; y < frameHeight; y++) {
      for (var x = 0; x < frameWidth; x++) {
        final offset = (x + y + globalTick) % 8;
        if (offset == 0) {
          cells[y][x] = AsciiCell.fromChar(effectChar);
        }
      }
    }

    return AsciiLayer(cells: cells, zIndex: 0);
  }

  /// 중앙 정렬 스프라이트 레이어 생성 (z=1)
  AsciiLayer _createCenteredSprite(List<String> lines) {
    final cells = _spriteToCells(lines);

    // 중앙 정렬
    final spriteWidth = lines.isEmpty ? 0 : lines[0].length;
    final offsetX = (frameWidth - spriteWidth) ~/ 2;
    final offsetY = (frameHeight - cells.length) ~/ 2;

    return AsciiLayer(
      cells: cells,
      zIndex: 1,
      offsetX: offsetX,
      offsetY: offsetY,
    );
  }

  /// 문자열 스프라이트를 AsciiCell 2D 배열로 변환
  List<List<AsciiCell>> _spriteToCells(List<String> lines) {
    return lines.map((line) {
      return line.split('').map(AsciiCell.fromChar).toList();
    }).toList();
  }
}

// ============================================================================
// 레벨업 프레임 (5프레임)
// ============================================================================

const _levelUpFrames = [
  [r'    *    ', r'   \|/   ', r'    o    ', r'   /|\   ', r'   / \   '],
  [r'   * *   ', r'   \|/   ', r'    O    ', r'  </|\>  ', r'   / \   '],
  [r'  * * *  ', r'   \|/   ', r'    O    ', r'  <\|/>  ', r'   / \   '],
  [r' * * * * ', r'  LEVEL  ', r'   UP!   ', r'   \O/   ', r'   / \   '],
  [r'* * * * *', r'  LEVEL  ', r'   UP!   ', r'   \O/   ', r'   | |   '],
];

// ============================================================================
// 퀘스트 완료 프레임 (4프레임)
// ============================================================================

const _questCompleteFrames = [
  [r'   [?]   ', r'    |    ', r'    o    ', r'   /|\   ', r'   / \   '],
  [r'  [???]  ', r'    |    ', r'    o!   ', r'   /|\   ', r'   / \   '],
  [r'  [DONE] ', r'    !    ', r'   \o/   ', r'    |    ', r'   / \   '],
  [r' +[DONE]+', r'   \!/   ', r'   \o/   ', r'    |    ', r'   / \   '],
];

// ============================================================================
// Act 완료 프레임 (4프레임)
// ============================================================================

const _actCompleteFrames = [
  [r'=========', r'  ACT    ', r' CLEAR   ', r'    o    ', r'   /|\   '],
  [r'~~~~~~~~~', r'  ACT    ', r' CLEAR!  ', r'   \o/   ', r'    |    '],
  [r'*~*~*~*~*', r'  ACT    ', r' CLEAR!! ', r'   \O/   ', r'   / \   '],
  [r'*********', r'  ACT    ', r' CLEAR!! ', r'   \O/   ', r'   | |   '],
];

// ============================================================================
// 부활 프레임 (5프레임)
// ============================================================================

const _resurrectionFrames = [
  // 프레임 1: R.I.P 묘비
  [r'   ___   ', r'  |RIP|  ', r'  |   |  ', r'__|___|__'],
  // 프레임 2: 빛 내림
  [r'   \|/   ', r'  -|R|-  ', r'  |   |  ', r'__|___|__'],
  // 프레임 3: 일어남
  [r'   \o/   ', r'  --|--  ', r'  |   |  ', r'__|___|__'],
  // 프레임 4: 서있음
  [r'    o    ', r'   /|\   ', r'   / \   ', r'_________'],
  // 프레임 5: 부활 완료
  [r' REVIVED ', r'   \o/   ', r'    |    ', r'___/ \___'],
];
