import 'dart:io';

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

/// 从原生宿主 App（Android/iOS）获取 ERP 连接配置。
///
/// 对应 Android 端 [HeaderInterceptor] + [WebApiUrl] 的值来源：
/// - baseUrl: Pub_CompInfo.getWebApiUrl()
/// - sn: SharedPreferences "MemberNo"
/// - loginId: SharedPreferences "LoginId"
///
/// 首次安装 / 清数据后，原生端登录功能尚未完成，此时 getConfig
/// 返回的字段可能为空，因此不标记 initialized，允许后续重试。
class HostAppChannel {
  static const _channel = MethodChannel('com.tboss.oa/config');
  static const _fileChannel = MethodChannel('com.tboss.oa/file');

  static String? _baseUrl;
  static String? _sn;
  static String? _loginId;
  static String? _compNo;
  static String? _dep;
  static String? _depName;
  static String? _usr;
  static String? _usrName;
  static int? _poiAmt;

  static String get baseUrl => _baseUrl ?? '';
  static String get sn => _sn ?? '';
  static String get loginId => _loginId ?? '';
  static String get compNo => _compNo ?? '';
  static String get dep => _dep ?? '';
  static String get depName => _depName ?? '';
  static String get usr => _usr ?? '';
  static String get usrName => _usrName ?? '';
  static int get poiAmt => _poiAmt ?? 2;

  static bool _initialized = false;
  static bool get isInitialized => _initialized;

  /// 从宿主 App 加载配置，需在 runApp 之前调用。
  static Future<void> initialize() async {
    if (_initialized) return;
    // 监听原生端主动下发的刷新通知（登录完成后触发）
    _channel.setMethodCallHandler((call) async {
      if (call.method == 'onLoginComplete') {
        await refresh();
      }
    });
    await _tryInit();
  }

  /// 重试获取配置（原生端可能尚未就绪，失败不抛异常）
  static Future<void> _tryInit() async {
    try {
      final result = await _channel.invokeMethod<Map<dynamic, dynamic>>('getConfig');
      if (result != null) {
        _baseUrl = result['baseUrl'] as String?;
        _sn = result['sn'] as String?;
        _loginId = result['loginId'] as String?;
        _compNo = result['compNo'] as String?;
        _dep = result['dep'] as String?;
        _depName = result['depName'] as String?;
        _usr = result['usr'] as String?;
        _usrName = result['usrName'] as String?;
        _poiAmt = result['poiAmt'] as int?;
      }
    } catch (_) {
      // 原生端 MethodChannel handler 尚未注册，稍后重试
    }
    // 只有 baseUrl 有效时才认为初始化成功
    _initialized = (_baseUrl != null && _baseUrl!.isNotEmpty);
  }

  /// 页面打开时调，确保配置已就绪；未就绪则重新拉取。
  static Future<void> ensureConfig() async {
    if (_initialized) return;
    await _tryInit();
  }

  /// 保存文件到手机公共 Downloads 目录（Android 通过 MediaStore，iOS 写应用文档）。
  /// 返回保存后的文件 URI（Android）或文件路径（iOS），失败返回 null。
  static Future<String?> saveFileToDownloads(
    Uint8List bytes,
    String fileName,
    String mimeType,
  ) async {
    if (Platform.isAndroid) {
      try {
        final uri = await _fileChannel.invokeMethod<String>(
          'saveToDownloads',
          {
            'bytes': bytes,
            'fileName': fileName,
            'mimeType': mimeType,
          },
        );
        return uri;
      } catch (_) {
        return null;
      }
    } else {
      // iOS: 写应用文档目录，用户在「文件」App 中查看
      try {
        final dir = await getApplicationDocumentsDirectory();
        final file = File('${dir.path}/$fileName');
        await file.writeAsBytes(bytes);
        return file.path;
      } catch (_) {
        return null;
      }
    }
  }

  /// 跳转原生审核过程页面
  static Future<void> showAuditTrail(String billId, String billNo, {int bilItm = 0}) async {
    try {
      await _channel.invokeMethod('showShState', {
        'billId': billId,
        'billNo': billNo,
        'bilItm': bilItm,
      });
    } catch (_) {
      // 原生端未实现时静默忽略
    }
  }

  /// 重新从宿主 App 拉取配置（用于用户切换 / 登录完成后刷新）。
  static Future<void> refresh() async {
    try {
      final result = await _channel.invokeMethod<Map<dynamic, dynamic>>('getConfig');
      if (result != null) {
        _baseUrl = result['baseUrl'] as String? ?? _baseUrl;
        _sn = result['sn'] as String? ?? _sn;
        _loginId = result['loginId'] as String? ?? _loginId;
        _compNo = result['compNo'] as String? ?? _compNo;
        _dep = result['dep'] as String? ?? _dep;
        _depName = result['depName'] as String? ?? _depName;
        _usr = result['usr'] as String? ?? _usr;
        _usrName = result['usrName'] as String? ?? _usrName;
        _poiAmt = result['poiAmt'] as int? ?? _poiAmt;
        _initialized = (_baseUrl != null && _baseUrl!.isNotEmpty);
      }
    } catch (_) {
      // 刷新失败保留旧值
    }
  }
}
