import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:loopin/IM/controller/im_user_info_controller.dart';
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/api/common_api.dart';
import 'package:loopin/api/video_api.dart';
import 'package:loopin/components/image_viewer.dart';
import 'package:loopin/components/preview_video.dart';
import 'package:loopin/service/http.dart';
import 'package:loopin/utils/index.dart';
import 'package:loopin/utils/permissions.dart';
import 'package:loopin/utils/snapshot.dart';
import 'package:shirne_dialog/shirne_dialog.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';

class UploadVideoPage extends StatefulWidget {
  final bool visible;
  const UploadVideoPage({super.key, required this.visible});

  @override
  State<UploadVideoPage> createState() => _UploadVideoPageState();
}

class _UploadVideoPageState extends State<UploadVideoPage> {
  final selectedVideo = Rxn<AssetEntity>();
  final selectedCover = Rxn<AssetEntity>();
  //视频
  final uploading = false.obs;
  final uploadProgress = 0.0.obs;
  final status = ''.obs;
  //图片
  final uploading2 = false.obs;
  final uploadProgress2 = 0.0.obs;
  final status2 = ''.obs;
  //地址
  final uploadedVideoUrl = ''.obs; // 网络视频地址
  final uploadedImgUrl = ''.obs; // 网络图片地址
  final videoPath = ''.obs; // 本地视频地址
  final imgPath = ''.obs; //本地图片地址
  final snapshot = ''.obs;
  // 文件id
  final fileId = ''.obs;

  late final FocusNode descFocusNode;

  late TextEditingController descriptionController;

  @override
  void initState() {
    super.initState();
    descFocusNode = FocusNode();
    descriptionController = TextEditingController();
  }

  Future<void> pickVideo() async {
    descFocusNode.unfocus();
    final hasPer = await Permissions.requestVideoPermission();
    logger.e(hasPer);
    if (!hasPer) {
      Permissions.showPermissionDialog('相册');
      return;
    }

    if (!mounted) return;

    final pickedAssets = await AssetPicker.pickAssets(
      context,
      pickerConfig: AssetPickerConfig(
        textDelegate: const AssetPickerTextDelegate(),
        pathNameBuilder: (AssetPathEntity album) {
          return Utils.translateAlbumName(album);
        },
        maxAssets: 1,
        requestType: RequestType.video,
        filterOptions: FilterOptionGroup(
          videoOption: const FilterOption(
            durationConstraint: DurationConstraint(
              max: Duration(minutes: 30),
            ),
          ),
        ),
      ),
    );

    if (pickedAssets != null && pickedAssets.isNotEmpty) {
      final asset = pickedAssets.first;
      final file = await asset.file; // 获取实际文件
      if (file != null) {
        final fileSizeInBytes = await file.length();
        final sizeInMB = fileSizeInBytes / (1024 * 1024);
        // 时间长度
        if (sizeInMB > 300) {
          MyDialog.toast('文件大小不能超过300MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
        } else {
          logger.i("文件合法，大小：$sizeInMB MB");
          selectedVideo.value = pickedAssets.first;
          status.value = '已选择视频';
          uploadVideo();
        }
      }
    }
  }

  // 选择封面图
  Future<void> pickCoverImage() async {
    descFocusNode.unfocus();

    final hasPer = await Permissions.requestPhotoPermission();
    if (!hasPer) {
      Permissions.showPermissionDialog('相册');
      return;
    }

    if (!mounted) return;

    final pickedAssets = await AssetPicker.pickAssets(
      context,
      pickerConfig: AssetPickerConfig(
        textDelegate: const AssetPickerTextDelegate(),
        pathNameBuilder: (AssetPathEntity album) {
          return Utils.translateAlbumName(album);
        },
        maxAssets: 1,
        requestType: RequestType.image,
      ),
    );

    if (pickedAssets != null && pickedAssets.isNotEmpty) {
      final asset = pickedAssets.first;
      final file = await asset.file; // 获取实际文件
      if (file != null) {
        final fileSizeInBytes = await file.length();
        final sizeInMB = fileSizeInBytes / (1024 * 1024);
        if (sizeInMB > 20) {
          MyDialog.toast('文件大小不能超过20MB', icon: const Icon(Icons.check_circle), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
        } else {
          logger.i("文件合法，大小：$sizeInMB MB");
          selectedCover.value = pickedAssets.first;
          uploadImg();
        }
      }
    }
  }

  // 上传图片
  Future<void> uploadImg() async {
    final coverFile = await selectedCover.value?.file;

    if (coverFile == null) {
      status.value = '未选择封面图';
      return;
    }

    imgPath.value = coverFile.path;
    uploading2.value = true;
    uploadProgress2.value = 0;
    status2.value = '上传中...';

    try {
      final res = await Http.upload(
        CommonApi.uploadFile,
        filePath: coverFile.path,
        fileKey: 'file',
        onSendProgress: (sent, total) {
          if (total > 0) {
            uploadProgress2.value = sent / total;
            if (sent == total) uploading2.value = false;
          }
        },
      );
      uploadedImgUrl.value = res['data']['url'];
      status2.value = '上传成功';
    } catch (e) {
      if (e is SocketException) {
        status2.value = '网络错误，请检查连接';
      } else {
        status2.value = '上传失败: ${e.toString()}';
      }
      descFocusNode.unfocus();
      uploading2.value = false;
    } finally {
      descFocusNode.unfocus();
      uploading2.value = false;
    }
  }

  // 上传视频
  Future<void> uploadVideo() async {
    final file = await selectedVideo.value?.file;

    if (file == null) {
      status.value = '未选择视频';
      return;
    }

    uploading.value = true;
    uploadProgress.value = 0;
    status.value = '上传中...';
    videoPath.value = file.path;
    logger.w(videoPath.value);
    // vwidth.value = file.width;

    snapshot.value = (await generateVideoThumbnail(file.path))!;
    logger.w(snapshot.value);

    try {
      final res = await Http.upload(
        CommonApi.uploadFile,
        filePath: file.path,
        fileKey: 'file',
        onSendProgress: (sent, total) {
          if (total > 0) {
            final pro = sent / total;
            uploadProgress.value = pro.clamp(0, 0.999);
          }
        },
      );
      logger.w('上传结果$res');
      uploadedVideoUrl.value = res['data']['url'];
      fileId.value = res['data']['ossId'];
      status.value = '上传成功';
      descFocusNode.unfocus();
      uploading.value = false;
    } catch (e) {
      if (e is SocketException) {
        status.value = '网络错误，请检查连接';
      } else {
        status.value = '上传失败: ${e.toString()}';
      }
      logger.e(e);
      descFocusNode.unfocus();
    } finally {
      descFocusNode.unfocus();
      uploading.value = false;
    }
  }

  // 发布
  Future<void> submitForm() async {
    logger.w(descriptionController.text);

    descFocusNode.unfocus();
    if (fileId.value.isEmpty) {
      Get.snackbar('请先上传视频', '未检测到上传的视频');
      return;
    }
    if (descriptionController.text.trim().isEmpty) {
      Get.snackbar('请填写视频描述', '描述是必填项');
      return;
    }

    try {
      final data = {
        'url': uploadedVideoUrl.value,
        'title': descriptionController.text.trim(),
        'fileId': fileId.value,
        'vlogerId': Get.find<ImUserInfoController>().userID.value,
        'width': selectedVideo.value!.width,
        'height': selectedVideo.value!.height,
      };
      if (uploadedImgUrl.value.isNotEmpty) {
        data['cover'] = uploadedImgUrl.value;
      }
      logger.w('发布内容：$data');
      await Http.post(VideoApi.publish, data: data);
      Get.snackbar('发布成功', '视频正在审核中');
      clearForm();
    } catch (e) {
      Get.snackbar('发布失败', '$e');
    } finally {}
  }

  void clearForm() {
    selectedVideo.value = null;
    selectedCover.value = null;
    uploadedImgUrl.value = '';
    uploadedVideoUrl.value = '';
    descriptionController.clear();
    descFocusNode.unfocus();
    status.value = '';
    status2.value = '';
    uploadProgress.value = 0.0;
    uploadProgress2.value = 0.0;
    videoPath.value = '';
    // 本地回显
    snapshot.value = '';
    imgPath.value = '';
  }

  // 预览视频
  void openVd() {
    descFocusNode.unfocus();
    showGeneralDialog(
      context: context,
      // barrierDismissible: true,
      barrierColor: Colors.black.withAlpha((1.0 * 255).round()),
      pageBuilder: (_, __, ___) {
        return SafeArea(
          child: PreviewVideo(
            videoUrl: videoPath.value,
          ),
        );
      },
      transitionBuilder: (_, anim, __, child) {
        return FadeTransition(opacity: anim, child: child);
      },
      transitionDuration: const Duration(milliseconds: 200),
    );
  }

  void openImg() {
    // 图片预览
    Get.to(() => ImageViewer(
          images: [imgPath.value],
          index: 0,
        ));
  }

  @override
  void dispose() {
    descriptionController.dispose();
    descFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FocusScope(
      canRequestFocus: widget.visible,
      // 只有 UploadVideoPage 可见时才允许 TextField 聚焦
      child: GestureDetector(
        onTap: () => descFocusNode.unfocus(),
        child: Scaffold(
          appBar: AppBar(title: const Text('上传视频')),
          body: SingleChildScrollView(
            padding: const EdgeInsets.all(20),
            child: Column(
              children: [
                TextField(
                  focusNode: descFocusNode,
                  autofocus: false,
                  controller: descriptionController,
                  decoration: const InputDecoration(
                    labelText: '视频描述 *',
                    border: OutlineInputBorder(),
                  ),
                  maxLines: 2,
                ),
                const SizedBox(height: 20),
                // 视频上传区
                Obx(() {
                  return Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      snapshot.value.isNotEmpty
                          ? GestureDetector(
                              onTap: () => openVd(),
                              child: ClipRRect(
                                borderRadius: BorderRadius.circular(8),
                                child: Image.file(
                                  File(snapshot.value),
                                  width: 80,
                                  fit: BoxFit.cover,
                                ),
                              ),
                            )
                          : const SizedBox(
                              height: 80,
                              child: Center(
                                  child: Text(
                                '未选择视频',
                                style: TextStyle(fontSize: 16),
                              )),
                            ),
                      const SizedBox(width: 24),
                      Expanded(
                        child: uploading.value
                            ? Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  const CircularProgressIndicator(),
                                  const SizedBox(height: 10),
                                  LinearProgressIndicator(value: uploadProgress.value),
                                  const SizedBox(height: 5),
                                  Text('${(uploadProgress.value * 100).toStringAsFixed(1)}%'),
                                ],
                              )
                            : ElevatedButton.icon(
                                onPressed: pickVideo,
                                icon: const Icon(Icons.upload),
                                label: Text(uploadedVideoUrl.value.isNotEmpty ? '重新选择' : '选择视频'),
                                style: ElevatedButton.styleFrom(
                                  minimumSize: const Size.fromHeight(50),
                                ),
                              ),
                      ),
                    ],
                  );
                }),
                const SizedBox(height: 20),
                // 图片上传区
                Obx(() {
                  return Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      imgPath.value.isNotEmpty
                          ? GestureDetector(
                              onTap: () => openImg(),
                              child: ClipRRect(
                                borderRadius: BorderRadius.circular(8),
                                child: Image.file(
                                  File(imgPath.value),
                                  width: 80,
                                  fit: BoxFit.cover,
                                ),
                              ),
                            )
                          : const SizedBox(
                              height: 80,
                              child: Center(
                                  child: Text(
                                '未选择封面',
                                style: TextStyle(fontSize: 16),
                              )),
                            ),
                      const SizedBox(width: 24),
                      Expanded(
                        child: uploading2.value
                            ? Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  const CircularProgressIndicator(),
                                  const SizedBox(height: 10),
                                  LinearProgressIndicator(value: uploadProgress2.value),
                                  const SizedBox(height: 5),
                                  Text('${(uploadProgress2.value * 100).toStringAsFixed(1)}%'),
                                ],
                              )
                            : ElevatedButton.icon(
                                onPressed: pickCoverImage,
                                icon: const Icon(Icons.upload),
                                label: Text(uploadedImgUrl.value.isNotEmpty ? '重新选择' : '选择封面（可选）'),
                                style: ElevatedButton.styleFrom(
                                  minimumSize: const Size.fromHeight(50),
                                ),
                              ),
                      ),
                    ],
                  );
                }),
                const SizedBox(height: 30),
                // 发布按钮
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton.icon(
                    onPressed: submitForm,
                    icon: const Icon(Icons.upload),
                    label: const Text('发布'),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
