import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
import 'package:asciineverdie/data/game_translations_ja.dart';
import 'package:asciineverdie/data/game_translations_ko.dart';
import 'package:asciineverdie/src/core/util/pq_logic.dart';
import 'package:flutter/widgets.dart';

/// 게임 데이터 번역을 위한 헬퍼 클래스
/// 현재 로케일에 따라 게임 데이터의 번역을 제공합니다.
///
/// 글로벌 로케일 시스템(game_text_l10n.dart)을 사용하여 일관성 보장
class GameDataL10n {
  GameDataL10n._();

  /// 현재 로케일이 한국어인지 확인 (글로벌 로케일 사용)
  static bool _isKorean(BuildContext context) {
    // 글로벌 로케일 우선, 폴백으로 context 로케일 사용
    if (l10n.isKoreanLocale) return true;
    final locale = Localizations.localeOf(context);
    return locale.languageCode == 'ko';
  }

  /// 현재 로케일이 일본어인지 확인 (글로벌 로케일 사용)
  static bool _isJapanese(BuildContext context) {
    if (l10n.isJapaneseLocale) return true;
    final locale = Localizations.localeOf(context);
    return locale.languageCode == 'ja';
  }

  /// 종족 이름 번역
  static String getRaceName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return raceTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 직업 이름 번역
  static String getKlassName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return klassTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 주문 이름 번역
  static String getSpellName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return spellTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 몬스터 이름 번역
  static String getMonsterName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return monsterTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 무기 이름 번역
  static String getWeaponName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return weaponTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 갑옷 이름 번역
  static String getArmorName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return armorTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 방패 이름 번역
  static String getShieldName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return shieldTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 칭호 번역
  static String getTitleName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return titleTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 인상적인 칭호 번역
  static String getImpressiveTitleName(
    BuildContext context,
    String englishName,
  ) {
    if (_isKorean(context)) {
      return impressiveTitleTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 아이템 속성 번역
  static String getItemAttribName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return itemAttribTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 아이템 접미사 번역
  static String getItemOfName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return itemOfsTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 공격 속성 번역
  static String getOffenseAttribName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return offenseAttribTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 나쁜 공격 속성 번역
  static String getOffenseBadName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return offenseBadTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 방어 속성 번역
  static String getDefenseAttribName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return defenseAttribTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 나쁜 방어 속성 번역
  static String getDefenseBadName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return defenseBadTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 특수 아이템 번역
  static String getSpecialName(BuildContext context, String englishName) {
    if (_isKorean(context)) {
      return specialTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 일반 게임 텍스트 번역 (context 없이 로케일 직접 지정)
  static String getRaceNameByLocale(String englishName, String languageCode) {
    if (languageCode == 'ko') {
      return raceTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 직업 이름 번역 (context 없이)
  static String getKlassNameByLocale(String englishName, String languageCode) {
    if (languageCode == 'ko') {
      return klassTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 몬스터 이름 번역 (context 없이)
  static String getMonsterNameByLocale(
    String englishName,
    String languageCode,
  ) {
    if (languageCode == 'ko') {
      return monsterTranslationsKo[englishName] ?? englishName;
    }
    return englishName;
  }

  /// 구조화된 장비 결과를 로컬라이즈된 문자열로 렌더링
  /// 예: EquipResult(baseName: "Keyboard", modifiers: ["Optimized"], plusValue: 2)
  /// → 영어: "+2 Optimized Keyboard"
  /// → 한국어: "+2 최적화된 키보드"
  static String renderEquipResult(
    BuildContext context,
    EquipResult result,
    int slotIndex,
  ) {
    if (_isKorean(context)) {
      return _renderEquipResultKo(result, slotIndex);
    }
    return result.displayName;
  }

  /// 한국어 장비 렌더링 (내부 함수)
  static String _renderEquipResultKo(EquipResult result, int slotIndex) {
    // 기본 장비 이름 번역
    String baseName;
    if (slotIndex == 0) {
      baseName = weaponTranslationsKo[result.baseName] ?? result.baseName;
    } else if (slotIndex == 1) {
      baseName = shieldTranslationsKo[result.baseName] ?? result.baseName;
    } else {
      baseName = armorTranslationsKo[result.baseName] ?? result.baseName;
    }

    // 수식어 번역 (공격용 vs 방어용)
    final isWeapon = slotIndex == 0;
    final translatedModifiers = result.modifiers.map((mod) {
      if (isWeapon) {
        // 공격 속성: offenseAttrib 또는 offenseBad
        return offenseAttribTranslationsKo[mod] ??
            offenseBadTranslationsKo[mod] ??
            mod;
      } else {
        // 방어 속성: defenseAttrib 또는 defenseBad
        return defenseAttribTranslationsKo[mod] ??
            defenseBadTranslationsKo[mod] ??
            mod;
      }
    }).toList();

    // 조합: 수식어들 + 기본 이름
    var name = baseName;
    for (final mod in translatedModifiers) {
      name = '$mod $name';
    }

    // +/- 수치 추가
    if (result.plusValue != 0) {
      final sign = result.plusValue > 0 ? '+' : '';
      name = '$sign${result.plusValue} $name';
    }

    return name;
  }

  /// 구조화된 아이템 결과를 로컬라이즈된 문자열로 렌더링
  /// 예: ItemResult(attrib: "Golden", special: "Iterator", itemOf: "Compilation")
  /// → 영어: "Golden Iterator of Compilation"
  /// → 한국어: "컴파일의 황금 이터레이터"
  static String renderItemResult(BuildContext context, ItemResult result) {
    if (_isKorean(context)) {
      return _renderItemResultKo(result);
    }
    return result.displayName;
  }

  /// 한국어 아이템 렌더링 (내부 함수)
  static String _renderItemResultKo(ItemResult result) {
    // 단순 아이템 (boringItem)
    if (result.boringItem != null) {
      return boringItemTranslationsKo[result.boringItem] ?? result.boringItem!;
    }

    // 복합 아이템: attrib + special + itemOf
    final attrib = result.attrib != null
        ? (itemAttribTranslationsKo[result.attrib] ?? result.attrib!)
        : null;
    final special = result.special != null
        ? (specialTranslationsKo[result.special] ?? result.special!)
        : null;
    final itemOf = result.itemOf != null
        ? (itemOfsTranslationsKo[result.itemOf] ?? result.itemOf!)
        : null;

    // 한국어 어순: "X의 Y" 패턴
    // "Golden Iterator of Compilation" → "컴파일의 황금 이터레이터"
    if (attrib != null && special != null && itemOf != null) {
      return '$itemOf의 $attrib $special';
    }

    // attrib + special만 있는 경우
    if (attrib != null && special != null) {
      return '$attrib $special';
    }

    return '';
  }

  /// 장비 이름 문자열 파싱 후 번역 (기존 저장 데이터 호환)
  /// 예: "+2 Optimized GPU-Powered Keyboard" → "+2 최적화된 GPU 파워 키보드"
  static String translateEquipString(
    BuildContext context,
    String equipString,
    int slotIndex,
  ) {
    final isKo = _isKorean(context);
    final isJa = _isJapanese(context);
    if ((!isKo && !isJa) || equipString.isEmpty) return equipString;

    // 1. +/- 값 추출
    final plusMatch = RegExp(r'^([+-]?\d+)\s+').firstMatch(equipString);
    String remaining = equipString;
    String plusPart = '';
    if (plusMatch != null) {
      plusPart = plusMatch.group(1)!;
      remaining = equipString.substring(plusMatch.end);
    }

    // 2. 기본 장비 이름 찾기 (가장 긴 매칭 우선)
    // 통합 맵 사용 (추가 번역 포함)
    final Map<String, String> baseMap;
    if (isKo) {
      if (slotIndex == 0) {
        baseMap = weaponTranslationsKo;
      } else if (slotIndex == 1) {
        baseMap = allShieldTranslationsKo;
      } else {
        baseMap = allArmorTranslationsKo;
      }
    } else {
      if (slotIndex == 0) {
        baseMap = weaponTranslationsJa;
      } else if (slotIndex == 1) {
        baseMap = allShieldTranslationsJa;
      } else {
        baseMap = allArmorTranslationsJa;
      }
    }

    String baseTranslated = remaining;
    String modifierPart = '';

    // 기본 장비 이름을 뒤에서부터 찾기
    for (final entry in baseMap.entries) {
      if (remaining.endsWith(entry.key)) {
        baseTranslated = entry.value;
        modifierPart = remaining
            .substring(0, remaining.length - entry.key.length)
            .trim();
        break;
      }
    }

    // 3. 수식어 번역
    final isWeapon = slotIndex == 0;
    final modWords = modifierPart
        .split(' ')
        .where((s) => s.isNotEmpty)
        .toList();
    final translatedMods = modWords.map((mod) {
      if (isKo) {
        if (isWeapon) {
          return offenseAttribTranslationsKo[mod] ??
              offenseBadTranslationsKo[mod] ??
              mod;
        } else {
          return defenseAttribTranslationsKo[mod] ??
              defenseBadTranslationsKo[mod] ??
              mod;
        }
      } else {
        if (isWeapon) {
          return offenseAttribTranslationsJa[mod] ??
              offenseBadTranslationsJa[mod] ??
              mod;
        } else {
          return defenseAttribTranslationsJa[mod] ??
              defenseBadTranslationsJa[mod] ??
              mod;
        }
      }
    }).toList();

    // 4. 조합
    var result = baseTranslated;
    for (final mod in translatedMods.reversed) {
      result = '$mod $result';
    }
    if (plusPart.isNotEmpty) {
      result = '$plusPart $result';
    }

    return result;
  }

  /// 아이템 이름 문자열 파싱 후 번역 (기존 저장 데이터 호환)
  /// 예: "Golden Iterator of Compilation" → "컴파일의 황금 이터레이터"
  /// 예: "index out of bounds Array fragment" → "인덱스 초과의 배열 조각"
  static String translateItemString(BuildContext context, String itemString) {
    final isKo = _isKorean(context);
    final isJa = _isJapanese(context);
    if ((!isKo && !isJa) || itemString.isEmpty) return itemString;

    // 1. specialItem 형식 체크: "Attrib Special of ItemOf"
    // itemOfs에 있는 값으로 끝나는지 확인
    final specialItemResult = _tryTranslateSpecialItem(itemString, isKo);
    if (specialItemResult != null) return specialItemResult;

    // 2. 몬스터 드롭 형식 체크: "{monster_lowercase} {drop_ProperCase}"
    final monsterDropResult = _tryTranslateMonsterDrop(itemString, isKo);
    if (monsterDropResult != null) return monsterDropResult;

    // 3. interestingItem 형식: "Attrib Special" (2단어)
    final words = itemString.split(' ');
    if (words.length == 2) {
      final attrib = words[0];
      final special = words[1];

      if (isKo) {
        final attribKo = itemAttribTranslationsKo[attrib] ?? attrib;
        final specialKo = specialTranslationsKo[special] ?? special;
        return '$attribKo $specialKo';
      } else {
        final attribJa = itemAttribTranslationsJa[attrib] ?? attrib;
        final specialJa = specialTranslationsJa[special] ?? special;
        return '$attribJa $specialJa';
      }
    }

    // 4. 단일 단어 (boringItem 등) - 잡템 번역 시도
    if (isKo) {
      return boringItemTranslationsKo[itemString] ??
          allDropTranslationsKo[itemString.toLowerCase()] ??
          itemString;
    } else {
      return boringItemTranslationsJa[itemString] ??
          allDropTranslationsJa[itemString.toLowerCase()] ??
          itemString;
    }
  }

  /// specialItem 형식 번역 시도
  /// "Attrib Special of ItemOf" → "ItemOf의 Attrib Special"
  static String? _tryTranslateSpecialItem(String itemString, bool isKo) {
    // "of" 뒤의 부분이 itemOfs에 있는지 확인
    final ofMatch = RegExp(r'^(.+)\s+of\s+(.+)$').firstMatch(itemString);
    if (ofMatch == null) return null;

    final beforeOf = ofMatch.group(1)!;
    final afterOf = ofMatch.group(2)!;

    // afterOf가 itemOfs에 있어야 specialItem 형식
    final itemOfsMap = isKo ? itemOfsTranslationsKo : itemOfsTranslationsJa;
    if (!itemOfsMap.containsKey(afterOf)) return null;

    // beforeOf를 Attrib + Special로 분리
    final words = beforeOf.split(' ');
    if (words.length < 2) return null;

    final attrib = words.sublist(0, words.length - 1).join(' ');
    final special = words.last;

    // Attrib와 Special이 유효한지 확인
    final attribMap = isKo
        ? itemAttribTranslationsKo
        : itemAttribTranslationsJa;
    final specialMap = isKo ? specialTranslationsKo : specialTranslationsJa;
    if (!attribMap.containsKey(attrib) && !specialMap.containsKey(special)) {
      return null;
    }

    final attribT = attribMap[attrib] ?? attrib;
    final specialT = specialMap[special] ?? special;
    final itemOfT = itemOfsMap[afterOf] ?? afterOf;

    if (isKo) {
      return '$itemOfT의 $attribT $specialT';
    } else {
      return '$itemOfTの$attribT $specialT';
    }
  }

  /// 몬스터 드롭 형식 번역 시도
  /// "{monster_lowercase} {drop_ProperCase}" → "{몬스터}의 {드롭아이템}"
  static String? _tryTranslateMonsterDrop(String itemString, bool isKo) {
    // 드롭 아이템 번역 맵 선택 (통합 맵 사용)
    final dropMap = isKo ? allDropTranslationsKo : allDropTranslationsJa;
    final monsterMap = isKo
        ? allMonsterTranslationsKo
        : allMonsterTranslationsJa;

    // (대소문자 무시, 아이템 문자열 끝에서 매칭)
    for (final entry in dropMap.entries) {
      final dropItem = entry.key;
      final dropItemProperCase = _properCase(dropItem);

      // 아이템 문자열이 드롭 아이템으로 끝나는지 확인
      if (itemString.endsWith(dropItemProperCase) ||
          itemString.endsWith(dropItem)) {
        // 드롭 아이템 앞 부분이 몬스터 이름
        String monsterPart;
        if (itemString.endsWith(dropItemProperCase)) {
          monsterPart = itemString
              .substring(0, itemString.length - dropItemProperCase.length)
              .trim();
        } else {
          monsterPart = itemString
              .substring(0, itemString.length - dropItem.length)
              .trim();
        }

        if (monsterPart.isEmpty) continue;

        // 몬스터 이름 번역 (소문자를 원래 형태로 변환하여 찾기)
        final monsterNameKey = _toTitleCase(monsterPart);
        final monsterT = monsterMap[monsterNameKey] ?? monsterPart;

        final dropT = entry.value;
        if (isKo) {
          return '$monsterT의 $dropT';
        } else {
          return '$monsterTの$dropT';
        }
      }
    }
    return null;
  }

  /// 첫 글자만 대문자로 (나머지는 그대로)
  static String _properCase(String s) {
    if (s.isEmpty) return s;
    return s[0].toUpperCase() + s.substring(1);
  }

  /// 각 단어의 첫 글자를 대문자로 (Title Case)
  /// 하이픈으로 연결된 단어도 처리 (예: "off-by-one" → "Off-by-One")
  static String _toTitleCase(String s) {
    return s
        .split(' ')
        .map((word) {
          if (word.isEmpty) return word;
          // 하이픈 포함 단어 처리
          if (word.contains('-')) {
            return word
                .split('-')
                .map((part) {
                  if (part.isEmpty) return part;
                  return part[0].toUpperCase() + part.substring(1);
                })
                .join('-');
          }
          return word[0].toUpperCase() + word.substring(1);
        })
        .join(' ');
  }
}
