import 'dart:io';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:crypto/crypto.dart';
import 'package:path/path.dart' as p;

/// 一个支持自动 Dio 缓存的 Image 组件
/// 用法完全对齐 Image.network(url)
class CacheImage extends StatefulWidget {
  final String url;
  final double? width;
  final double? height;
  final BoxFit? fit;
  final double scale;
  final AlignmentGeometry alignment;
  final ImageRepeat repeat;
  final FilterQuality filterQuality;
  final Color? color;
  final BlendMode? colorBlendMode;
  final ImageLoadingBuilder? loadingBuilder;
  final ImageErrorWidgetBuilder? errorBuilder;
  final bool matchTextDirection;

  // 使用位置参数接收 url，其余为可选命名参数
  const CacheImage.network(
      this.url, {
        Key? key,
        this.width,
        this.height,
        this.fit,
        this.scale = 1.0,
        this.alignment = Alignment.center,
        this.repeat = ImageRepeat.noRepeat,
        this.filterQuality = FilterQuality.low,
        this.color,
        this.colorBlendMode,
        this.loadingBuilder,
        this.errorBuilder,
        this.matchTextDirection = false,
      }) : super(key: key);

  @override
  State<CacheImage> createState() => _CacheImageState();
}

class _CacheImageState extends State<CacheImage> {
  File? _localFile;
  bool _isInit = false;

  /// 统一日志工具（支持发布/调试环境）
  void _log(String message, {bool isError = false}) {
    // 发布环境只打印错误日志，调试环境全部打印
    if (kReleaseMode) {
      if (isError) {
        print('[CacheImage-ERROR] $message');
      }
    } else {
      final tag = isError ? '[CacheImage-ERROR]' : '[CacheImage-INFO]';
      print('$tag $message');
    }
  }

  @override
  void initState() {
    super.initState();
    _log('图片组件初始化，URL: ${widget.url}');
    _handleCache();
  }

  // 当外部传入的 url 发生变化时，重新触发缓存逻辑
  @override
  void didUpdateWidget(CacheImage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.url != widget.url) {
      _log('URL 发生变化，重新加载缓存\n旧URL: ${oldWidget.url}\n新URL: ${widget.url}');
      _handleCache();
    }
  }

  Future<void> _handleCache() async {
    try {
      _log('开始处理图片缓存逻辑，URL: ${widget.url}');

      // 1. 生成唯一文件名 (MD5)
      final String fileName = md5.convert(utf8.encode(widget.url)).toString();
      _log('生成文件MD5: $fileName');

      // 获取临时目录 (建议缓存放在临时目录，由系统根据空间决定是否清理)
      final Directory cacheDir = await getTemporaryDirectory();
      final File file = File(p.join(cacheDir.path, 'image_cache', fileName));
      _log('本地缓存路径: ${file.path}');

      // 2. 检查本地是否存在
      if (await file.exists()) {
        _log('✅ 本地缓存已存在，直接加载本地文件');
        if (mounted) {
          setState(() {
            _localFile = file;
            _isInit = true;
          });
        }
        return;
      }

      // 3. 本地不存在，使用 Dio 下载
      _log('ℹ️ 本地无缓存，开始从网络下载图片');
      final dio = Dio();
      final response = await dio.get(
        widget.url,
        options: Options(responseType: ResponseType.bytes),
      );
      _log('✅ 图片下载完成，数据大小: ${response.data.length} bytes');

      // 4. 尝试保存到本地 (Quiet Mode: 失败仅打印，不抛出异常)
      try {
        await file.parent.create(recursive: true);
        await file.writeAsBytes(response.data);
        _log('✅ 图片成功保存到本地缓存');
        if (mounted) {
          setState(() {
            _localFile = file;
          });
        }
      } catch (e) {
        _log('❌ 本地保存失败 (不影响显示): $e', isError: true);
      }
    } catch (e) {
      _log('❌ 下载或逻辑处理失败: $e', isError: true);
    } finally {
      if (mounted) {
        setState(() => _isInit = true);
      }
      _log('🏁 图片缓存逻辑执行完成');
    }
  }

  @override
  Widget build(BuildContext context) {
    // 如果本地文件已就绪，直接加载本地文件
    if (_localFile != null) {
      _log('使用本地缓存图片渲染');
      return Image.file(
        _localFile!,
        key: widget.key,
        width: widget.width,
        height: widget.height,
        fit: widget.fit,
        alignment: widget.alignment,
        repeat: widget.repeat,
        filterQuality: widget.filterQuality,
        color: widget.color,
        colorBlendMode: widget.colorBlendMode,
        matchTextDirection: widget.matchTextDirection,
        // 如果文件读取过程中出错，尝试回退到网络或报错组件
        errorBuilder: widget.errorBuilder ?? (context, error, stack) {
          _log('❌ 本地图片加载失败，回退到网络加载', isError: true);
          return _buildNetworkImage();
        },
      );
    }

    // 默认或下载中，渲染网络图片
    _log('使用网络图片渲染（加载中/无缓存）');
    return _buildNetworkImage();
  }

  Widget _buildNetworkImage() {
    return Image.network(
      widget.url,
      key: widget.key,
      width: widget.width,
      height: widget.height,
      fit: widget.fit,
      scale: widget.scale,
      alignment: widget.alignment,
      repeat: widget.repeat,
      filterQuality: widget.filterQuality,
      color: widget.color,
      colorBlendMode: widget.colorBlendMode,
      matchTextDirection: widget.matchTextDirection,
      loadingBuilder: widget.loadingBuilder,
      errorBuilder: (context, error, stack) {
        _log('❌ 网络图片加载失败: $error', isError: true);
        if (widget.errorBuilder != null) {
          return widget.errorBuilder!(context, error, stack);
        }
        return const SizedBox();
      },
    );
  }
}