import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_measure/utils/prompt_box.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/interfaces/image_pool.dart';
import 'package:flyinsono/managers/interfaces/remedical.dart';
import 'package:flyinsono/managers/interfaces/server_config.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:fis_measure/process/workspace/rpc_bridge.dart';
import 'entitys/Image_info.dart';
import 'entitys/image_page.dart';
import 'entitys/image_state.dart';
import 'index.dart';

class ImagePoolController extends FControllerBase {
  final ScrollController imagesController = ScrollController();
  final FEventHandler<bool> onSelectAllImageChange = FEventHandler<bool>();
  final remedicalManager = Get.find<IRemedicalManager>();
  final state = ImagePoolState();
  final imagePoolManager = Get.find<IImagePoolManager>();

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    initParameters();
    initDatas();
    imagePoolManager.onExecuteResultArrived.addListener(_onExecuteResult);
    super.onInit();
  }

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

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    RPCBridge.ins.source = VidImageSource.Remedical;
    super.onClose();
  }

  /// dispose 释放内存
  @override
  void dispose() {
    imagePoolManager.onExecuteResultArrived.removeListener(_onExecuteResult);
    state.canPlayImages.forEach((key, image) {
      image.onStateChanged.dispose();
    });
    super.dispose();
  }

  //按下返回后清理页面状态
  void clearStateAfterPressedBack() {
    state.imageInfos = [];
    state.imagePags = {};
    state.isShowLoading = true;
  }

  ///获取检查对应的图像
  Future<RemedicalListResult> getRemedicalListByRecordInfoAsync() async {
    try {
      busy = true;
      final result = await rpc.remedical.getRemedicalListByRecordInfoAsync(
        QueryRecordRequest(
          token: Store.user.token,
          recordCode: state.recordCode,
        ),
      );
      state.cloudImages = result;
      busy = false;
      return result;
    } catch (e) {
      busy = false;
      return RemedicalListResult();
    }
  }

  /// 获取测量图像
  Future<void> findRemedicalMeasuredInfoAsync() async {
    try {
      state.remedicalMeasured = [];
      final result = await rpc.recordInfo.findRemedicalMeasuredInfoAsync(
        FindRemedicalMeasuredInfoRequest(
          token: Store.user.token,
          recordCode: state.recordCode,
        ),
      );
      state.remedicalMeasured = result;
    } catch (e) {
      state.remedicalMeasured = [];
      printError(
          info: "findRemedicalMeasuredInfoAsync exception:" + e.toString());
      logger.e("findRemedicalMeasuredInfoAsync exception:", e);
    }
  }

  /// 获取AI图像
  Future<void> findAiImagesAsync() async {
    if (state.recordCode.isEmpty) {
      return;
    }
    state.remedicalAISelectedInfos = [];
    final result = await rpc.remedical.getPatientAISelectedInfosAsync(
      GetPatientAISelectedInfosRequest(
        token: Store.user.token,
        recordCode: state.recordCode,
      ),
    );

    state.remedicalAISelectedInfos = result;
  }

  ///初始化入参
  void initParameters() {
    var parameters = router.getParams(NavIds.HOME) ?? {};
    if (parameters.isNotEmpty && parameters.containsKey('recordCode')) {
      state.recordCode = parameters['recordCode'] ?? '';
    }
    if (parameters.containsKey('patientCode')) {
      state.patientCode = parameters['patientCode'] ?? '';
    }
  }

  ///初始化数据
  Future<void> initDatas() async {
    await getRemedicalListByRecordInfoAsync();
    await findRemedicalMeasuredInfoAsync();
    await findAiImagesAsync();
    initPlayVideos();
    state.isShowLoading = false;
  }

  ///获取所有图像
  List<ExamImageInfo> getImageUrls() {
    final index = state.selectedIndex;
    List<ExamImageInfo> imageUrls = [];
    int imageIndex = 0;
    if (index == 0) {
      final remedicalItemList = state.cloudImages.remedicalItemList ?? [];
      remedicalItemList.forEach((remedicalItem) {
        final remedicalList = remedicalItem.remedicalList ?? [];
        remedicalList.forEach((remedical) {
          final terminalImages = remedical.terminalImages;
          if (terminalImages != null) {
            final application = remedical.application ?? '';
            final organ = remedical.patientScanType ?? '';
            final isImage =
                remedical.fileDataType == RemedicalFileDataTypeEnum.Image ||
                    remedical.fileDataType ==
                        RemedicalFileDataTypeEnum.ThirdVidSingle ||
                    remedical.fileDataType ==
                        RemedicalFileDataTypeEnum.VinnoVidSingle;
            final applicaionCategory = remedical.applicationCategory ?? "";
            String vidUrl = '';
            if (!isImage) {
              vidUrl = terminalImages.imageUrl ?? '';
            }
            imageUrls.add(
              ExamImageInfo(
                imageIndex,
                terminalImages.coverImageUrl ?? '',
                terminalImages.previewUrl ?? '',
                organ: organ,
                isImage: isImage,
                vidUrl: vidUrl,
                application: application,
                remedicalCode: remedical.remedicalCode ?? '',
                applicationCategory: applicaionCategory,
                recordCode: remedical.recordCode!,
                diagnosisConclusion: remedical.diagnosisConclusion,
                diagnosisOrgans: remedical.diagnosisOrgans,
              ),
            );
            imageIndex++;
          }
        });
      });
    } else if (index == 1) {
      final images = state.remedicalMeasured;
      for (var image in images) {
        imageUrls.add(
          ExamImageInfo(
            imageIndex,
            image.measuredFileToken ?? '',
            image.previewFileToken ?? '',
            organ: '',
            isImage: true,
            vidUrl: '',
            application: '',
            remedicalCode: image.remedicalMeasuredInfoCode ?? '',
            imageType: ExamImageType.MeasureImage,
            applicationCategory: '',
          ),
        );
        imageIndex++;
      }
    } else if (index == 2) {
      // AI 图像集合
      final images = state.remedicalAISelectedInfos;
      for (var image in images) {
        imageUrls.add(
          ExamImageInfo(
            imageIndex,
            image.aIFileToken ?? '',
            image.previewFileToken ?? '',
            organ: '',
            isImage: true,
            vidUrl: image.orginalFileToken!,
            application: '',
            remedicalCode: image.remedicalCode ?? '',
            imageType: ExamImageType.AiImage,
            applicationCategory: '',
            recordCode: image.recordCode!,
            remedicalAISelectedInfoCode: image.remedicalAISelectedInfoCode,
            diagnosisConclusion: image.diagnosisConclusion,
            diagnosisOrgans: image.diagnosisOrgans,
          ),
        );
        imageIndex++;
      }
    }
    state.imageInfos = imageUrls;
    final column = state.column;
    final pageNum = (imageUrls.length / (column * column)).ceil();
    state.imagePags = {};
    for (var i = 0; i < pageNum; i++) {
      final pageImages = imageUrls
          .where((element) =>
              element.index < (i + 1) * column * column &&
              element.index >= i * column * column)
          .toList();
      if (pageImages.isNotEmpty) {
        state.imagePags[i] = ImagePage(pageImages, i);
      }
    }
    return imageUrls;
  }

  ///选中图像
  void selectedImage(int index, int allLength) {
    int pageIndex = 0;
    state.imagePags.forEach((key, value) {
      if (value.images.any((element) => element.index == index)) {
        pageIndex = key;
        return;
      }
    });
    if (state.currentPageIndex != pageIndex) {
      state.currentPageIndex = pageIndex;
      state.canPlayImages.values.forEach((element) {
        element.isAutoPlay = false;
        element.isPlayEnd = true;
      });
    }
    var rowCount = (state.imageInfos.length / state.column).ceil();

    final lastPageRows = (state.currentPageIndex) * state.column;
    _getNextPlayImages(lastPageRows, rowCount);
  }

  ///页码
  void loadPageIndexs() {
    final index = state.currentPageIndex;
    final length = state.imagePags.length;
    if (length < 8) {
      state.pageIndexs.clear();
      state.imagePags.keys.forEach((element) {
        state.pageIndexs.add(element);
      });
    } else if (index < 3) {
      state.pageIndexs = [0, 1, 2, 3, 4, 5, 6];
    } else if (index >= 3 && index < length - 3) {
      state.pageIndexs = [
        index - 3,
        index - 2,
        index - 1,
        index,
        index + 1,
        index + 2,
        index + 3
      ];
    } else {
      state.pageIndexs = [
        length - 7,
        length - 6,
        length - 5,
        length - 4,
        length - 3,
        length - 2,
        length - 1,
      ];
    }
  }

  ///加载所有图像并执行播放
  void initPlayVideos() {
    try {
      final imageUrls = getImageUrls();
      loadPageIndexs();
      if (imageUrls.isNotEmpty &&
          imageUrls.any((element) => !element.isImage)) {
        final rowCount = (imageUrls.length / state.column).ceil();
        for (var i = 0; i < rowCount; i++) {
          final images = imageUrls.where((image) =>
              image.index < (i + 1) * state.column && !image.isImage);
          if (images.isNotEmpty) {
            for (var imageInfo in images) {
              state.isShowPlayIconMap[imageInfo.index] = true;
              state.canPlayImages[imageInfo.index] =
                  ImageState(isAutoPlay: true);
            }
            return;
          }
        }
      }
    } catch (e) {
      logger.e('ImagePoolController _initPlayVideos ex:', e);
    }
  }

  ///图像状态改变
  void onImageStateChange(int index) {
    ///用户自己点击的图像，不需要计算下一行
    if (state.userPlayImages.contains(index)) {
      state.userPlayImages.remove(index);
      return;
    }
    final imageCanPlay = state.canPlayImages;

    final imageInfos = state.imageInfos;
    final row = ((index + 1) / state.column).ceil();
    final rowImageKeys =
        imageCanPlay.keys.where((element) => element <= (row * state.column));

    ///若当前行还有未执行完成的，则不需要执行下一行的播放
    if (rowImageKeys
        .any((element) => imageCanPlay[element]!.isPlayEnd == false)) {
      return;
    }
    final rowCount = (imageInfos.length / state.column).ceil();

    ///获取下一行中需要播放的视频
    _getNextPlayImages(row, rowCount);
  }

  ///打开图像测量
  Future<void> openImageMeasure(
    ExamImageInfo imageInfo,
  ) async {
    remedicalManager.openImageMeasurePage(
      imageInfo.vidUrl,
      imageInfo.index,
      imageInfo.remedicalCode,
      imageInfo.recordCode,
      imageInfo.remedicalAISelectedInfoCode,
      state.patientCode,
    );
  }

  ///下一页
  void nextPage() {
    state.canPlayImages.forEach((key, value) {
      value.isPlayEnd = true;
    });
    state.isShowPlayIconMap.forEach((key, value) {
      value = true;
    });
    state.currentPageIndex++;
    loadPageIndexs();
    var rowCount = (state.imageInfos.length / state.column).ceil();
    final lastPageRows = (state.currentPageIndex) * state.column;
    _getNextPlayImages(lastPageRows, rowCount);
  }

  ///跳页
  void jumpToPage(int index) {
    state.canPlayImages.values.forEach((element) {
      element.isPlayEnd = true;
    });
    state.currentPageIndex = index;
    loadPageIndexs();
    var rowCount = (state.imageInfos.length / state.column).ceil();

    final lastPageRows = (state.currentPageIndex) * state.column;
    _getNextPlayImages(lastPageRows, rowCount);
  }

  ///上一页
  void previewsPage() {
    state.canPlayImages.values.forEach((element) {
      element.isPlayEnd = true;
    });
    state.currentPageIndex--;
    loadPageIndexs();
    final rowCount = (state.imageInfos.length / state.column).ceil();
    final lastPageRows = (state.currentPageIndex) * state.column;
    _getNextPlayImages(lastPageRows, rowCount);
  }

  ///批量导出
  Future<void> batchExportMeasureData() async {
    var checkNet = await Get.find<IServerConfigManager>().checkNetWork();
    if (!checkNet) {
      PromptBox.toast(i18nBook.common.networkError.t);
      return;
    }
    if (state.selectedImages.isEmpty) {
      PromptBox.toast(i18nBook.common.selectExportImage.t);
      return;
    }
    state.isExporting = true;
    await rpc.remedical.batchExportMeasureResultAsync(
      BatchExportMeasureResultRequest(
        token: Store.user.token,
        businessType: BusinessTypeEnum.RemoteDiagnosis,
        recordCode: state.recordCode,
        languageCode: i18nBook.locale.toCodeString('-'),
        remedicalMeasuredInfoCodes: state.selectedImages,
      ),
    );
  }

  ///获取下一行中需要播放的视频
  void _getNextPlayImages(int currentRow, int rowCount) {
    if (currentRow == rowCount) {
      ///如果已经是最后一行，则返回
      return;
    }
    final images = state.imageInfos.where((image) =>
        image.index > (currentRow * state.column - 1) &&
        image.index < (currentRow + 1) * state.column &&
        !image.isImage);

    ///若下一行没有能播放的视频，则继续扫描下一行
    if (images.isEmpty) {
      return _getNextPlayImages(currentRow + 1, rowCount);
    }
    final result = images.toList();

    ///若没有需要播放的视频
    if (result.isEmpty) {
      return;
    }

    result.forEach((element) {
      state.canPlayImages[element.index] = ImageState(isAutoPlay: true);
      state.isShowPlayIconMap[element.index] = false;
    });
  }

  void _onExecuteResult(Object sender, ExecuteResultNotification e) {
    logger.i(
        'ExecuteResultNotification,isSuccess:${e.isSuccess},measureDataDownloadUrl:${e.exportFileToken}');
    state.isExporting = false;
    if (e.isSuccess) {
      state.isExportFinish = e.isSuccess;
      state.measureDataDownloadUrl = e.exportFileToken ?? '';
    }
  }
}
