import 'package:date_format/date_format.dart';
import 'package:fis_common/extensions/string.dart';
import 'package:fis_common/helpers/encrypt.dart';
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:flutter/material.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/services/modules/patient_configurations.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/entities/patient_Info.dart';
import 'package:flyinsono/pages/remedical/consultation/controller.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';

import 'index.dart';
import 'widgets/date_time.dart';

///增加或编辑病人信息对话框控制器
class AddoreditPatientDialogController extends GetxController {
  //状态
  final state = AddoreditPatientDialogState();
  final _controllers = Map<String, TextEditingController>();
  // 病人改查 配置项表单
  final patientCheck = Get.find<PatientCheckService>();
  AddoreditPatientDialogController() {
    state.isEditStatus = false;
  }

  PatientInfoBaseDTO patient = PatientInfoBaseDTO();
  Map<String, dynamic> patientInfo = {};

  /// 处理隐私保护
  Map<String, dynamic> editPatientInfo = {};
  String patientCode = "";
  ConsultationController consultation = Get.find<ConsultationController>();
  List patientKeyList = [];

  ///跟据不同Key值获取TextEditingController
  TextEditingController getControllerByKey(String key, {String value = ''}) {
    if (_controllers.containsKey(key)) {
      if (value.isNotEmpty) {
        _controllers[key]!.text = value;
      }
      return _controllers[key]!;
    } else {
      _controllers[key] = TextEditingController(text: value);
      return _controllers[key]!;
    }
  }

  /// 校验身份证规则
  bool validateIdNumber(String? id) {
    if (id == null || id.isEmpty) {
      return false;
    }

    // 校验位加权因子
    final List<int> weightFactor = [
      7,
      9,
      10,
      5,
      8,
      4,
      2,
      1,
      6,
      3,
      7,
      9,
      10,
      5,
      8,
      4,
      2
    ];

    // 校验位映射表
    final List<String> checkCodeMap = [
      '1',
      '0',
      'X',
      '9',
      '8',
      '7',
      '6',
      '5',
      '4',
      '3',
      '2'
    ];

    // 验证长度和格式
    if (id.length != 18 || !RegExp(r'^\d{17}[\dxX]$').hasMatch(id)) {
      return false;
    }

    // 验证出生日期
    final int year = int.parse(id.substring(6, 10));
    final int month = int.parse(id.substring(10, 12));
    final int day = int.parse(id.substring(12, 14));
    if (!DateTime.tryParse(
            '$year-${month < 10 ? '0$month' : month}-${day < 10 ? '0$day' : day}T00:00:00')!
        .isAfter(DateTime(1900, 1, 1))) {
      return false;
    }

    // 计算校验位
    int sum = 0;
    for (int i = 0; i < 17; i++) {
      sum += int.parse(id[i]) * weightFactor[i];
    }
    final int mod = sum % 11;
    final String checkCode = checkCodeMap[mod];

    // 验证校验位
    return checkCode.toUpperCase() == id[17].toUpperCase();
  }

  ///身份证号变化，更新年龄
  void onIdCardChange(String id) {
    try {
      var birth = id.substring(6, 14);
      var data = DateTime.tryParse(birth);
      if (data == null) {
        logger.e(
            'AddoreditPatientDialogController onIdCardChange error,can not convert:' +
                id);
        return;
      }
      final fmtedDuration = Get.find<FmtedDuration>();
      var birthday = formatDate(data, ['yyyy', '-', 'mm', '-', 'dd']);
      _controllers['Birthday']!.text = birthday;
      patientInfo["Birthday"] = birthday;
      editPatientInfo["Birthday"] = birthday;
      fmtedDuration.isChangeTime = !fmtedDuration.isChangeTime;
    } catch (e) {
      logger.e('AddoreditPatientDialogController onIdCardChange ex', e);
    }
  }

  ///清理缓存controllers
  void clearControllers() {
    _controllers.clear();
  }

  /// 新增病人信息
  Future<bool> createPatient() async {
    try {
      List<DataItemDTO> list = [];
      bool isPerson =
          consultation.state.patientType == OrganizationPatientTypeEnum.Person;

      ///先判断key值是否存在 输入框判断
      if (isPerson) {
        if (!patientInfo.containsKey('Name') ||
            !patientInfo.containsKey('Phone')) {
          PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
          return false;
        }
        if (patientInfo['Name'].toString().isNullOrWhiteSpace ||
            patientInfo['Phone'].toString().isNullOrWhiteSpace) {
          PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
          return false;
        }
        if (patientInfo['Phone'].toString().length != 11 ||
            !patientInfo['Phone'].toString().isPhoneNumber) {
          PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
          return false;
        }
      } else {
        if (!patientInfo.containsKey('AnimalInfoName') ||
            !patientInfo.containsKey('AnimalInfoPhone')) {
          PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
          return false;
        }
        if (patientInfo['AnimalInfoName'].toString().isNullOrWhiteSpace ||
            patientInfo['AnimalInfoPhone'].toString().isNullOrWhiteSpace) {
          PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
          return false;
        }
        if (patientInfo['AnimalInfoPhone'].toString().length != 11 ||
            !patientInfo['AnimalInfoPhone'].toString().isPhoneNumber) {
          PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
          return false;
        }
      }

      patientInfo.forEach((key, value) {
        if (key == 'Phone' ||
            key == 'Name' ||
            key == 'IdentityCard' ||
            key == 'InsuranceCode' ||
            key == 'AnimalInfoName' ||
            key == 'AnimalInfoPhone' ||
            key == 'AnimalInfoIdentityCard') {
          value = FEncryptHelper.encodeBase64(value);
        }

        if (value != null) {
          list.add(DataItemDTO(
            key: key,
            value: value.toString(),
          ));
        }
      });

      consultation.state.currentNewlyCreatedPatient = null;
      final createPatient = await rpc.patient.createPatientAsync(
        CreatePatientRequest(
          token: Store.user.token,
          patientData: list,
        ),
      );
      if (createPatient.isNotNullOrEmpty) {
        PromptBox.toast(i18nBook.remedical.createSuccess.t);
        consultation.state.currentNewlyCreatedPatient = createPatient;
        return true;
      } else {
        PromptBox.toast('$createPatient');
      }
    } catch (e) {
      printError(info: "createPatient exception:" + e.toString());
      logger.e("createPatient exception:", e);
    }
    return false;
  }

  /// 编辑病人信息
  Future<bool> editPatient() async {
    bool isPerson =
        consultation.state.patientType == OrganizationPatientTypeEnum.Person;

    ///先判断key值是否存在
    if (isPerson) {
      if (!patientInfo.containsKey('Name') ||
          !patientInfo.containsKey('Phone')) {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
        return false;
      }
      if (patientInfo['Name'].toString().isNullOrWhiteSpace ||
          patientInfo['Phone'].toString().isNullOrWhiteSpace) {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
        return false;
      }

      /// 编辑的手机号校验
      if (editPatientInfo['Phone'] != null) {
        if (editPatientInfo['Phone'].toString().length != 11 ||
            !editPatientInfo['Phone'].toString().isPhoneNumber) {
          PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
          return false;
        }
      }
    } else {
      if (!patientInfo.containsKey('AnimalInfoName') ||
          !patientInfo.containsKey('AnimalInfoPhone')) {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
        return false;
      }
      if (patientInfo['AnimalInfoName'].toString().isNullOrWhiteSpace ||
          patientInfo['AnimalInfoPhone'].toString().isNullOrWhiteSpace) {
        PromptBox.toast(i18nBook.user.requiredFieldsCannotBeEmpty.t);
        return false;
      }

      /// 编辑的手机号校验
      if (editPatientInfo['AnimalInfoPhone'] != null) {
        if (editPatientInfo['AnimalInfoPhone'].toString().length != 11 ||
            !editPatientInfo['AnimalInfoPhone'].toString().isPhoneNumber) {
          PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
          return false;
        }
      }
    }
    List<DataItemDTO> list = [];

    editPatientInfo.forEach((key, value) {
      if (key == 'Phone' ||
          key == 'Name' ||
          key == 'IdentityCard' ||
          key == 'InsuranceCode' ||
          key == 'AnimalInfoName' ||
          key == 'AnimalInfoPhone' ||
          key == 'AnimalInfoIdentityCard') {
        value = FEncryptHelper.encodeBase64(value);
      }
      if (value != null) {
        list.add(DataItemDTO(
          key: key,
          value: value,
        ));
      }
    });

    try {
      final updetePatient = await rpc.patient.updatePatientAsync(
        UpdatePatientRequest(
          token: Store.user.token,
          code: patientCode,
          patientData: list,
          assignmentUserCodes: [],
        ),
      );
      if (updetePatient) {
        PromptBox.toast(i18nBook.remedical.editSuccess.t);
        return true;
      } else {
        PromptBox.toast('$updetePatient');
      }
    } catch (e) {
      logger.e("editPatient exception:", e);
      return false;
    }
    return false;
  }

  /// 保存病人信息
  Future<void> savePatient() async {
    bool result;
    if (state.isEditStatus) {
      result = await editPatient();
      if (result) {
        cancelPatient();
      }
    }
  }

  /// 取消编辑或新增的病人信息
  void cancelPatient([isClose = true]) {
    patientInfo = {};
    state.isEditStatus = false;
    if (isClose) Get.back();
  }

  /// 病人详细信息初始化数据
  ///
  /// [patientId] 病人编码
  void initPatientInfosData(String patientCode) {
    this.patientCode = patientCode;
    var patientInfos = consultation.state.patientInfo;
    consultation.state.patientType == OrganizationPatientTypeEnum.Person
        ? patientInfo = {
            'Name': patientInfos.name,
            'Phone': patientInfos.phone,
            'IdentityCard': patientInfos.identityCard,
            'InsuranceCode': patientInfos.insuranceCode,
            'Age': patientInfos.age,
            'Sex': patientInfos.sex == '' ? null : patientInfos.sex,
            'HeadImgUrl':
                patientInfos.headImgUrl == '' ? null : patientInfos.headImgUrl,
            'Birthday': patientInfos.birthday ?? '',
            'AgeUnits': patientInfos.ageUnits,
            'AgeDay': patientInfos.ageDay,
            'AgeWeek': patientInfos.ageWeek,
            'AgeMonth': patientInfos.ageMonth,
            'AgeYear': patientInfos.ageYear,
          }
        : patientInfo = {
            'AnimalInfoName': patientInfos.name,
            'AnimalInfoPhone': patientInfos.phone,
            'AnimalInfoIdentityCard': patientInfos.identityCard,
            'AnimalInfoInsuranceCode': patientInfos.insuranceCode,
            'AnimalInfoAge': patientInfos.age,
            'AnimalInfoSex': patientInfos.sex == '' ? null : patientInfos.sex,
            'Species': patientInfos.species == '' ? null : patientInfos.species,
            'Breed': patientInfos.breed,
            'AnimalInfoHeadImgUrl':
                patientInfos.headImgUrl == '' ? null : patientInfos.headImgUrl,
            'AgeUnits': patientInfos.ageUnits,
            'AgeDay': patientInfos.ageDay,
            'AgeWeek': patientInfos.ageWeek,
            'AgeMonth': patientInfos.ageMonth,
            'AgeYear': patientInfos.ageYear,
          };
  }

  /// 编辑弹框
  void openEditInit(String patientId) async {
    try {
      initPatientInfosData(patientId);
      final gender = 1;
      state.groupValue = gender == 0
          ? "NotFilled"
          : gender == 1
              ? "Male"
              : "Female";
      state.isEditStatus = true;
      if (kIsMobile) {
        await router.to(MobileRouteNames.Remedical.AddOrEditPatirntDiaLog);
      } else {
        await router.dialog(() => AddoreditPatientDialogPage());
      }
    } catch (e) {
      logger.e("openEditInit exception:", e);
      printError(info: e.toString());
    }
  }

  ///接收病人数据
  List acceptPatientJson(Map<String, dynamic> map) {
    var list = [];
    map.forEach((key, value) {
      if (value != null) {
        if (key == 'HeadImgUrl' || key == 'AnimalInfoHeadImgUrl') {
        } else {
          value['key'] = key;
          list.add(value);
        }
      }
    });
    return list;
  }

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    patientKeyList = acceptPatientJson(patientCheck.getChectList());
  }

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

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

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