import 'dart:async';

import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/index.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/desktop/names.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/common_business.dart';
import 'package:flyinsono/managers/interfaces/report.dart';
import 'package:flyinsono/pages/index.dart';
import 'package:flyinsono/pages/remedical/consultation/controller.dart';
import 'package:flyinsono/pages/remedical/consultation/state.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/association_exams.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/exam_images_list_view.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/exam_images_view.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/exam_records.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/inspection_details_dialog.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/inspection_report_dialog.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';

/// 检查记录的控制器
class ExamRecordsController extends FControllerBase {
  late ConsultationController controller;
  late FConsultationState state;
  ExamRecordsController(ConsultationController controller) {
    this.controller = controller;
    this.state = controller.state;
  }

  /// 打开检查详情弹窗
  ///
  /// [recordCode] 检查code
  void openCheckDialog(String? recordCode) async {
    if (recordCode == null) return;
    var result = await getCheckInfo(recordCode);
    if (result) {
      router.dialog(
        () => InspectionDetailsDiaLog(
          recordCode: recordCode,
          checkInfo: state.checkLists.firstWhere(
            (element) => element.recordCode == recordCode,
          ),
          patientInfoExts: controller.state.checkInfoLists,
          patientInfo: state.patientInfo,
          patientType: controller.state.patientType,
        ),
      );
    }
  }

  /// 打开关联报告
  ///
  /// [recordCode] 检查code
  void openReportDialog(
    String? recordCode,
  ) async {
    final reportLists = state.patientTab == 0
        ? await rpc.report.findExamReportsAsync(
            FindReportsRequest(
              token: Store.user.token,
              recordCode: recordCode,
              languageCode: i18nBook.locale.toCodeString('-'),
            ),
          )
        : await controller.referPatientInfoController
            .queryReferralExamReportsAsync(state.referralRecordCode);
    print(reportLists);

    router.dialog(
      () => InspectionReportDiaLog(
        recordCode: recordCode!,
        reportLists: reportLists,
        patientInfo: state.patientInfo,
      ),
    );
    // await getCheckInfo(recordCode!);
  }

  /// 打开那些未扫查的图像
  ///
  /// [patientCode] 病人code
  void association(String patientCode, String devicePatientCode) async {
    await getRecordInfoPagesAsync(
      patientCode,
      QueryRecordStatusEnum.NotScanned,
    );
    if (state.getRecordsPageResult.length == 0) {
      Future.delayed(const Duration(milliseconds: 500), () {
        PromptBox.toast(i18nBook.remedical.noCheckToHandle.t);
      });
    } else {
      Get.back();
      router.dialog(
        () => AssociatCheck(patientCode, devicePatientCode),
      );
    }
  }

  /// 清除转诊缓存
  void cleanState() {
    state.subjectMatter = '';
    state.referralOrganizationCode = null;
    state.referralUserCode = null;
    state.referUserList = [];
  }

  ///查询检查详情
  Future<QueryRecordResult?> queryRecordInfoAsync(String recordCode) async {
    try {
      return await rpc.recordInfo.queryRecordInfoAsync(
        QueryRecordRequest(
          token: Store.user.token,
          recordCode: recordCode,
        ),
      );
    } catch (e) {
      logger.e('ExamRecordsController queryRecordInfoAsync ex:', e);
      return null;
    }
  }

  /// 获取检查信息
  Future<bool> getCheckInfo(String recordCode) async {
    try {
      final checkInfo = await queryRecordInfoAsync(recordCode);
      if (checkInfo == null) {
        return false;
      }
      final patientInfoExtList = checkInfo.patientInfoExtList ?? [];
      state.checkInfoLists = patientInfoExtList;
      return true;
    } catch (e) {
      logger.e('msg', e);
    }
    return false;
  }

  /// 关联检查-获取未扫查的图像
  Future<void> getRecordInfoPagesAsync(
      String patientCode, QueryRecordStatusEnum? queryRecordStatus,
      {int? pageIndex = 1}) async {
    try {
      final checkLists =
          await getRecordInfoPages(patientCode, pageIndex, queryRecordStatus);

      state.getRecordsPageResult = checkLists.pageData ?? [];
    } catch (e) {
      logger.e('queryReferralRecordInfoPagesAsync', e);
    }
  }

  ///获取检查的扫查图像
  Future<bool> getCheckScannedImage(String recordCode) async {
    try {
      final reportManager = Get.find<IReportManager>();
      final result = state.patientTab == 0
          ? await reportManager.getRemedicalListByRecordInfoAsync(recordCode)
          : await reportManager.queryReferralRemedicalListByRecordInfoAsync(
              recordCode,
              state.referralRecordCode,
            );
      state.getScannedImage = result;
      if (result.remedicalItemList == null ||
          result.remedicalItemList!.isEmpty) {
        PromptBox.toast(i18nBook.common.noData.t);
        return false;
      }
      await controller.findRemedicalMeasuredInfoAsync(recordCode);
      state.recordCode = recordCode;
      if (kIsMobile) {
        return true;
      } else {
        router.to(
          RouteNames.Remedical.ImagePool,
          id: NavIds.HOME,
          parameters: {
            "recordCode": recordCode,
            "patientCode": state.patientCode,
          },
        );
      }
    } catch (e) {
      printError(
          info: "getRemedicalListByRecordInfoAsync exception:" + e.toString());
      logger.e("getRemedicalListByRecordInfoAsync exception:", e);
    }
    return false;
  }

  //手机端检查记录上一条
  Future<void> lastExamPage() async {
    if (state.examRecordIndex > 0) {
      state.examRecordIndex--;
      state.examRecord = state.checkLists[state.examRecordIndex];
      await getCheckInfo(state.examRecord.recordCode!);
      controller.onstatusChange.emit(this, '');
    }
  }

  ///手机端检查记录下一条
  Future<void> nextExamPage() async {
    if (state.examRecordIndex + 1 == state.checkLists.length) {
      var patientInfo = state.patientInfos[state.selectPatientCardIndex];
      state.recordPage++;
      getCheckLists(patientInfo.patientCode, pageIndex: state.recordPage);
    }
    if (state.examRecordIndex < state.checkLists.length) {
      state.examRecordIndex++;
      state.examRecord = state.checkLists[state.examRecordIndex];
      await getCheckInfo(state.examRecord.recordCode!);
    }
    controller.onstatusChange.emit(this, '');
  }

  Future<PageResult<GetRecordsPageDTO>> getRecordInfoPages(
    String? patientCode,
    int? pageIndex,
    QueryRecordStatusEnum? queryRecordStatus,
  ) async {
    try {
      final getRecordsPage = await rpc.recordInfo.getRecordInfoPagesAsync(
        GetRecordsPageRequest(
          token: Store.user.token,
          pageIndex: pageIndex ?? 1,
          queryRecordStatus: queryRecordStatus ?? QueryRecordStatusEnum.All,
          pageSize: 60,
          patientCode: patientCode,
        ),
      );
      return getRecordsPage;
    } catch (e) {
      return PageResult<GetRecordsPageDTO>();
    }
  }

  /// 获取检查列表
  Future<void> getCheckLists(String? patientCode, {int? pageIndex = 1}) async {
    if (patientCode == null || patientCode.isEmpty) {
      logger.i("getRecordInfoPage by patientCode fail,patientCode is empty");
      return;
    }
    try {
      final checkLists = await getRecordInfoPages(
        patientCode,
        pageIndex,
        QueryRecordStatusEnum.All,
      );

      List<GetRecordsPageDTO> datas = checkLists.pageData ?? [];
      state.recordCount = checkLists.totalCount;
      if (pageIndex == 1) {
        state.checkLists = datas;
      } else {
        //获取下一页信息
        state.checkLists.addAll(datas);
      }
      if (kIsMobile && state.checkLists.isNotEmpty) {
        state.examRecord = state.checkLists[0];
      } else if (kIsMobile && state.checkLists.isEmpty) {
        state.examRecord = GetRecordsPageDTO();
      }
    } catch (e) {
      state.checkLists = [];
      logger.e('getRecordInfoPages', e);
    }
  }

  /// 打开检查页面
  Future<void> openCreatecheckPage(String patientCode) async {
    if (kIsMobile) {
      final recordCode = state.examRecord.recordCode ?? '';
      if (recordCode.isEmpty) {
        PromptBox.toast(
            i18nBook.homePage.notYet.t + i18nBook.remedical.check.t);
        return;
      }
      state.recordPage = 1;
      state.examRecordIndex = 0;
      Get.to(() => ExamRecord());
    } else {
      router.dialog(
        () => CreatecheckPage(
          patientCode,
        ),
        binding: CreatecheckBinding(),
      );
    }
  }

  ///手机端获取云端图像
  Future<void> getImages() async {
    final patientInfo = state.patientInfos[state.selectPatientCardIndex];
    await getCheckLists(patientInfo.patientCode);
  }

  /// 获取转入机构
  Future<void> queryReferralOrganizationsAsync() async {
    try {
      final result = await rpc.remedical.queryReferralOrganizationsAsync(
        ReferralOrganizationsQueryRequest(
          token: Store.user.token,
        ),
      );
      List<OrgModel> referOrg = [];

      result.forEach(
        (e) {
          referOrg.add(
            OrgModel(
              name: e.organizationName ?? '',
              code: e.organizationCode ?? '',
            ),
          );
        },
      );
      state.referOrg = referOrg;
    } catch (e) {
      printError(
          info: "queryReferralOrganizationsAsync exception:" + e.toString());
      logger.e("queryReferralOrganizationsAsync exception:", e);
    }
  }

  /// 获取转入机构下面的医生用户
  Future<void> getUserListAsync(String organizationCode) async {
    final result = await rpc.user.getUserListAsync(
      GetUserListRequest(
        token: Store.user.token,
        organizationCode: organizationCode,
        language: i18nBook.locale.toCodeString('-'),
        roleCodes: [RoleType.certifiedPhysician, RoleType.certifiedExpert],
        // 全部和待分配的枚举
        organizationQueryType: OrganizationQueryTypeEnum.All,
      ),
    );
    final List<UserDoctorModel> referUserList = [];
    result.forEach(
      (element) {
        final referUserName = element.displayName!;
        referUserList.add(
          UserDoctorModel(
            name: referUserName,
            code: element.userCode ?? '',
            roleCodes: element.roleCodes ?? [],
            fieldList: element.fieldList ?? [],
            headImageUrl: element.headImageUrl ?? '',
          ),
        );
      },
    );
    state.referUserList = referUserList;
  }

  /// 加载角色集合
  Future<void> loadRoles() async {
    final roles = await rpc.role.findAuthenticationRolesAsync(
      FindAuthenticationRolesRequest(
        token: Store.user.token,
        language: i18nBook.locale.toCodeString('-'),
      ),
    );
    List<UserRoleModel> userRoleList = [];
    roles.forEach(
      (e) => userRoleList.add(
        UserRoleModel(
          code: e.roleCode ?? '',
          name: e.roleName ?? '',
        ),
      ),
    );
    state.userRoleList = userRoleList;
  }

  /// 转诊提交
  Future<void> submitRefer(
    String patientCode,
    String referralRecordCode,
  ) async {
    try {
      if (state.subjectMatter.isEmpty ||
          state.referralUserCode == '' ||
          state.referralUserCode == null ||
          state.referralOrganizationCode == '') {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
      } else {
        if (!controller.state.isModifyReferralRecord) {
          /// 创建转诊
          final applyReferralRecord =
              await rpc.remedical.applyReferralRecordAsync(
            CreateReferralRecordRequest(
              token: Store.user.token,
              patientCode: patientCode,
              subjectMatter: state.subjectMatter,
              referralOrganizationCode: state.referralOrganizationCode,
              referralUserCode: state.referralUserCode,
              referralRecordCode: referralRecordCode,
            ),
          );
          if (applyReferralRecord.isNotEmpty) {
            if (controller.state.patientTab == 0) {
              await findPatientReferralRecordAsync(patientCode);
            } else {
              await findReferralInRecordAsync(referralRecordCode);
            }
            controller.state.referTab = 1;
          }
        } else {
          /// 修改转诊
          final applyReferralRecord =
              await rpc.remedical.modifyReferralRecordAsync(
            ModifyReferralRecordRequest(
              token: Store.user.token,
              patientCode: patientCode,
              subjectMatter: state.subjectMatter,
              referralOrganizationCode: state.referralOrganizationCode,
              referralUserCode: state.referralUserCode,
              referralRecordCode: controller.state.modifyReferralRecordCode,
            ),
          );
          if (applyReferralRecord.isNotEmpty) {
            if (controller.state.patientTab == 0) {
              await findPatientReferralRecordAsync(patientCode);
            } else {
              await findReferralInRecordAsync(referralRecordCode);
            }
            controller.state.referTab = 1;
          }
        }
        controller.state.isModifyReferralRecord = false;
        controller.state.modifyReferralRecordCode = '';
      }
    } catch (e) {
      printError(info: "applyReferralRecordAsync exception:" + e.toString());
      logger.e("applyReferralRecordAsync exception:", e);
    }
  }

  /// 转出历史
  Future<void> findPatientReferralRecordAsync(String patientCode) async {
    try {
      final checkLists = await rpc.remedical.findPatientReferralRecordAsync(
        FindPatientReferralRecordRequest(
          token: Store.user.token,
          patientCode: patientCode,
        ),
      );
      state.referralRecordDetail = checkLists;
    } catch (e) {
      printError(
          info: "findPatientReferralRecordAsync exception:" + e.toString());
      logger.e("findPatientReferralRecordAsync exception:", e);
    }
  }

  /// 转入历史
  Future<void> findReferralInRecordAsync(String referralRecordCode) async {
    try {
      final checkLists = await rpc.remedical.findReferralInRecordAsync(
        FindReferralInRecordRequest(
          token: Store.user.token,
          referralRecordCode: referralRecordCode,
        ),
      );
      state.referralRecordDetail = checkLists;
    } catch (e) {
      printError(info: "findReferralInRecordAsync exception:" + e.toString());
      logger.e("findReferralInRecordAsync exception:", e);
    }
  }

  /// 撤销转诊
  Future<void> withdrawReferralRecordAsync(
      String referralRecordCode, String patientCode) async {
    try {
      final withdrawReferralRecord =
          await rpc.remedical.withdrawReferralRecordAsync(
        WithdrawReferralRecordRequest(
          token: Store.user.token,
          referralRecordCode: referralRecordCode,
        ),
      );
      if (withdrawReferralRecord) {
        if (controller.state.patientTab == 0) {
          await findPatientReferralRecordAsync(patientCode);
        } else {
          await findReferralInRecordAsync(referralRecordCode);
        }
        // 状态变化
        controller.state.referTab = 3;
        controller.state.referTab = 1;
      } else {
        PromptBox.toast('error');
      }
    } catch (e) {
      printError(info: "withdrawReferralRecordAsync exception:" + e.toString());
      logger.e("withdrawReferralRecordAsync exception:", e);
    }
  }

  /// 同意转诊 or 拒绝转诊
  Future<void> auditReferralRecordAsync(
    String referralRecordCode,
    bool isReceive,
  ) async {
    try {
      if (!isReceive && state.refuseCause.isEmpty) {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
      } else {
        final withdrawReferralRecord =
            await rpc.remedical.auditReferralRecordAsync(
          AuditReferralRecordRequest(
            token: Store.user.token,
            referralRecordCode: referralRecordCode,
            isReceive: isReceive,
            rejectReason: state.refuseCause,
          ),
        );
        if (withdrawReferralRecord) {
          await findReferralInRecordAsync(referralRecordCode);
          // 状态变化
          controller.state.referTab = 3;
          controller.state.referTab = 1;
          router.back();
          controller.state.refuseCause = '';
        } else {
          PromptBox.toast('error');
        }
      }
    } catch (e) {
      printError(info: "withdrawReferralRecordAsync exception:" + e.toString());
      logger.e("withdrawReferralRecordAsync exception:", e);
    }
  }

  openCloudImagePage() async {
    /// 抛出未实现的异常
    throw UnimplementedError();
    // 病人卡片已弃用
    // final recordCode = state.examRecord.recordCode ?? '';

    // if (recordCode.isEmpty) {
    //   PromptBox.toast(i18nBook.homePage.notYet.t + i18nBook.remedical.image.t);
    //   return;
    // }
    // await controller.findRemedicalMeasuredInfoAsync(recordCode);
    // if (state.imageScanned.length == 0) {
    //   PromptBox.toast(i18nBook.homePage.notYet.t + i18nBook.remedical.image.t);
    //   return;
    // } else {
    //   await Get.to(
    //     () => ExamImagesListView(
    //       measureImages: state.remedicalMeasured,
    //       cloudImageInfos: state.imageScanned,
    //       patientCode: state.patientCode,
    //     ),
    //   );
    // }
  }
}
