import 'dart:convert';
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart' show rootBundle, MethodChannel;

class AppConfig {
  final String flavor;
  final String baseUrl;
  final String t3Token;
  final bool enableLogging;

  AppConfig({
    required this.flavor,
    required this.baseUrl,
    required this.t3Token,
    required this.enableLogging,
  });

  factory AppConfig.fromMap(Map<String, dynamic> map) {
    final flavor = (map['flavor'] as String?)?.trim();
    final baseUrl = (map['baseUrl'] as String?)?.trim();
    final token   = (map['t3Token'] as String?)?.trim();
    final enable  = map['enableLogging'];

    if ((flavor ?? '').isEmpty) throw const FormatException("env thiếu 'flavor'");
    if ((baseUrl ?? '').isEmpty) throw const FormatException("env thiếu 'baseUrl'");
    // if ((token ?? '').isEmpty)   throw const FormatException("env thiếu 'libToken'");
    if (kDebugMode) {
      print('AppConfig: flavor=$flavor, baseUrl=$baseUrl, t3Token=${token ?? ''}, enableLogging=$enable');
    }
    return AppConfig(
      flavor: flavor!,
      baseUrl: baseUrl!,
      t3Token: token ?? '',
      enableLogging: enable is bool ? enable : true,
    );
  }

  static late AppConfig current;
}

Future<void> loadEnv() async {
  Map<String, dynamic>? cfg;
  if (kIsWeb) {
    // Web platform: single source of truth. Scripts prepare env.json.
    cfg = await _tryLoadAsset('assets/config/env.json');
  } else if (Platform.isIOS) {
    cfg = await _tryLoadAsset('assets/config/env.json');
    cfg ??= await _tryLoadFromMethodChannel();
  } else if (Platform.isAndroid) {
    cfg = await _tryLoadFromMethodChannel();
    cfg ??= await _tryLoadAsset('assets/config/env.json');
  } else {
    cfg = await _tryLoadAsset('assets/config/env.json');
  }
  if (cfg == null) {
    throw Exception('Không tải được cấu hình môi trường (env).');
  }
  AppConfig.current = AppConfig.fromMap(cfg);
  if (kDebugMode) {
    print('✅ AppConfig loaded: flavor=${AppConfig.current.flavor}, baseUrl=${AppConfig.current.baseUrl}');
  }
}

Future<Map<String, dynamic>?> _tryLoadAsset(String path) async {
  try {
    final s = await rootBundle.loadString(path);
    return jsonDecode(s) as Map<String, dynamic>;
  } catch (_) {
    return null;
  }
}

Future<Map<String, dynamic>?> _tryLoadFromMethodChannel() async {
  try {
    const channel = MethodChannel('com.icom.mypoint/config');
    final dynamic result = await channel.invokeMethod('getConfig');
    if (result is String) {
      final json = jsonDecode(result) as Map<String, dynamic>;
      return json;
    } else if (result is Map) {
      final map = Map<String, dynamic>.from(result as Map);
      return map;
    }
  } catch (_) {}
  return null;
}