import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart';
import 'package:video_compress/video_compress.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:path/path.dart' as p;
import 'ItemWidgetFactory.dart';

/// 媒体选择类型
enum MediaType { image, video }

/// 纵向滚动四列的媒体添加组件，支持拍摄、全屏相册多选，以及初始地址列表展示
/// 新增 isEdit 属性控制编辑状态
class MediaPickerRow extends StatefulWidget {
  final int maxCount;
  final MediaType mediaType;
  final List<String>? initialMediaPaths;
  final ValueChanged<List<File>> onChanged;
  final ValueChanged<String>? onMediaAdded;
  final ValueChanged<String>? onMediaRemoved;
  final ValueChanged<String>? onMediaTapped; // 新增：媒体点击回调
  final bool isEdit; // 新增：控制编辑状态
  final bool isCamera; // 新增：只能拍照

  const MediaPickerRow({
    Key? key,
    this.maxCount = 4,
    this.mediaType = MediaType.image,
    this.initialMediaPaths,
    required this.onChanged,
    this.onMediaAdded,
    this.onMediaRemoved,
    this.onMediaTapped, // 新增
    this.isEdit = true, // 默认可编辑
    this.isCamera = false,
  }) : super(key: key);

  @override
  _MediaPickerGridState createState() => _MediaPickerGridState();
}

class _MediaPickerGridState extends State<MediaPickerRow> {
  final ImagePicker _picker = ImagePicker();
  late List<String> _mediaPaths;
  bool _isProcessing = false; // 转码或处理时显示 loading

  @override
  void initState() {
    super.initState();
    _mediaPaths =
        widget.initialMediaPaths != null
            ? widget.initialMediaPaths!.take(widget.maxCount).toList()
            : [];
    WidgetsBinding.instance.addPostFrameCallback((_) {
      widget.onChanged(
        _mediaPaths
            .map((p) => p.startsWith('http') ? File('') : File(p))
            .toList(),
      );
    });
  }

  // 公共：当得到本地媒体路径时（可能是 mov/avi 等），需要在这里统一处理（转码、入队、回调）
  Future<void> _handlePickedPath(String path) async {
    if (!mounted) return;
    if (path.isEmpty) return;

    try {
      String finalPath = path;

      // 如果是视频并且不是 mp4，则调用 video_compress 转码
      if (widget.mediaType == MediaType.video) {
        final ext = p.extension(path).toLowerCase();
        if (ext != '.mp4') {
          setState(() => _isProcessing = true);
          try {
            final info = await VideoCompress.compressVideo(
              path,
              quality: VideoQuality.MediumQuality,
              deleteOrigin: false,
            );
            if (info != null && info.file != null) {
              finalPath = info.file!.path;
              debugPrint('✅ 转换完成: $path -> $finalPath');
            } else {
              throw Exception("转码失败: 返回空文件");
            }
          } catch (e) {
            debugPrint('❌ 视频转码失败: $e');
            if (mounted) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(content: Text('视频转码失败: ${e.toString()}')),
              );
            }
            return;
          } finally {
            if (mounted) setState(() => _isProcessing = false);
          }
        }
      }

      // 添加到列表
      if (_mediaPaths.length < widget.maxCount) {
        setState(() => _mediaPaths.add(finalPath));
        widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
        widget.onMediaAdded?.call(finalPath);
      }
    } catch (e) {
      debugPrint('处理选中媒体失败: $e');
    }
  }

  Future<void> _showPickerOptions() async {
    if (!widget.isEdit) return; // 不可编辑时直接返回

    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      builder:
          (_) => SafeArea(
            child: Wrap(
              children: [
                ListTile(
                  titleAlignment: ListTileTitleAlignment.center,
                  leading: Icon(
                    widget.mediaType == MediaType.image
                        ? Icons.camera_alt
                        : Icons.videocam,
                  ),
                  title: Text(
                    widget.mediaType == MediaType.image ? '拍照' : '拍摄视频',
                  ),
                  onTap: () {
                    Navigator.of(context).pop();
                    _pickCamera();
                  },
                ),
                ListTile(
                  titleAlignment: ListTileTitleAlignment.center,
                  leading: Icon(
                    widget.mediaType == MediaType.image
                        ? Icons.photo_library
                        : Icons.video_library,
                  ),
                  title: Text(
                    widget.mediaType == MediaType.image ? '从相册选择' : '从相册选择视频',
                  ),
                  onTap: () {
                    Navigator.of(context).pop();
                    _pickGallery();
                  },
                ),
                ListTile(
                  titleAlignment: ListTileTitleAlignment.center,
                  leading: const Icon(Icons.close),
                  title: const Text('取消'),
                  onTap: () => Navigator.of(context).pop(),
                ),
              ],
            ),
          ),
    );
  }

  Future<void> _pickCamera() async {
    if (!widget.isEdit || _mediaPaths.length >= widget.maxCount) return;

    try {
      XFile? picked;
      if (widget.mediaType == MediaType.image) {
        picked = await _picker.pickImage(source: ImageSource.camera);
        if (picked != null) {
          final path = picked.path;
          setState(() => _mediaPaths.add(path));
          widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
          widget.onMediaAdded?.call(path);
        }
      } else {
        picked = await _picker.pickVideo(source: ImageSource.camera);
        if (picked != null) {
          await _handlePickedPath(picked.path);
        }
      }
    } catch (e) {
      debugPrint('拍摄失败: $e');
    }
  }

  // 修改 _pickGallery 方法
  Future<void> _pickGallery() async {
    if (!widget.isEdit || _mediaPaths.length >= widget.maxCount) return;

    try {
      // iOS: 使用 PhotoManager.requestPermissionExtend() 唤起系统权限弹窗（支持 limited）
      if (Platform.isIOS) {
        final permission = await PhotoManager.requestPermissionExtend();
        debugPrint('iOS photo permission state: $permission');

        if (permission != PermissionState.authorized &&
            permission != PermissionState.limited) {
          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('请到设置中开启相册访问权限')),
            );
          }
          return;
        }

        // 授权或 limited：继续打开 AssetPicker
        final remaining = widget.maxCount - _mediaPaths.length;
        final List<AssetEntity>? assets = await AssetPicker.pickAssets(
          context,
          pickerConfig: AssetPickerConfig(
            requestType:
            widget.mediaType == MediaType.image ? RequestType.image : RequestType.video,
            maxAssets: remaining,
            gridCount: 4,
          ),
        );

        if (assets != null) {
          for (final asset in assets) {
            if (_mediaPaths.length >= widget.maxCount) break;
            try {
              final file = await asset.file;
              if (file != null) {
                final path = file.path;
                await _handlePickedPath(path);
              } else {
                debugPrint('资产获取 file 为空，asset id: ${asset.id}');
              }
            } catch (e) {
              debugPrint('读取 asset 文件失败: $e');
            }
          }
          if (mounted) setState(() {});
          widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
        }

      } else {
        // Android: 使用 permission_handler 请求存储权限（简单处理）
        final PermissionStatus current = await Permission.storage.status;
        PermissionStatus status;
        if (current.isGranted) {
          status = PermissionStatus.granted;
        } else {
          status = await Permission.storage.request();
        }

        debugPrint('Android storage permission: $status');

        if (status == PermissionStatus.granted) {
          final remaining = widget.maxCount - _mediaPaths.length;
          final List<AssetEntity>? assets = await AssetPicker.pickAssets(
            context,
            pickerConfig: AssetPickerConfig(
              requestType:
              widget.mediaType == MediaType.image ? RequestType.image : RequestType.video,
              maxAssets: remaining,
              gridCount: 4,
            ),
          );

          if (assets != null) {
            for (final asset in assets) {
              if (_mediaPaths.length >= widget.maxCount) break;
              try {
                final file = await asset.file;
                if (file != null) {
                  final path = file.path;
                  await _handlePickedPath(path);
                } else {
                  debugPrint('资产获取 file 为空，asset id: ${asset.id}');
                }
              } catch (e) {
                debugPrint('读取 asset 文件失败: $e');
              }
            }
            if (mounted) setState(() {});
            widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
          }
        } else if (status == PermissionStatus.permanentlyDenied) {
          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('请到设置中开启相册访问权限')),
            );
          }
          await openAppSettings();
        } else {
          if (mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('相册访问权限被拒绝')),
            );
          }
        }
      }
    } catch (e, st) {
      debugPrint('相册选择失败: $e\n$st');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('相册选择失败')),
        );
      }
    }
  }

  // 修改拍照方法，使用 permission_handler 请求相机权限
  Future<void> _cameraAction() async {
    if (!widget.isEdit || _mediaPaths.length >= widget.maxCount) return;

    // 请求相机权限
    final PermissionStatus status = await Permission.camera.request();

    if (status != PermissionStatus.granted) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('相机权限被拒绝')));
      }
      return;
    }

    try {
      if (widget.mediaType == MediaType.image) {
        XFile? picked = await _picker.pickImage(source: ImageSource.camera);
        if (picked != null) {
          final path = picked.path;
          setState(() => _mediaPaths.add(path));
          widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
          widget.onMediaAdded?.call(path);
        }
      } else {
        // video from camera
        XFile? picked = await _picker.pickVideo(source: ImageSource.camera);
        if (picked != null) {
          await _handlePickedPath(picked.path);
        }
      }
    } catch (e) {
      debugPrint('拍摄失败: $e');
      // 友好提示
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('拍摄失败，请检查相机权限或设备状态')));
      }
    }
  }

  void _removeMedia(int index) async {
    final ok = await CustomAlertDialog.showConfirm(
      context,
      title: '温馨提示',
      content:
          widget.mediaType == MediaType.image ? '确定要删除这张图片吗？' : '确定要删除这个视频吗?',
      cancelText: '取消',
    );
    if (ok) {
      final removed = _mediaPaths[index];
      setState(() => _mediaPaths.removeAt(index));
      widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
      widget.onMediaRemoved?.call(removed);
    }
  }

  @override
  Widget build(BuildContext context) {
    final showAddButton = widget.isEdit && _mediaPaths.length < widget.maxCount;
    final itemCount = _mediaPaths.length + (showAddButton ? 1 : 0);

    return Stack(
      children: [
        GridView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
            crossAxisSpacing: 8,
            mainAxisSpacing: 8,
            childAspectRatio: 1,
          ),
          itemCount: itemCount,
          itemBuilder: (context, index) {
            // 显示媒体项
            if (index < _mediaPaths.length) {
              final path = _mediaPaths[index];
              final isNetwork = path.startsWith('http');

              return GestureDetector(
                onTap: () => widget.onMediaTapped?.call(path),
                child: Stack(
                  children: [
                    ClipRRect(
                      borderRadius: BorderRadius.circular(5),
                      child: SizedBox.expand(
                        // 让内容强制填满格子
                        child:
                            widget.mediaType == MediaType.image
                                ? (isNetwork
                                    ? Image.network(
                                      path,
                                      fit: BoxFit.cover, // 铺满格子并裁剪
                                    )
                                    : Image.file(
                                      File(path),
                                      fit: BoxFit.cover, // 铺满格子并裁剪
                                    ))
                                : Container(
                                  color: Colors.black12,
                                  child: const Center(
                                    child: Icon(
                                      Icons.videocam,
                                      color: Colors.white70,
                                    ),
                                  ),
                                ),
                      ),
                    ),

                    // 只在可编辑状态下显示删除按钮
                    if (widget.isEdit)
                      Positioned(
                        top: -15,
                        right: -15,
                        child: IconButton(
                          icon: const Icon(
                            Icons.cancel,
                            size: 20,
                            color: Colors.red,
                          ),
                          onPressed: () => _removeMedia(index),
                        ),
                      ),
                  ],
                ),
              );
            }
            // 显示添加按钮
            else if (showAddButton) {
              return GestureDetector(
                onTap: widget.isCamera ? _cameraAction : _showPickerOptions,
                child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(color: Colors.black12),
                    borderRadius: BorderRadius.circular(5),
                  ),
                  child: const Center(
                    child: Icon(Icons.camera_alt, color: Colors.black26),
                  ),
                ),
              );
            } else {
              return const SizedBox.shrink();
            }
          },
        ),

        // 转码/处理 loading 遮罩
        if (_isProcessing)
          Positioned.fill(
            child: Container(
              color: Colors.transparent,
              child: const Center(child: CircularProgressIndicator()),
            ),
          ),
      ],
    );
  }
}

/// 照片上传区域组件，使用纵向四列Grid展示
/// 新增 isEdit 属性控制编辑状态
class RepairedPhotoSection extends StatefulWidget {
  final int maxCount;
  final MediaType mediaType;
  final String title;
  final List<String>? initialMediaPaths;
  final ValueChanged<List<File>> onChanged;
  final ValueChanged<String>? onMediaAdded;
  final ValueChanged<String>? onMediaRemoved;
  final ValueChanged<String>? onMediaTapped; // 新增：媒体点击回调
  final VoidCallback onAiIdentify;
  final bool isShowAI;
  final double horizontalPadding;
  final bool isRequired;
  final bool isShowNum;
  final bool isEdit; // 新增：控制编辑状态
  final bool isCamera; // 新增：只能拍照

  const RepairedPhotoSection({
    Key? key,
    this.maxCount = 4,
    this.mediaType = MediaType.image,
    required this.title,
    this.initialMediaPaths,
    this.isShowAI = false,
    required this.onChanged,
    required this.onAiIdentify,
    this.horizontalPadding = 5,
    this.onMediaAdded,
    this.onMediaRemoved,
    this.onMediaTapped, // 新增
    this.isRequired = false,
    this.isShowNum = true,
    this.isEdit = true, // 默认可编辑
    this.isCamera = false,
  }) : super(key: key);

  @override
  _RepairedPhotoSectionState createState() => _RepairedPhotoSectionState();
}

class _RepairedPhotoSectionState extends State<RepairedPhotoSection> {
  late List<String> _mediaPaths;

  @override
  void initState() {
    super.initState();
    _mediaPaths =
        widget.initialMediaPaths?.take(widget.maxCount).toList() ?? [];
    WidgetsBinding.instance.addPostFrameCallback((_) {
      widget.onChanged(_mediaPaths.map((p) => File(p)).toList());
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      padding: const EdgeInsets.only(left: 0, right: 10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: EdgeInsets.symmetric(horizontal: widget.horizontalPadding),
            child: ListItemFactory.createRowSpaceBetweenItem(
              leftText: widget.title,
              rightText:
                  widget.isShowNum
                      ? '${_mediaPaths.length}/${widget.maxCount}'
                      : '',
              isRequired: widget.isRequired,
            ),
          ),
          const SizedBox(height: 8),
          Padding(
            padding: EdgeInsets.symmetric(horizontal: widget.horizontalPadding),
            child: MediaPickerRow(
              maxCount: widget.maxCount,
              mediaType: widget.mediaType,
              initialMediaPaths: _mediaPaths,
              isCamera: widget.isCamera,
              onChanged: (files) {
                final newPaths = files.map((f) => f.path).toList();
                setState(() {
                  _mediaPaths = newPaths;
                });
                widget.onChanged(files);
              },
              onMediaAdded: widget.onMediaAdded,
              onMediaRemoved: widget.onMediaRemoved,
              onMediaTapped: widget.onMediaTapped,
              // 传递点击回调
              isEdit: widget.isEdit, // 传递编辑状态
            ),
          ),
          const SizedBox(height: 8),
          if (widget.isShowAI && widget.isEdit) // 只在可编辑状态下显示AI按钮
            Padding(
              padding: EdgeInsets.symmetric(
                horizontal: widget.horizontalPadding,
              ),
              child: GestureDetector(
                onTap: widget.onAiIdentify,
                child: Container(
                  padding: const EdgeInsets.symmetric(horizontal: 15),
                  height: 36,
                  decoration: BoxDecoration(
                    color: const Color(0xFFDFEAFF),
                    borderRadius: BorderRadius.circular(18),
                  ),
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Image.asset('assets/images/ai_img.png', width: 20),
                      const SizedBox(width: 5),
                      const Text('AI隐患识别与处理'),
                    ],
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }
}
