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

/// Canvas용 마을/상점 애니메이션 합성기
///
/// 마을 배경 + 상점 건물 + 캐릭터
/// Phase 4: 종족별 캐릭터 프레임 지원
class CanvasTownComposer {
  const CanvasTownComposer({this.raceId});

  /// 종족 ID (종족별 캐릭터 프레임 선택용)
  final String? raceId;

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

  /// 레이어 기반 프레임 생성
  List<AsciiLayer> composeLayers(int globalTick) {
    return [
      _createBackgroundLayer(),
      _createShopLayer(),
      _createCharacterLayer(globalTick),
    ];
  }

  /// 마을 배경 레이어 생성 (z=0)
  AsciiLayer _createBackgroundLayer() {
    final cells = List.generate(
      frameHeight,
      (_) => List.filled(frameWidth, AsciiCell.empty),
    );

    // 하늘 (상단 2줄)
    for (var x = 0; x < frameWidth; x++) {
      // 별/구름 패턴
      if (x % 12 == 3) {
        cells[0][x] = AsciiCell.fromChar('*');
      }
      if (x % 8 == 5) {
        cells[1][x] = AsciiCell.fromChar('~');
      }
    }

    // 바닥 (하단 1줄)
    for (var x = 0; x < frameWidth; x++) {
      cells[7][x] = AsciiCell.fromChar('=');
    }

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

  /// 상점 건물 레이어 생성 (z=1)
  AsciiLayer _createShopLayer() {
    const shopLines = [
      r'     ___________      ',
      r'    /   SHOP    \     ',
      r'   |  _______    |    ',
      r'   | |       |   |    ',
      r'   | |  $$   |  ||    ',
      r'___|_|_______|__||____',
    ];

    final cells = _spriteToCells(shopLines);

    // 상점 위치 (오른쪽)
    const shopX = 32;
    final shopY = frameHeight - cells.length - 1;

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

  /// 캐릭터 레이어 생성 (z=2)
  /// Phase 4: 종족별 프레임 지원
  AsciiLayer _createCharacterLayer(int globalTick) {
    final frameIndex = globalTick % 4; // 4프레임 루프
    List<String> charFrame;

    // 종족별 프레임 사용 시도
    if (raceId != null && raceId!.isNotEmpty) {
      final raceData = RaceCharacterFrames.get(raceId!);
      if (raceData != null) {
        // idle 프레임 직접 사용 (마을에서는 서있는 자세)
        final idleFrame = raceData.idle[frameIndex % raceData.idle.length];
        charFrame = idleFrame.lines;
      } else {
        charFrame = _shopIdleFrames[frameIndex];
      }
    } else {
      charFrame = _shopIdleFrames[frameIndex];
    }

    final cells = _spriteToCells(charFrame);

    // 상점 앞에 캐릭터 배치
    const charX = 25;
    final charY = frameHeight - cells.length - 1;

    return AsciiLayer(cells: cells, zIndex: 2, offsetX: charX, offsetY: charY);
  }

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

// ============================================================================
// 상점 앞 대기 프레임 (4프레임 루프) - 물건 보는 동작
// ============================================================================

const _shopIdleFrames = [
  // 프레임 1: 기본
  [r'  o   ', r' /|\  ', r' / \  '],
  // 프레임 2: 머리 숙임
  [r'  o   ', r' /|~  ', r' / \  '],
  // 프레임 3: 물건 보기
  [r'  o?  ', r' /|   ', r' / \  '],
  // 프레임 4: 고개 끄덕
  [r'  o!  ', r' /|\  ', r' / \  '],
];
