import 'dart:typed_data';

import 'package:dio/dio.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_ui/base_define/page.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/pages/upload/cropper_screen.dart';
import 'package:flyinsono/pages/upload/upload.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;

const _limitFileSuffixs = <String>[
  ".bmp",
  ".gif",
  ".svg",
  ".png",
  ".jpg",
  ".ico",
  ".xbm",
  ".dib",
  ".pjp",
  ".tif",
  ".tiff",
  ".jfif",
  ".apng",
  ".webp",
  ".avif",
  ".jpeg",
  ".svgz",
  ".pjpeg",
];

/// 图片上传卡片
class ImageUploadCard extends FStatefulWidget implements FPage {
  /// 图片上传卡片
  ///
  /// [onChoosen] 已选择回调
  ///
  /// [onUploaded] 已上传回调
  ///
  /// [onError] 错误回调
  ///
  /// [hintText] 提示文案
  ///
  /// [isSquare] 是否正方形
  ///
  /// [originImgUrl] 现有图片链接
  ImageUploadCard({
    Key? key,
    this.hintText,
    this.onUploaded,
    this.onError,
    this.onChoosen,
    this.onDeleted,
    this.width,
    this.height,
    this.isSquare = false,
    this.isShowAddIcon = false,
    this.isCircleAvatar,
    this.originImgUrl,
    this.localImageUrl = '',
    this.pageName = 'ImageUploadCard',
  }) : super(key: key);

  final String? hintText;
  final ValueCallback<String>? onUploaded;
  final ValueCallback<dynamic>? onError;
  final ValueCallback<dynamic>? onChoosen;
  final VoidCallback? onDeleted;
  final bool isSquare;
  @override
  final String pageName;

  ///是否头像图像(使用圆形区域剪裁图片)
  final bool? isCircleAvatar;

  ///是否显示添加Icon
  final bool? isShowAddIcon;

  ///宽度
  final double? width;

  ///高度
  final double? height;

  ///现有图像链接
  final String? originImgUrl;

  ///本地Mock图像地址
  final String? localImageUrl;

  @override
  FState<ImageUploadCard> createState() => _ImageUploadCardState();
}

class _ImageUploadCardState extends FState<ImageUploadCard> {
  UploadStatus status = UploadStatus.waitChoose;
  XFile? _xFile;
  String? _imgUrl;
  String? _localUrl;

  @override
  void initState() {
    _localUrl = widget.localImageUrl;
    setUrl(widget.originImgUrl);
    super.initState();
  }

  @override
  void didUpdateWidget(covariant ImageUploadCard oldWidget) {
    setUrl(widget.originImgUrl);
    super.didUpdateWidget(oldWidget);
  }

  ///设置图像地址
  void setUrl(url) {
    _imgUrl = url;
    if ((_imgUrl != null && _imgUrl!.isNotEmpty) ||
        (_localUrl != null && _localUrl!.isNotEmpty)) {
      status = UploadStatus.success;
    } else {
      if (status == UploadStatus.success) {
        status = UploadStatus.waitChoose;
      }
    }
  }

  @override
  FWidget build(BuildContext context) {
    FWidget child;
    switch (status) {
      case UploadStatus.waitChoose:
        child = _buildWaitChoose();
        break;
      case UploadStatus.ready:
        child = FText("ready");
        break;
      case UploadStatus.uploading:
        child = _builduploading();
        _uploadFile();
        break;
      case UploadStatus.success:
        child = _buildOriginImg();
        break;
      case UploadStatus.fail:
        child = FText("Fail");
        break;
    }

    return UploadCard(
      uploadCardPanel: child,
      cardHeight: widget.height,
      cardWidth: widget.width,
      isCircleAvatar: widget.isCircleAvatar,
    );
  }

  ///上传中
  FWidget _builduploading() {
    return const FCenter(child: FCircularProgressIndicator());
  }

  ///上传完成图像
  FWidget _buildOriginImg() {
    final isCircleAvatar = widget.isCircleAvatar ?? false;

    if (isCircleAvatar) {
      final child = FPadding(
        padding: EdgeInsets.all(1),
        child: FAvatar(
          imageProvider: NetworkImage(widget.originImgUrl!),
          size: 70,
          errorBuilder: (context, error, stackTrace) {
            return FImage.asset(
              'assets/images/avatar_man.png',
              fit: BoxFit.cover,
            );
          },
        ),
      );
      Future.delayed(const Duration(milliseconds: 100), () {
        setState(() {
          status = UploadStatus.waitChoose;
        });
      });
      return child;
    }
    bool isLocal = false;
    if ((_imgUrl == null || _imgUrl!.isEmpty) &&
        (_localUrl != null && _localUrl!.isNotEmpty)) {
      isLocal = true;
      return ImageUploadSuccessBox(_localUrl!, isLocal, onDelete: _deleteFile);
    }
    return ImageUploadSuccessBox(_imgUrl!, isLocal, onDelete: _deleteFile);
  }

  ///图像待选择上传
  FWidget _buildWaitChoose() {
    final isShowAddIcon = widget.isShowAddIcon ?? false;
    final isCircleAvatar = widget.isCircleAvatar ?? false;
    final child = FStack(
      children: [
        if (isShowAddIcon) ...[
          FCenter(
            child: const FIcon(Icons.add,
                size: 36, color: Color.fromARGB(255, 104, 87, 87)),
          ),
        ],
        FPositioned(
          bottom: 10,
          left: 0,
          right: 0,
          child: FCenter(
            child: FText(
              widget.hintText ?? i18nBook.upload.uploadImage.t,
              style: const TextStyle(fontSize: 16, color: Colors.grey),
            ),
          ),
        ),
        if (isCircleAvatar) ...[
          if (widget.originImgUrl!.isEmpty) ...[
            FCenter(
              child: FAvatar(
                imageProvider: AssetImage("assets/images/avatar_man.png"),
                size: 70,
              ),
            ),
          ] else ...[
            FCenter(
              child: FAvatar(
                imageProvider: NetworkImage(widget.originImgUrl!),
                size: 70,
                errorBuilder: (context, error, stackTrace) {
                  return FImage.asset(
                    'assets/images/avatar_man.png',
                    fit: BoxFit.cover,
                  );
                },
              ),
            ),
          ]
        ]
      ],
    );
    return FMouseRegion(
      cursor: SystemMouseCursors.click,
      child: FGestureDetector(
        name: "chooseFile",
        businessParent: this.widget,
        onTap: _chooseFile,
        child: FContainer(
          color: Colors.transparent,
          child: child,
        ),
      ),
    );
  }

  ///删除图像
  void _deleteFile() {
    setState(() {
      _localUrl = null;
      setUrl(null);
      _xFile = null;
    });
    widget.onDeleted?.call();
  }

  ///选择图像
  void _chooseFile() async {
    if (kIsMobile) {
      final oldFile = _xFile;
      var result = await _showModalBottomSheet(Get.context!);
      if (result) {
        setState(() {
          if (_xFile != oldFile) {
            status = UploadStatus.uploading;
          }
        });
      }
    } else {
      final isCircleAvatar = widget.isCircleAvatar ?? false;
      if (isCircleAvatar) {
        final result = await _cropImage(_xFile);
        if (!result) {
          return;
        }
      } else {
        _xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
      }
      if (_xFile != null) {
        final fileSuffix = path.extension(_xFile!.name);
        if (!_limitFileSuffixs.contains(fileSuffix)) {
          // 验证是否图片文件
          PromptBox.toast(i18nBook.upload.selectCorrectImageFileType.t);
          return;
        }
        if (await _xFile!.length() > 0)
          setState(() {
            status = UploadStatus.uploading;
          });
      }
    }
  }

  ///上传图像
  Future<void> _uploadFile() async {
    try {
      final url = await rpc.storage.upload(_xFile!);
      Future.delayed(const Duration(milliseconds: 500), () {
        //下载地址回调
        widget.onUploaded?.call(url ?? "");
        setState(() {
          setUrl(url);
        });
      });
    } catch (e) {
      printError(info: e.toString());
      setUrl(null);
    }
  }

  ///底部弹出抽屉，用于选择在拍照/图库中选择图像
  Future<bool> _showModalBottomSheet(BuildContext context) async {
    var picker = ImagePicker();
    bool result = false;
    final isCircleAvatar = widget.isCircleAvatar ?? false;
    await showModalBottomSheet(
        context: context,
        backgroundColor: Colors.white, //背景颜色
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(10), topRight: Radius.circular(10))),
        isScrollControlled: false, //是否是全屏还是半屏，true全屏，默认false半屏
        isDismissible: true, //外部是否可以点击，false不可以点击，true可以点击，点击后消失
        builder: (BuildContext context) {
          return FColumn(
            mainAxisSize: MainAxisSize.min, // 设置最小的弹出
            children: [
              FListTile(
                leading: FIcon(Icons.photo_camera),
                title: FText(i18nBook.upload.takePhoto.t),
                onTap: () async {
                  _xFile = await picker.pickImage(source: ImageSource.camera);
                  if (_xFile != null) {
                    if (isCircleAvatar) {
                      result = await _cropImage(_xFile!);
                    } else {
                      result = true;
                    }
                    print(_xFile!.name);
                  }
                  router.back();
                },
              ),
              RowSeparator(),
              FListTile(
                leading: FIcon(Icons.photo_library),
                title: FText(i18nBook.upload.selectFromAlbum.t),
                onTap: () async {
                  _xFile = await picker.pickImage(source: ImageSource.gallery);
                  if (_xFile != null) {
                    print(_xFile!.name);
                    if (isCircleAvatar) {
                      result = await _cropImage(_xFile!);
                    } else {
                      result = true;
                    }
                  }
                  router.back();
                },
              ),
              RowSeparator(
                thickness: 5,
              ),
              FListTile(
                leading: FIcon(Icons.cancel),
                title: FText(i18nBook.common.cancel.t),
                onTap: () {
                  router.back();
                },
              ),
            ],
          );
        });
    return result;
  }

  ///剪裁图像 返回值代表是否成功剪裁
  Future<bool> _cropImage(XFile? image) async {
    try {
      Uint8List result;
      if (kIsMobile) {
        final bytes = await image!.readAsBytes();
        result = await Get.to(
          () => CropperScreen(),
          arguments: bytes,
        );
      } else {
        final orgUrl = widget.originImgUrl ?? "";
        Uint8List bytes;
        if (orgUrl.isEmpty) {
          logger.i("orgUrl is empty");
          bytes = Uint8List(0);
        } else {
          logger.i("orgUrl:" + orgUrl);
          try {
            final response = await Dio().get(orgUrl,
                options: Options(responseType: ResponseType.bytes));
            bytes = Uint8List.fromList(response.data);
          } catch (err) {
            bytes = Uint8List(0);
            logger.e("orgUrl error orgUrl:" + orgUrl);
            logger.e("error:" + err.toString());
          }
        }
        final cropResult = await Get.dialog(
          CropperScreen(),
          useSafeArea: true,
          arguments: bytes,
        );
        if (cropResult is Uint8List) {
          result = cropResult;
        } else {
          result = Uint8List(0);
        }
      }
      final fileName = Store.user.token + '.jpg';
      if (result.length > 0) {
        _xFile = XFile.fromData(
          result,
          name: fileName,
          mimeType: 'image/jpeg',
        );
      } else {
        _xFile = null;
        return false;
      }
      return true;
    } catch (e) {
      printError(info: e.toString());
      logger.e("_cropImage error:", e);
      return false;
    }
  }
}
