// ignore_for_file: unused_field

import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/lab/components/classify_data_selector/classify_data_selector.dart';
import 'package:flyinsono/lab/manager/interfaces/analysis.dart';
import 'package:flyinsono/lab/manager/interfaces/project.dart';
import 'package:flyinsono/lab/manager/page_manager.dart';
import 'package:flyinsono/lab/mock_data/mock_rpc.dart';
import 'package:flyinsono/lab/pages/lab_export/entitys/image_type.dart';
import 'package:flyinsono/lab/router/lab_route_names.dart';
import 'package:flyinsono/managers/interfaces/export_data.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'entitys/export_init_arguments.dart';
import 'index.dart';

class LabExportController extends GetxController {
  LabExportController({
    required this.tabHashCode,
    this.initArguments,
  });

  dynamic initArguments;

  final int tabHashCode;

  static const fileTypeSelectorId = "file_type_selector"; // 文件类型选择器
  static const patientSwitcherId = "patient_switcher"; //  样本/病人选择器
  static const imageDataViewId = "image_data_view"; // 图像及数据展示
  static const exportConfigPanelId = "export_config_panel"; // 底部操作栏

  final state = LabExportState();

  final exportManager = Get.find<IExportDataManager>();

  List<UDiskDriveInfoDTO> dataTargetList = [];

  String? selectedDataTarget;

  Set<ImageType> exportTypeList = {};

  Set<ImageType> exportTypes = {};

  ///项目code
  String projectCode = '';

  /// 病人列表
  List<ClassifyData<PatientModel>> patientClassifyData = [];

  bool isPatientListLoading = false;

  int selectedPatientIndex = 0;
  int selectedClassifyIndex = 0;

  /// 病人多选
  List<MultipleCheckModel> multipleCheckList = [];

  // /// 所有图片列表
  // List<ImageModel> allImageList = [];
  bool isImageListLoading = false;

  /// 所有的图片和病人
  List<LabExportResult> _allImageAndPatientList = [];

  /// 当前选中的图片和病人
  List<LabExportResult> _selectedImageAndPatientList = [];

  /// 根据图片类型筛选的图片和病人
  List<LabExportResult> _selectedImageAndPatientListByType = [];

  // 获取当前选中的病人
  PatientModel get selectedPatient =>
      patientClassifyData[selectedClassifyIndex].data[selectedPatientIndex];

  /// 图片列表
  List<ImageModel> get imageList => _allImageAndPatientList.length == 0
      ? []
      : _allImageAndPatientList[selectedPatientIndex].imageList;

  /// 当前选中的图片列表
  List<ImageModel> get selectedImageList =>
      _selectedImageAndPatientList[selectedPatientIndex].imageList;

  /// 根据图片类型筛选的图片列表
  List<ImageModel> get selectedImageListByType => imageList;

  int _totalImageListLength = 0;

  int get totalImageListLength => _selectedImageAndPatientList.fold(
        0,
        (total, labExportResult) => total + labExportResult.imageList.length,
      );

  set totalImageListLength(int value) {
    _totalImageListLength = value;
  }

  ///导出图像格式
  ExportImageFormat exportImageFormat =
      ExportImageFormat(Store.user.imageType, Store.user.videoType);

  /// 项目接口
  final projectService = Get.find<IProjectManager>();

  /// 选中文件类型（已屏蔽）
  void changeSelectedFileType(
    ImageType type,
    bool isSelected,
  ) {
    if (isSelected) {
      exportTypes.add(type);
    } else {
      exportTypes.remove(type);
    }
    List<ImageType?> imageTypeList = exportTypes.map((e) {
      return e;
    }).toList();

    for (int i = 0; i < _selectedImageAndPatientList.length; i++) {
      _selectedImageAndPatientList[i].imageList =
          _selectedImageAndPatientListByType[i]
              .imageList
              .where(
                (element) => imageTypeList.contains(
                  element.vidDataInfo.imageType,
                ),
              )
              .toList();
    }
    classifyDataChange();

    update([
      patientSwitcherId,
      fileTypeSelectorId,
      imageDataViewId,
      exportConfigPanelId,
    ]);
  }

  // 切换导出目标
  void changeDataTarget(String target) {
    selectedDataTarget = target;
    update([exportConfigPanelId]);
  }

  void clickPatientItem(int classifyIndex, int index) {
    if (selectedPatientIndex == index) {
      return;
    }

    selectedClassifyIndex = classifyIndex;
    selectedPatientIndex = index;

    update([patientSwitcherId, imageDataViewId, fileTypeSelectorId]);
  }

  /// 多选项的点击事件
  void clickPatientMultipleItem(int classifyIndex, int index) {
    for (int i = 0; i < _selectedImageAndPatientList.length; i++) {
      if (index == i) {
        if (_selectedImageAndPatientList[i].imageList.length == 0) {
          _selectedImageAndPatientList[i].imageList =
              _allImageAndPatientList[i].imageList.toList();
          _selectedImageAndPatientListByType[i].imageList =
              _allImageAndPatientList[i].imageList.toList();
        } else {
          _selectedImageAndPatientList[i].imageList = [];
          _selectedImageAndPatientListByType[i].imageList = [];
        }
      }
    }
    classifyDataChange();
    update([patientSwitcherId, imageDataViewId, fileTypeSelectorId]);
  }

  // 根据数据源更新样本列表（病人列表）
  void updatePatientList(List<PatientModel> result) async {
    isPatientListLoading = true;
    isImageListLoading = true;
    patientClassifyData = [
      ClassifyData(classifyName: "实验样本", data: result),
    ];
    state.noPatient = false;
    selectedClassifyIndex = 0;
    selectedPatientIndex = 0;

    for (PatientModel p in result) {
      await setAllImageAndPatientList(p.code);
    }
    isPatientListLoading = false;

    classifyDataChange();
    update([patientSwitcherId, imageDataViewId, fileTypeSelectorId]);
  }

  int getAllImageLength() {
    int allLength = 0;
    for (LabExportResult i in _selectedImageAndPatientList) {
      allLength += i.imageList.length;
      setExportTypeList(i.imageList);
    }

    totalImageListLength = allLength;
    update([exportConfigPanelId]);
    return allLength;
  }

  String imageTypeToString(ImageType imageType) {
    switch (imageType) {
      case ImageType.Measure_Result:
        return "图像 ";
      case ImageType.URM:
        return "URM ";
      case ImageType.URM_Result:
        return "URM 分析结果";
      case ImageType.Video:
        return "视频 ";
      case ImageType.Vid:
        return "";
      default:
        return "未知";
    }
  }

  // 导出图片
  Future<void> exportImage() async {}

  void setExportTypeList(List<ImageModel> imageList) {
    for (ImageModel i in imageList) {
      if (i.vidDataInfo.imageType == ImageType.Measure_Result) {
        if (!(exportTypeList.contains(ImageType.Measure_Result))) {
          exportTypeList.add(ImageType.Measure_Result);
          exportTypes.add(ImageType.Measure_Result);
        }
      }
      if (i.vidDataInfo.imageType == ImageType.URM) {
        if (!(exportTypeList.contains(ImageType.URM))) {
          exportTypeList.add(ImageType.URM);
          exportTypes.add(ImageType.URM);
        }
      }
      // if (i.vidDataInfo.imageType == ImageType.URM_Result) {
      //   if (!(exportTypeList.contains(ImageType.URM_Result))) {
      //     exportTypeList.add(ImageType.URM_Result);
      //     exportTypes.add(ImageType.URM_Result);
      //   }
      // }
      if (i.vidDataInfo.imageType == ImageType.Video) {
        if (!(exportTypeList.contains(ImageType.Video))) {
          exportTypeList.add(ImageType.Video);
          exportTypes.add(ImageType.Video);
        }
      }
    }
  }

  // 根据病人Id 更新图片列表
  Future<void> setAllImageAndPatientList(String patientCode) async {
    isImageListLoading = true;
    List<ImageModel> result = [];

    List<SampleRemedicalInfoDTO>? getSampleImgList =
        await projectService.getSampleImgList(
      patientCode: patientCode,
    );

    getSampleImgList?.forEach((element) {
      // find urm result vid
      ImageType imageType =
          Get.find<IURMFunctionManager>().getImageType(element);
      String vidUrl = element.imageUrl ?? '';
      if (imageType == ImageType.URM_Result) {
        String? urmResultVid =
            Get.find<IURMFunctionManager>().findURMResultVid(element);
        if (urmResultVid != null) {
          vidUrl = urmResultVid;
        }
      }
      result.add(
        ImageModel(
          id: element.businessCode ?? '',
          createTime: element.createTime ?? DateTime.now(),
          description: '',
          fileTypeName: '',
          fileDataType: element.fileDataType,
          vidDataInfo: VidDataInfo(
            vidUrl: vidUrl,
            id: element.businessCode ?? '',
            coverUrl: element.coverImgUrl ?? '',
            sampleRemedicalFileDataTypeEnum: element.fileDataType,
            imageType: imageType,
          ),
        ),
      );
    });

    isImageListLoading = false;
    List<ImageModel> imageList = result;
    LabExportResult allImageAndPatientList = LabExportResult(
      patientId: patientCode,
      imageList: imageList.toSet().toList(),
    );
    LabExportResult selectedImageAndPatientList = LabExportResult(
      patientId: patientCode,
      imageList: imageList.toSet().toList(),
    );
    LabExportResult selectedImageAndPatientListByType = LabExportResult(
      patientId: patientCode,
      imageList: imageList.toSet().toList(),
    );
    _allImageAndPatientList.add(
      allImageAndPatientList,
    );
    _selectedImageAndPatientList.add(
      selectedImageAndPatientList,
    );
    _selectedImageAndPatientListByType.add(
      selectedImageAndPatientListByType,
    );

    getAllImageLength();
  }

  /// 实验样本列表选择
  void classifyDataChange() {
    for (int i = 0; i < _selectedImageAndPatientList.length; i++) {
      List<ImageModel> allImageList =
          _allImageAndPatientList[i].imageList.toSet().toList();
      PatientModel patient = patientClassifyData[selectedClassifyIndex].data[i];
      MultipleCheckModel currentMultipleCheck = MultipleCheckModel(
        checkCode: patient.code,
        allCheck: allImageList.length,
        checkedCheck: _selectedImageAndPatientList[i].imageList.length,
        isChecked: _selectedImageAndPatientList[i].imageList.length != 0,
      );
      if (allImageList.length != 0) {
        if (multipleCheckList
            .any((element) => element.checkCode == patient.code)) {
          var item = multipleCheckList
              .firstWhere((element) => element.checkCode == patient.code);
          multipleCheckList.remove(item);
        }
        multipleCheckList.add(currentMultipleCheck);
      } else {
        if (multipleCheckList.length > 0) {
          var item = multipleCheckList
              .firstWhereOrNull((element) => element.checkCode == patient.code);
          if (item != null) {
            multipleCheckList.remove(item);
          }
        }
        multipleCheckList.add(currentMultipleCheck);
      }
    }
    update([patientSwitcherId, exportConfigPanelId]);
  }

  // 导出选中数据
  Future<void> exportDataToProject() async {
    if (_selectedImageAndPatientList.isEmpty) {
      PromptBox.toast("未选择任何数据");
      return;
    }

    List<String> patientCodes = [];
    for (LabExportResult p in _selectedImageAndPatientList) {
      if (p.imageList.isNotEmpty) {
        patientCodes.add(p.patientId);
      }
    }
    if (patientCodes.isEmpty) {
      PromptBox.toast("未选择任何数据");
      return;
    }
    ProjectSampleDataExportResult sampleDataInfo = await exportManager
        .getProjectSampleDataExport(projectCode, patientCodes);
    ResearchProjectDTO? projectInfo = await Get.find<IProjectManager>()
        .getResearchProjectDetail(projectCode: projectCode);
    String name = projectInfo?.name ?? '';
    String formattedDate =
        DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
    name += "数据导出_" + formattedDate;

    exportManager.exportDatas(name, selectedDataTarget,
        exportImageFormat: exportImageFormat,
        businessCode: projectCode,
        sampleDataInfo: sampleDataInfo);
    PageManager.ins.closeTab(tabHashCode);
    PageManager.ins.openNewTab(
      LabRouteNames.TaskList,
      "任务列表",
      multiple: false,
    );
  }

  /// 初始化导出目标列表
  void initTargetList() async {
    state.isTargetListUpdating = true;
    dataTargetList = await exportManager.getAllStorageList();
    // TODO 真实场景应该通过入参来预设导出目标
    if (dataTargetList.isNotEmpty) {
      selectedDataTarget = dataTargetList[0].path;
    }
    state.isTargetListUpdating = false;
    update([exportConfigPanelId]);
  }

  /// 更新导出目标列表
  void updateTargetList() async {
    state.isTargetListUpdating = true;
    dataTargetList = await exportManager.getAllStorageList();
    if (dataTargetList.isEmpty) {
      selectedDataTarget = null;
    } else if (!dataTargetList.contains(selectedDataTarget)) {
      selectedDataTarget = dataTargetList[0].path;
    }
    state.isTargetListUpdating = false;
    update([exportConfigPanelId]);
  }

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    initTargetList();
    print("LabBatchAnalysisController onInit initArguments: $initArguments");
    if (initArguments is LabExportInitArguments) {
      projectCode = initArguments.projectCode;
      updatePatientList(initArguments.labExportPatientList);
    }
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
  }
}

class LabExportResult {
  String patientId;
  List<ImageModel> imageList;

  LabExportResult({
    required this.patientId,
    required this.imageList,
  });
}

class MultipleCheckModel {
  String checkCode;
  int allCheck = 0;
  int checkedCheck = 0;
  bool isChecked = true;

  MultipleCheckModel({
    required this.checkCode,
    required this.allCheck,
    required this.checkedCheck,
    required this.isChecked,
  });
}

class ExportConfigPanelState {
  bool isTargetListUpdating = false;
}
