import 'dart:convert';

import 'package:fis_jsonrpc/rpc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vitalapp/architecture/defines.dart';
import 'package:vitalapp/architecture/utils/prompt_box.dart';
import 'package:vitalapp/architecture/values/features.dart';
import 'package:vitalapp/components/alert_dialog.dart';
import 'package:vitalapp/global.dart';
import 'package:vitalapp/managers/interfaces/device.dart';
import 'package:vitalapp/managers/interfaces/models/device.dart';
import 'package:vitalapp/managers/interfaces/patient.dart';
import 'package:vitalapp/managers/interfaces/permission.dart';
import 'package:vitalapp/pages/controllers/blue_location_mixin.dart';
import 'package:vitalapp/pages/controllers/crowd_labels.dart';
import 'package:vitalapp/pages/controllers/home_nav_mixin.dart';
import 'package:vitalapp/pages/patient/bluetooth_card_reader/view.dart';
import 'package:vitalapp/pages/patient/card_reader/index.dart';
import 'package:vitalapp/pages/patient/create/state.dart';
import 'package:vitalapp/pages/patient/create/widgets/face_result_dialog.dart';
import 'package:vitalapp/pages/patient/list/controller.dart';
import 'package:vitalapp/routes/routes.dart';
import 'package:vitalapp/store/store.dart';
import 'package:vnote_device_plugin/consts/types.dart';
import 'package:fis_common/logger/logger.dart';
import '../../facial_recognition/index.dart';
import '../../id_card_scan/index.dart';

class CreatePatientController extends FControllerBase
    with HomeNavMixin, BluetoothAndLocationMixin {
  final _patientManager = Get.find<IPatientManager>();
  final crowdLabelsController = Get.find<CrowdLabelsController>();
  final _patientListController = Get.find<PatientListController>();
  final _deviceManager = Get.find<IDeviceManager>();

  final state = CreatePatientState();

  @override
  Future<void> onLoad() {
    final params = Get.parameters;
    if (params.containsKey("from")) {
      if (params["from"] == "list") {
        state.isCreateOnly = true;
      }
    }
    if (Routes.parameters.containsKey('patientInfo')) {
      if (Routes.parameters['patientInfo'] != null) {
        PatientBaseDTO patientInfo = PatientBaseDTO.fromJson(
          jsonDecode(
            Routes.parameters['patientInfo']!,
          ),
        );
        patientInfoParse(patientInfo);
      }
    }
    return super.onLoad();
  }

  /// 保存档案，调整签约
  void gotoSignContract() async {
    setBusy("正在保存...");
    String? code;
    try {
      final validateMsg = await _validateForm();
      if (validateMsg != null) {
        toast(validateMsg);
        return null;
      }

      code = await _submitForm();
      if (code == null) {
        busy = false;
        PromptBox.toast("保存失败");
        return;
      }

      // final code = "13B95A2B2790464BBFD9B30A71F15C95";
      busy = false;
      Future.delayed(
        const Duration(milliseconds: 800),
        () {
          state.reset(); // 重置状态
        },
      );
    } finally {
      if (code != null) {
        Get.toNamed(
          "/contract/package_list",
          parameters: {"patientCode": code},
        );
      }
    }
    // Get.find<HomeController>().switchNavByName("/patient/list");
    // Future.delayed(
    //   const Duration(milliseconds: 800),
    //   () {
    //     // TODO:
    //     Get.find<PatientListController>().gotoDetail(code);
    //     busy = false;
    //   },
    // );
  }

  /// 存为档案，调整到档案详情
  void saveAndBack() async {
    final validateMsg = await _validateForm();
    if (validateMsg != null) {
      toast(validateMsg);
      return null;
    }

    final code = await _submitForm();
    if (code == null) {
      busy = false;
      logger.e('CreatePatientController saveAndBack code is null');
      // PromptBox.toast("保存失败");
      return;
    } else {
      busy = false;
      // await queryIsNeedFaceInput();   //询问是否录入人脸
      if (Store.user.hasFeature(FeatureKeys.FaceRecognition) && kIsOnline) {
        var photoUrl = await getPatientPhoto(state.cardNo);
        if (photoUrl.isEmpty) {
          await onFaceEntryClicked(); //不询问直接录入
        }
      }
      Future.delayed(
        ///这个800ms不能移除，移除后会导致建档失败
        const Duration(milliseconds: 800),
        () {
          state.reset(); // 重置状态
          busy = false;
          PromptBox.toast("保存成功");
          _patientListController.reloadList();
        },
      );
    }

    ///不跳转到详情页
    // Get.find<HomeController>().switchNavByName("/patient/list");
    // Get.put(PatientListController());
    Future.delayed(
      ///这个800ms不能移除，移除后会导致建档失败
      const Duration(milliseconds: 800),
      () async {
        onIdcardInfoIsCreateRecord(code);
        await Get.find<PatientListController>().gotoDetail(
          code,
        );
        busy = false;
      },
    );
  }

  /// 询问是否需要人脸录入
  Future<void> queryIsNeedFaceInput() async {
    /// 拥有人脸权限并且不是身份证扫码建档
    if (Store.user.hasFeature(FeatureKeys.FaceRecognition) && kIsOnline) {
      var photoUrl = await getPatientPhoto(state.cardNo);
      if (photoUrl.isNotEmpty) {
        await Get.dialog(VAlertDialog(
          contentPadding: const EdgeInsets.fromLTRB(20, 1, 20, 1),
          title: '提示',
          content: Container(
            margin: const EdgeInsets.only(bottom: 20),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Image.network(photoUrl,
                    width: 300, height: 220, fit: BoxFit.cover,
                    loadingBuilder: (context, child, progress) {
                  if (progress == null ||
                      progress.cumulativeBytesLoaded ==
                          progress.expectedTotalBytes) {
                    return Image.network(
                      photoUrl,
                      width: 300,
                      height: 220,
                      fit: BoxFit.cover,
                    );
                  }
                  return const CircularProgressIndicator(
                      color: Colors.blueAccent);
                }),
                const Text("该居民已采集过人脸，是否重新采集？",
                    style: TextStyle(fontSize: 20),
                    textAlign: TextAlign.center),
              ],
            ),
          ),
          confirmLabel: '重新采集',
          cancelLabel: '跳过',
          showCancel: true,
          onConfirm: () async {
            await onFaceEntryClicked();
            Get.back();
          },
          onCanceled: () {
            Get.back();
          },
        ));
      } else {
        await Get.dialog(VAlertDialog(
          contentPadding: const EdgeInsets.fromLTRB(20, 1, 20, 1),
          title: '提示',
          content: Container(
            margin: const EdgeInsets.only(bottom: 20),
            child: const Text(
              '请采集人像，完成后可以使用人脸识别功能',
              style: TextStyle(fontSize: 20),
              textAlign: TextAlign.center,
            ),
          ),
          confirmLabel: '采集',
          cancelLabel: '暂不采集',
          showCancel: true,
          onConfirm: () async {
            await onFaceEntryClicked();
            Get.back();
          },
          onCanceled: () {
            Get.back();
          },
        ));
      }
    }
  }

  Future<DeviceModel?> getDevice(String type) async {
    List<DeviceModel> devices = await _deviceManager.getDeviceList();

    return devices.firstWhereOrNull((element) => element.type == type);
  }

  /// 点击读卡事件
  void onReadCardClicked() async {
    final DeviceModel? device = await getDevice(DeviceTypes.IC_READER);
    CardReaderResult? result;
    if (device != null) {
      final envPassed = await checkDeviceConnectEnv();
      if (envPassed) {
        result = await Get.dialog<CardReaderResult>(
          const BluetoothCardReaderDialog(),
          barrierDismissible: false,
        );
      }
    } else {
      result = await Get.dialog<CardReaderResult>(
        const CardReaderDialog(),
        barrierDismissible: false,
      );
    }

    if (result != null && result.success) {
      PromptBox.toast("读取成功");
      state.cardNo = result.cardNo; // 回填身份证号
      state.name = result.name; // 回填姓名
      state.gender = result.gender; // 回填性别
      state.nation = result.nation; // 回填民族
      state.birthday = result.birthday; // 回填出生日期
      state.censusRegister = result.address; // 回填户籍地址
      if (state.isSyncAddresses) {
        state.address = result.address; // 回填现住地址
      }
    } else {
      print("读卡取消");
    }
  }

  /// 点击读卡事件 （若已建档跳详情页面 若未建档跳创建页面）
  void onReadCardClickedToDetail() async {
    final DeviceModel? device = await getDevice(DeviceTypes.IC_READER);
    CardReaderResult? result;
    if (device != null) {
      final envPassed = await checkDeviceConnectEnv();
      if (envPassed) {
        result = await Get.dialog<CardReaderResult>(
          const BluetoothCardReaderDialog(),
          barrierDismissible: false,
        );
      }
    } else {
      result = await Get.dialog<CardReaderResult>(
        const CardReaderDialog(),
        barrierDismissible: false,
      );
    }

    if (result != null && result.success) {
      PromptBox.toast("读取成功");
      PatientBaseDTO patientInfo = PatientBaseDTO();
      patientInfo.cardNo = result.cardNo; // 回填身份证号
      patientInfo.patientName = result.name; // 回填姓名
      patientInfo.patientGender = result.gender; // 回填性别
      patientInfo.nationality = result.nation; // 回填民族
      patientInfo.birthday = result.birthday; // 回填出生日期
      patientInfo.patientAddress = result.address; // 回填户籍地址
      onIdcardInfoIsCreateRecord(patientInfo.cardNo!, patientInfo);
    } else {
      print("读卡取消");
    }
  }

  /// 点击身份识别建档（拍摄扫描身份证）
  void onIdCardScanClicked() async {
    var verifyResult = await _verifyCameraPermissions();
    if (!verifyResult) {
      return;
    }
    final IdCardScanResult? result = await Get.to<IdCardScanResult>(
      () => const IdCardScanPage(),
    );
    if (result != null && result.success) {
      PromptBox.toast("身份证信息识别成功");
      PatientBaseDTO patientInfo = result.patientBaseDTO;
      patientInfoParse(patientInfo);
    } else {
      print("识别取消");
    }
  }

  /// 点击身份识别（拍摄扫描身份证）
  void onIdCardScanClickedToDetail() async {
    var verifyResult = await _verifyCameraPermissions();
    if (!verifyResult) {
      return;
    }
    final IdCardScanResult? result = await Get.to<IdCardScanResult>(
      () => const IdCardScanPage(),
    );
    if (result != null && result.success) {
      PromptBox.toast("身份证信息识别成功");
      PatientBaseDTO patientInfo = result.patientBaseDTO;
      onIdcardInfoIsCreateRecord(patientInfo.cardNo!, patientInfo);
    } else {
      print("识别取消");
    }
  }

  void patientInfoParse(PatientBaseDTO patientInfo) {
    state.cardNo = patientInfo.cardNo ?? ""; // 回填身份证号
    state.name = patientInfo.patientName ?? ""; // 回填姓名
    state.gender = patientInfo.patientGender; // 回填性别
    state.nation = patientInfo.nationality ?? ""; // 回填民族
    state.birthday = patientInfo.birthday; // 回填出生日期
    state.censusRegister = patientInfo.patientAddress ?? ""; // 回填户籍地址
    if (state.isSyncAddresses) {
      state.address = patientInfo.patientAddress ?? ""; // 回填现住地址
    }
  }

  Future<bool> _verifyCameraPermissions() async {
    IPermissionManager permissionManager = Get.find<IPermissionManager>();
    var isCameraPermissions =
        await permissionManager.requestCameraPermissions();
    if (!isCameraPermissions) {
      await Get.dialog(
        VAlertDialog(
          title: "提示",
          width: 420,
          content: Container(
            height: 32,
            padding: const EdgeInsets.symmetric(horizontal: 24),
            alignment: Alignment.center,
            child: const Text(
              "未授予相机权限,前去设置",
              style: TextStyle(fontSize: 20),
            ),
          ),
          showCancel: false,
          onConfirm: () async {
            Get.back();
            await permissionManager.openAppSettingsAsync();
          },
        ),
        barrierDismissible: false,
        barrierColor: Colors.black.withOpacity(.4),
      );
    }
    return isCameraPermissions;
  }

  /// 点击人脸识别
  void onFaceIdLoginClicked() async {
    var verifyResult = await _verifyCameraPermissions();
    if (!verifyResult) {
      return;
    }
    final FaceRecognitionResult? result = await Get.to<FaceRecognitionResult>(
      () => const FacialRecognitionPage(
        mode: FacialRecognitionMode.faceRecognition,
      ),
    );
    if (result != null && result.success) {
      final patient = result.patientInfo;
      final hasConfirmed = await FaceResultDialog.show(patient, true);
      if (hasConfirmed) {
        await _checkinPatient(patient);
      }
    } else {
      print("识别取消");
    }
  }

  void onIdcardInfoIsCreateRecord(
    String cardNo, [
    PatientBaseDTO? patientInfo,
  ]) async {
    PatientDTO? patientInfoDto = await _patientManager.getDetail(cardNo);
    if (patientInfoDto != null) {
      Store.user.currentSelectPatientInfo = patientInfoDto;
    }
    if (patientInfo != null) {
      final hasConfirmed =
          await FaceResultDialog.show(patientInfo, patientInfoDto != null);

      if (hasConfirmed) {
        if (patientInfoDto != null) {
          await Get.find<PatientListController>()
              .gotoDetail(patientInfo.cardNo!, patientInfoDto, patientInfo);
        } else {
          await Get.find<PatientListController>().gotoCreate(
            patientInfo.cardNo!,
            patientInfoDto,
            patientInfo,
          );
        }
      }
    }
  }

  /// 点击录入人脸
  Future<void> onFaceEntryClicked() async {
    final PatientDTO patientInfo = PatientDTO(
      patientName: state.name,
      phone: state.phoneNo,
      cardNo: state.cardNo,
      nationality: state.nation,
      birthday: state.birthday,
      cardType: state.cardType,
      patientGender: state.gender!,
      code: state.cardNo,
    );
    bool? result = await Get.to<bool>(
      () => FacialRecognitionPage(
        mode: FacialRecognitionMode.faceInput,
        patientInfo: patientInfo,
      ),
    );
    if (result != null && result) {
      PromptBox.toast('人脸数据存入成功');
    }
  }

  /// 处理 “同户籍地址” 勾选变更事件
  void onSyncAddressCheckChanged(bool isChecked) {
    state.isSyncAddresses = isChecked;
    if (isChecked) {
      // 同步户籍地址到现住地址
      state.address = state.censusRegister;
    } else {
      state.address = "";
    }
  }

  /// 处理户籍地址变更
  void onCensusRegisterChanged(String value) {
    state.censusRegister = value;
    if (state.isSyncAddresses) {
      state.address = value;
    }
  }

  Future<String> getPatientPhoto(String patientCode) async {
    final dto = await _patientManager.getDetail(patientCode);
    if (dto != null && dto.photos != null && dto.photos!.isNotEmpty) {
      return dto.photos![0];
    }
    return "";
  }

  Future<String?> _submitForm() async {
    setBusy("正在保存...");

    final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
    final request = CreatePatientRequest(
      patientName: state.name,
      phone: state.phoneNo,
      patientGender: state.gender!,
      nationality: state.nation,
      birthday: state.birthday?.toUtc(),
      cardType: state.cardType,
      cardNo: state.cardNo,
      patientAddress: state.address,
      permanentResidenceAddress: state.censusRegister,
      crowdLabels: crowdLabelCodes,
    );
    final result = await _patientManager.create(request);
    return result;
  }

  bool validateIDCard(String idCard) {
    // 校验身份证号码长度
    if (idCard.length != 18) {
      return false;
    }

    // 校验前17位是否为数字
    String idCard17 = idCard.substring(0, 17);
    if (!isNumeric(idCard17)) {
      return false;
    }

    // 校验最后一位校验码
    String checkCode = getCheckCode(idCard17);
    if (idCard[17].toUpperCase() != checkCode) {
      print("checkCode: $checkCode");
      return false;
    }

    return true;
  }

  bool isNumeric(String str) {
    if (str.isEmpty) {
      return false;
    }
    return double.tryParse(str) != null;
  }

  bool isAlphaNumeric(String str) {
    final RegExp alphaNumericRegExp = RegExp(r'^[a-zA-Z0-9]+$');
    return alphaNumericRegExp.hasMatch(str);
  }

  bool isAlphaNumericChineseWithSpace(String str) {
    final RegExp alphaNumericChineseWithSpaceRegExp =
        RegExp(r'^[a-zA-Z0-9\u4e00-\u9fa5\s]+$');
    return alphaNumericChineseWithSpaceRegExp.hasMatch(str);
  }

  String getCheckCode(String idCard17) {
    List<int> coefficients = [
      7,
      9,
      10,
      5,
      8,
      4,
      2,
      1,
      6,
      3,
      7,
      9,
      10,
      5,
      8,
      4,
      2
    ];
    List<String> checkCodes = [
      '1',
      '0',
      'X',
      '9',
      '8',
      '7',
      '6',
      '5',
      '4',
      '3',
      '2'
    ];

    int sum = 0;
    for (int i = 0; i < idCard17.length; i++) {
      int digit = int.parse(idCard17[i]);
      sum += digit * coefficients[i];
    }

    int remainder = sum % 11;
    return checkCodes[remainder];
  }

  Future<String?> _validateForm() async {
    if (state.name.isEmpty) {
      return "请填写姓名";
    }
    // else {
    //   if (!isAlphaNumericChineseWithSpace(state.name) ||
    //       state.name.length >= 20) {
    //     return "姓名只能由中文、字母或数字组成，并且小于20个字符";
    //   }
    // }
    if (state.cardNo.isEmpty) {
      return "请填写证件号";
    }

    if (state.phoneNo.isNotEmpty) {
      if (state.phoneNo.length != 11 || !isNumeric(state.phoneNo)) {
        return "请填写正确的手机号";
      }
    }
    if (state.cardType == CardTypeEnum.Identity) {
      bool isNotIDCard = validateIDCard(state.cardNo);
      if (!isNotIDCard) {
        return "请填写正确的证件号";
      }
    }

    if (state.cardType == CardTypeEnum.SocialInsurance) {
      if (state.cardNo.length != 18 || !isNumeric(state.cardNo)) {
        return "请填写正确的社保号";
      }
    }

    if (state.cardType == CardTypeEnum.Passport) {
      if (state.cardNo.length != 9 || !isAlphaNumeric(state.cardNo)) {
        return "请填写正确的护照号";
      }
    }

    if (state.gender == null) {
      return "请选择性别";
    }

    /// TODO 需求变更暂时删除
    // final selectedNormalCodes = crowdLabelsController.state.selectedNormalCodes;

    // if (selectedNormalCodes.length > 1) {
    //   return "人群分类：一般人群、儿童、孕妇、老年人，只可选择其一！";
    // }
    // final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
    // if (crowdLabelCodes.isEmpty) {
    //   return "请选择人群分类";
    // }
    // if (state.gender == GenderEnum.Male &&
    //     crowdLabelCodes.contains('RQFL_YF')) {
    //   return "当前居民性别为“男”，人群分类不可选择孕妇！";
    // }
    return null;
  }

  /// 切换当前登记居民
  Future<void> _checkinPatient(PatientBaseDTO patient) async {
    final patientDTO = PatientDTO(
      code: patient.cardNo,
      cardNo: patient.cardNo,
      patientName: patient.patientName,
      nationality: patient.nationality,
      patientGender: patient.patientGender,
      birthday: patient.birthday,
      patientAddress: patient.patientAddress,
    );
    Store.user.currentSelectPatientInfo = patientDTO;
    logger.i(
        'create居民 当前居民是：${patientDTO.patientName} 居民code：${patientDTO.code}');
    onIdcardInfoIsCreateRecord(patientDTO.code!);
    await Get.find<PatientListController>().gotoDetail(
      patient.cardNo!,
    );
  }

  Future<void> setGender(String cardNo) async {
    if (cardNo.isNotEmpty && cardNo.length > 17) {
      var sexNum = cardNo.substring(16, 17);
      if (sexNum.isNotEmpty && RegExp(r'^\d+$').hasMatch(sexNum)) {
        if (int.parse(sexNum) % 2 == 1) {
          state.gender = GenderEnum.Male;
        } else {
          state.gender = GenderEnum.Female;
        }
      } else {
        state.gender = GenderEnum.Unknown;
      }
    }
  }
}
