import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

const _translationAssetPrefix = 'assets/translations/';
const _templateFileName = 'template.toml';
const _safeFallbackLocaleCode = 'en';

List<String> extractSupportedLocaleCodesFromAssets(Iterable<String> assets) {
  final localeCodes = <String>{};
  for (final asset in assets) {
    if (!asset.startsWith(_translationAssetPrefix) ||
        !asset.endsWith('.toml')) {
      continue;
    }
    final fileName = asset.substring(_translationAssetPrefix.length);
    if (fileName.contains('/') || fileName == _templateFileName) {
      continue;
    }
    final rawCode = fileName.substring(0, fileName.length - '.toml'.length);
    final normalized = rawCode.toLowerCase().replaceAll('_', '-');
    if (_isValidLocaleCode(normalized)) {
      localeCodes.add(normalized);
    }
  }

  final sorted = localeCodes.toList()..sort();
  return sorted;
}

class LocaleRegistry {
  static final Set<String> _localeCodes = <String>{};
  static bool _initialized = false;

  static void primeWithDefaults({
    Iterable<String> localeCodes = const ['en', 'ko'],
  }) {
    if (_localeCodes.isNotEmpty) {
      return;
    }
    _localeCodes.addAll(
      localeCodes
          .map((code) => code.toLowerCase().replaceAll('_', '-'))
          .where(_isValidLocaleCode),
    );
    if (_localeCodes.isEmpty) {
      _localeCodes.add(_safeFallbackLocaleCode);
    }
  }

  static Future<void> initialize({AssetBundle? assetBundle}) async {
    if (_initialized) {
      return;
    }
    final bundle = assetBundle ?? rootBundle;
    try {
      final manifest = await AssetManifest.loadFromAssetBundle(bundle);
      final extracted = extractSupportedLocaleCodesFromAssets(
        manifest.listAssets(),
      );
      _localeCodes.addAll(extracted);
    } catch (_) {
      // manifest 로딩 실패 시 안전 fallback으로 계속 진행합니다.
    }

    if (_localeCodes.isEmpty) {
      _localeCodes.add(_safeFallbackLocaleCode);
    }
    _initialized = true;
  }

  static List<String> get supportedLocaleCodes {
    final sorted = _localeCodes.toList()..sort();
    return List.unmodifiable(sorted);
  }

  static String get fallbackLocaleCode {
    final supported = supportedLocaleCodes;
    if (supported.isEmpty) {
      return _safeFallbackLocaleCode;
    }
    if (supported.contains('en')) {
      return 'en';
    }
    return supported.first;
  }

  static bool contains(String code) {
    return _localeCodes.contains(code.toLowerCase());
  }

  @visibleForTesting
  static void setSupportedLocaleCodesForTest(Iterable<String> localeCodes) {
    _localeCodes
      ..clear()
      ..addAll(
        localeCodes
            .map((code) => code.toLowerCase().replaceAll('_', '-'))
            .where(_isValidLocaleCode),
      );
    if (_localeCodes.isEmpty) {
      _localeCodes.add(_safeFallbackLocaleCode);
    }
    _initialized = true;
  }

  @visibleForTesting
  static void resetForTest() {
    _localeCodes.clear();
    _initialized = false;
  }
}

bool _isValidLocaleCode(String value) {
  return RegExp(r'^[a-z]{2,3}$').hasMatch(value);
}
