import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../common/api/index.dart';
import '../../../common/models/index.dart';
import '../../../common/routers/index.dart';
import '../../../common/utils/index.dart';
import '../../../common/values/index.dart';
import '../../../common/widgets/index.dart';
import '../../home/contact/contact_picker/index.dart';
import 'Image_slider_viewer/index.dart';
import 'cloud_disk_helpler.dart';
import 'file_type_list/index.dart';
import 'folder_picker/index.dart';
import 'index.dart';

class YunpanController extends GetxController {
  YunpanController();

  final state = YunpanState();
  int folderLevel = 0; // 组织层级
  final _renameController = TextEditingController();
  final _eventBus = EventBus();
  final _eventId = 'clouddisk';
   /// 队列处理进度通知
  final _queueController = StreamController<dynamic>();

  /// 图片查看器使用
   final List<FileInfo> imageList = [];

 
  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    state.title = Get.parameters['displayName'] ?? "app_name_yunpan".tr;
    _queueController.stream.listen((event) { 
      refreshData(showLoading: false);
    });
    _eventBus.on(EventBus.clouddiskFileUploadedMsg, _eventId, (f){
      _queueController.add(f);
    });
    _initBreadcrumb();
    refreshData();
    initAnimElement();
    super.onReady();
  }

  @override
  void onClose() {
    _eventBus.off(EventBus.clouddiskFileUploadedMsg, _eventId);
     _queueController.close();
    super.onClose();
  }

  /// 初始化或动画结束后执行
  initAnimElement() {
    state.visibleAnimIcon = false;
    final context = Get.context;
    if (context == null) {
      return;
    }
    final size = MediaQuery.of(context).size;
    state.animRight = size.width / 2;
    state.animTop = size.height / 2;
    state.animWidth = 64;
  }
  ///  开始执行上传文件丢进去的动画
  _startUploadAnim() {
    state.visibleAnimIcon = true;
    state.animRight = 0;
    state.animTop = 0;
    state.animWidth = 0;
  }

  /// 初始化面包屑导航
  _initBreadcrumb() {
    folderLevel = 0;
    state.breadcrumbBeans.clear();
    state.breadcrumbBeans.add(FolderBreadcrumbBean(
         'cloud_disk_breadcrumb_all'.tr, O2.o2DefaultUnitParentId, folderLevel));
  }

  /// 刷新数据
  void refreshData({bool showLoading = true}) {
    var lastBreadcrumb = state.breadcrumbBeans.last;
    // 获取列表数据
    _loadList(lastBreadcrumb, showLoading: showLoading);
    // 是否显示 顶部的分类区域
    if (state.breadcrumbBeans.length == 1) {
      state.visibleTop = true;
    } else {
      state.visibleTop = false;
    }
  }
  /// 根据当前层级加载列表数据
  void _loadList(FolderBreadcrumbBean breadcrumbBean, {bool showLoading = true}) {
    state.cloudDiskItemCheckedList.clear();
    var folderId = breadcrumbBean.folderId;
    folderLevel = breadcrumbBean.level;
    if (folderId == O2.o2DefaultUnitParentId){
      _loadTopList(showLoading: showLoading);
    } else {
      _loadListByParent(folderId, showLoading: showLoading);
    }
  }

  /// 查询顶层数据
  Future<void> _loadTopList({bool showLoading = true}) async {
    if (showLoading) { Loading.show(); }
    List<CloudDiskItem> items = [];
    var listFolder = await FileAssembleService.to.listFolderTop();
    if (listFolder != null) {
      for (var element in listFolder) {
        var item = CloudDiskItem.folder(element);
        items.add(item);
      }
    }
    var listFile = await FileAssembleService.to.listFileTop();
    if (listFile != null) {
      for (var element in listFile) {
        var item = CloudDiskItem.file(element);
        items.add(item);
      }
    }
    state.cloudDiskItemList..clear()..addAll(items);
    // 数据过滤 把图片对象放入 imageList
    imageList..clear()..addAll(
      state.cloudDiskItemList.where((p0) => !p0.isFolder && p0.file?.fileNamePlusExtension().isImageFileName == true).map((e) {
        FileInfo info = e.file!;
        info.isV3 = false;
        return info;
      }).toList());
    if (showLoading) { Loading.dismiss(); }
  }
  /// 查询数据
  Future<void> _loadListByParent(String parentId, {bool showLoading = true}) async {
    if (showLoading) {
      Loading.show();
    }
    List<CloudDiskItem> items = [];
    var listFolder = await FileAssembleService.to.listFolderByParent(parentId);
    if (listFolder != null) {
      for (var element in listFolder) {
        var item = CloudDiskItem.folder(element);
        items.add(item);
      }
    }
    var listFile = await FileAssembleService.to.listFileByParent(parentId);
    if (listFile != null) {
      for (var element in listFile) {
        var item = CloudDiskItem.file(element);
        items.add(item);
      }
    }
    state.cloudDiskItemList..clear()..addAll(items);
    // 数据过滤 把图片对象放入 imageList
    imageList..clear()..addAll(
      state.cloudDiskItemList.where((p0) => !p0.isFolder && p0.file?.fileNamePlusExtension().isImageFileName == true).map((e) {
        FileInfo info = e.file!;
        info.isV3 = false;
        return info;
      }).toList());
    if (showLoading) { Loading.dismiss(); }
  }
  /// 创建文件夹
  void createFolder() async {
    final context = Get.context;
    if (context == null) {
      return;
    }
    var folderId = state.breadcrumbBeans.last.folderId;
    if (folderId == O2.o2DefaultUnitParentId) {
      folderId = '';
    }
    _renameController.text = "";
    var result = await O2UI.showCustomDialog(
        context,
        'cloud_disk_action_create_folder'.tr,
        TextField(
          controller: _renameController,
          maxLines: 1,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.done,
        ));
    if (result == O2DialogAction.positive) {
      final filename = _renameController.text;
      if (filename.isEmpty) {
        Loading.showError('cloud_disk_create_folder_not_empty_name'.tr);
        return;
      }
      final post = FolderPost(name: filename, superior: folderId);
      await FileAssembleService.to.createFolder(post);
      refreshData();
    }
  }
  /// 上传文件
  void uploadFile() async {
    var folderId = state.breadcrumbBeans.last.folderId;
    if (folderId == O2.o2DefaultUnitParentId) {
      folderId = O2.o2DefaultPageFirstKey;
    }
    O2Utils.pickerFileOrImage((paths) {
      _uploadFileBegin(paths, folderId);
    }, allowMultiple: true);
  }
  Future<void> _uploadFileBegin(List<String?> paths, String folderId) async {
    if (paths.isEmpty) {
      return;
    }
    for (var element in paths) {
      if (element?.isNotEmpty == true) {
        CloudDiskHelper().uploadFile(File(element!), folderId, false);
      }
    }
   _startUploadAnim();
  }

  openUploadPage() {
    Get.toNamed(O2OARoutes.appCloudDiskUploadList);
  }

  /// 点击面包屑导航
 void clickBreadcrumb(FolderBreadcrumbBean bean) {
    var list = state.breadcrumbBeans.toList();
    var last = list.last;
    if (bean.folderId != last.folderId) {
      var clickIndex = 0;
      for (var i = 0; i < list.length; i++) {
        var item = list[i];
        if (item.folderId == bean.folderId) {
          clickIndex = i;
        }
      }
      var newList = clickIndex == 0 ? [list[0]] : list.sublist(0, clickIndex);
      state.breadcrumbBeans.clear();
      state.breadcrumbBeans.addAll(newList);
      refreshData();
    }
 }
 /// 选中某一个 Item
  void onItemCheckedChange(CloudDiskItem item, bool? checked) {
    if (checked == true) {
      state.cloudDiskItemCheckedList.add(item);
    } else if (checked == false) {
      state.cloudDiskItemCheckedList.removeWhere((element) {
        if (element.isFolder && item.isFolder) {
          return element.folder?.id == item.folder?.id;
        } else if (!element.isFolder && !item.isFolder) {
          return element.file?.id == item.file?.id;
        }
        return false;
      });
    }
  }
 
  /// 点击列表对象 
  void onItemClick(CloudDiskItem item) {
    if (item.isFolder) {
      OLogger.d('点击文件夹: ${item.folder?.name}');
      FolderBreadcrumbBean bean = FolderBreadcrumbBean(item.folder?.name ?? '', item.folder?.id ?? '', folderLevel+1);
      state.breadcrumbBeans.add(bean);
      refreshData();
    } else {
      OLogger.d('点击文件: ${item.file?.name}');
      final file = item.file;
      if (file != null) {
        if (file.fileNamePlusExtension().isImageFileName == true) {
          ImageSliderViewerPage.openViewer(imageList, currentFileId: file.id); // 图片查看器
        } else {
          CloudDiskHelper().downloadAndOpenFile(file); // 其他文件打开
        }
      }
    }
  }


  /// 重命名
  void rename() async {
    if (state.cloudDiskItemCheckedList.isEmpty) {
      return;
    }
    final context = Get.context;
    if (context == null) {
      return;
    }
    final item = state.cloudDiskItemCheckedList.first;
    _renameController.text = item.displayName;
    
    var result = await O2UI.showCustomDialog(
        context,
        'cloud_disk_buttons_rename'.tr,
        TextField(
          controller: _renameController,
          maxLines: 1,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.done,
        ));
    if (result == O2DialogAction.positive) {
      final filename = _renameController.text;
      if (filename.isEmpty) {
        Loading.showError('cloud_disk_rename_not_empty'.tr);
        return;
      }
      _renameItem(item, filename);
    }
  }

  _renameItem(CloudDiskItem item, String newName) async {
    if (item.isFolder) {
      var folder = item.folder;
      if (folder == null) {
        return;
      }
      folder.name = newName;
      final result = await FileAssembleService.to.updateFolder(folder);
      if (result != null) {
        refreshData();
      }
    } else {
       var file = item.file;
      if (file == null) {
        return;
      }
      file.name = newName;
      final result = await FileAssembleService.to.updateFile(file);
      if (result != null) {
        refreshData();
      }
    }
  }

  /// 删除
  void delete() {
    final context = Get.context;
    if (context == null) {
      return;
    }
    if (state.cloudDiskItemCheckedList.isEmpty) {
      return;
    }
    O2UI.showConfirm(context, 'cloud_disk_delete_confirm'.tr, okPressed: (){
      _deleteItems();
    });
  }
  _deleteItems() async {
    for (var item in state.cloudDiskItemCheckedList) {
      if (item.isFolder) {
        final id = item.folder?.id ?? '';
        if (id.isNotEmpty) {
          await FileAssembleService.to.deleteFolder(id);
        }
      } else  {
        final id = item.file?.id ?? '';
        if (id.isNotEmpty) {
          await FileAssembleService.to.deleteFile(id);
        }
      }
    }
    refreshData();
  }
  /// 移动
  void move() async {
    if (state.cloudDiskItemCheckedList.isEmpty) {
      return;
    }
    final result = await FolderPickerPage.open();
    if (result != null && result is FolderInfo) {
      final newParent = result;
      OLogger.d('选择的目录： ${newParent.name} ${newParent.id}');
      for (var item in state.cloudDiskItemCheckedList) {
        if (item.isFolder) {
          var folder = item.folder;
          if (folder == null) {
            continue;
          }
          folder.superior = newParent.id;
          await FileAssembleService.to.updateFolder(folder);
        } else  {
          final file = item.file;
          if (file == null) {
            continue;
          }
          file.folder = newParent.id;
          await FileAssembleService.to.updateFile(file);
        }
      }
      refreshData();
    }
  }
  /// 分享
  void share() async {
    if (state.cloudDiskItemCheckedList.isEmpty) {
      return;
    }
    final result = await ContactPickerPage.startPicker([
      ContactPickMode.personPicker,
      ContactPickMode.departmentPicker,
    ], multiple: true);
    if (result != null && result is ContactPickerResult) {
      final users = (result.users ?? []).map((e) => e.distinguishedName??'').toList();
      final units = (result.departments ?? []).map((e) => e.distinguishedName??'').toList();
      if (users.isEmpty && units.isEmpty) {
        return;
      }
      for (var item in state.cloudDiskItemCheckedList) {
        var id = '';
        if (item.isFolder) {
          id = item.folder?.id ?? '';
        } else  {
          id = item.file?.id ?? '';
        }
        if (id.isEmpty) {
          continue;
        }
        final form = CloudDiskShareForm(fileId: id, shareOrgList: units, shareUserList: users);
        await FileAssembleService.to.share(form);
      }
      refreshData();
    }
  }

  void clickGoto(CloudDiskFileType type) {
    FileTypeListPage.open(type);
  }

  void clickGotoShare() {
    Get.toNamed(O2OARoutes.appCloudDiskShareList);
  }

}
