import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart'; // 引入 Flutter 核心包
import 'package:http/http.dart' as http;
import 'package:puzzleweave/models/api_helper.dart';
import 'package:puzzleweave/utils/utils.dart';
import 'package:logging/logging.dart';

final Logger _log = Logger('cached_request.dart');

typedef TransformFunction = Future<dynamic> Function(dynamic json);

// 混入 WidgetsBindingObserver 以监听应用生命周期
class CachedRequest with WidgetsBindingObserver {
  // !!! 新增属性 1: 标记最近一次请求是否通过网络成功完成
  bool _hasRecentSuccessfulFetch = false;
  bool get hasRecentSuccessfulFetch => _hasRecentSuccessfulFetch;

  static final Map<String, CachedRequest> _cache = {};

  final String url;
  TransformFunction? transformFunction;
  // 仅使用 .broadcast()，但 onListen 只会触发一次
  final StreamController _streamController = StreamController.broadcast();

  dynamic _transformed;
  // --- 【新增】Getter：允许外部同步访问最新的缓存数据 ---
  dynamic get cachedData => _transformed;

  CachedRequest._internal(this.url, this.transformFunction) {
    _log.info('New cached request: $url');
    // 注册生命周期监听器
    WidgetsBinding.instance.addObserver(this);
    _init();
  }

  factory CachedRequest.fromUrl(String url, {TransformFunction? transformFunction}) {
    // 确保单例模式下，只注册一次监听器
    if (!_cache.containsKey(url)) {
      _cache[url] = CachedRequest._internal(url, transformFunction);
    }
    return _cache[url]!;
  }

  // --- 关键修改：生命周期监听 ---
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _log.info('App Resumed from background. Forcing refresh for $url');
      // 应用程序从后台恢复到前台时，强制刷新数据
      refresh();
    }
  }

  // 由于 CachedRequest 是一个单例，它不会被销毁，除非应用完全关闭。
  // 但是，为了严谨性，如果添加了 Dispose 逻辑，应记得移除 Observer。
  // 注意：在 Flutter Provider 或 InheritedWidget 依赖的单例中，通常不需要手动调用 dispose。
  // 如果需要清理：
  /*
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _streamController.close();
    // ... clean up
  }
  */
  // ---------------------------------

  _init() {
    // FIX: 首次初始化时，立即尝试加载缓存（如果有）
    _cacheLoad();
    _remoteLoad();
    // _streamController.onListen = () {
    //   if (_transformed != null) {
    //     // 如果有缓存数据，立即发送给新的监听者
    //     _streamController.add(_transformed);
    //   }
    // };

    _streamController.onListen = () {
      _log.info('Stream listener added for $url. Current data available? ${_transformed != null}');
      if (_transformed != null) {
        // 确保新订阅者立即获得缓存数据 (用于热重载或首次进入)
        // 使用 Future.microtask 确保在 onListen 结束后再触发 add，避免同步递归
        Future.microtask(() => _streamController.add(_transformed));
      }
    };
  }

  Future<void> refresh() async {
    await _remoteLoad();
  }

  Future<void> reload() async {
    await _cacheLoad();
  }

  _remoteLoad() async {
    try {
      final response = await http.get(Uri.parse(url));
      if (response.statusCode != 200) {
        // 如果状态码失败，则标记为失败，并抛出异常
        _hasRecentSuccessfulFetch = false; // !!! 关键：网络失败
        throw Exception('Invalid status code: ${response.statusCode} when fetching: $url');
      }

      // !!! 关键：网络请求成功，标记为成功
      _hasRecentSuccessfulFetch = true;
      _log.info('${response.statusCode}, $url, Network Success: true');

      final data = jsonDecode(response.body);
      _emit(data);

      await saveString(cachePath, response.body);
    } catch (error) {
      _streamController.addError(error);
      _log.severe('Remote load failed for $url: $error');
      // 即使在 catch 块中，也再次确认标记为失败（以防万一）
      _hasRecentSuccessfulFetch = false;
    }
  }

  _emit(dynamic data) async {
    _log.info('Emiting data..... ');
    try {
      if (transformFunction != null) {
        data = await transformFunction?.call(data);
      }

      // 仅当有监听者时才尝试添加数据
      if (_streamController.hasListener) {
        _streamController.add(data);
      }
      _transformed = data;
    } catch (error) {
      _streamController.addError(error);
      _log.severe('Data transformation or emission failed: $error');
    }
  }

  _cacheLoad() async {
    try {
      final file = await localFile(cachePath);
      if (await file.exists()) {
        _log.info('File $file exists, try loading from cache..');
        final data = await loadJson(cachePath);
        _emit(data);
      } else {
        if (url == ApiHelper.latestUri) {
          _log.info('Loading builtin latest asset data...');
          final data = await loadJSONFromAsset('assets/builtin/latest.json');
          _emit(data);
        }
        if (url == ApiHelper.collectionUri) {
          _log.info('Loading builtin collection asset data...');
          final data = await loadJSONFromAsset('assets/builtin/collection.json');
          _emit(data);
        }
      }
    } catch (error) {
      // 缓存加载失败不应该阻止远程加载
      _streamController.addError(error);
    }
  }

  String get hash => md5Hash(url);
  String get cachePath => 'api_cache/$hash';
  Stream get stream => _streamController.stream;

  @override
  String toString() {
    return 'CachedRequest(url=$url)';
  }
}
