import 'dart:convert';
import 'dart:io';

import 'package:fis_jsonrpc/rpc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:uuid/uuid.dart';
import 'package:vitalapp/architecture/storage/storage.dart';
import 'package:vitalapp/architecture/utils/prompt_box.dart';
import 'package:vitalapp/architecture/utils/upload.dart';
import 'package:vitalapp/components/alert_dialog.dart';
import 'package:vitalapp/database/entities/defines.dart';
import 'package:vitalapp/database/entities/diagnosis.dart';
import 'package:vitalapp/global.dart';
import 'package:vitalapp/managers/interfaces/record_data_cache.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vnote_device_plugin/consts/types.dart';
import 'package:vitalapp/architecture/defines.dart';
import 'package:vitalapp/architecture/storage/text_storage.dart';
import 'package:vitalapp/managers/interfaces/cachedRecord.dart';
import 'package:vitalapp/managers/interfaces/device.dart';
import 'package:vitalapp/managers/interfaces/diagnosis.dart';
import 'package:vitalapp/managers/interfaces/models/device.dart';
import 'package:vitalapp/pages/medical/models/item.dart';
import 'package:vitalapp/pages/medical/state.dart';
import 'package:vitalapp/store/store.dart';
import 'package:vnote_device_plugin/events/event_type.dart';
import 'package:fis_common/logger/logger.dart';

class MedicalController extends FControllerBase {
  String patientCode = '';
  Map<String, dynamic> diagnosisDataValue = {};

  String appDataId = "";
  final state = MedicalState();
  final recordDataCacheManager = Get.find<IRecordDataCacheManager>();
  static final typeConvertMap = <String, String>{
    DeviceTypes.TEMP: "Temp",
    DeviceTypes.WEIGHT: "BMI",
    DeviceTypes.SPO2: "SpO2",
    DeviceTypes.NIBP: "NIBP",
    DeviceTypes.SUGAR: "GLU",
    DeviceTypes.URINE: "Urine",
    DeviceTypes.IC_READER: "ICReader",
    DeviceTypes.HEART: "HEART",
  };

  final changePatient = FEventHandler<String>();
  final _diagnosisManager = Get.find<IDiagnosisManager>();
  final _cachedRecordManager = Get.find<ICachedRecordManager>();
  final _deviceManager = Get.find<IDeviceManager>();
  final _medicalMenus = [
    MedicalItem(key: DeviceTypes.TEMP, diagnosticItem: '体温'),
    MedicalItem(key: DeviceTypes.SUGAR, diagnosticItem: '血糖'),
    MedicalItem(key: DeviceTypes.NIBP, diagnosticItem: '血压'),
    MedicalItem(key: DeviceTypes.SPO2, diagnosticItem: '血氧'),
    MedicalItem(key: DeviceTypes.WEIGHT, diagnosticItem: 'BMI'),
    MedicalItem(key: DeviceTypes.URINE, diagnosticItem: '尿常规'),
    MedicalItem(key: DeviceTypes.HEART, diagnosticItem: '心电'),
  ];
  @override
  void onReady() {
    initData();
    getAccessTypes();
    super.onReady();
  }

  Future<void> initData() async {
    patientCode = Store.user.currentSelectPatientInfo?.code ?? '';
    if (patientCode.isNotEmpty) {
      var cachedAppDataId = await readCachedAppDataId();
      if (cachedAppDataId != null) {
        appDataId = cachedAppDataId;
      } else {
        await saveCachedAppDataId();
      }
      await initReadCached();
    }
  }

  Future<void> getAccessTypes() async {
    List<MedicalItem> medicalItemList = [];
    List<String> accessTypes = await _deviceManager.getAccessTypes();
    for (var element in _medicalMenus) {
      if (accessTypes.contains(element.key)) {
        medicalItemList.add(element);
      }
    }
    state.medicalMenuList = medicalItemList;
  }

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

  Future<void> initReadCached() async {
    if (patientCode.isNotEmpty) {
      TextStorage cachedRecord = TextStorage(
        fileName: 'JKJC',
        directory: "patient/$patientCode",
      );
      String? value = await cachedRecord.read();
      if (value == null) {
        diagnosisDataValue = {};
        Store.resident.handleSaveMedicalData(jsonEncode(diagnosisDataValue));
        return;
      }
      Store.resident.handleSaveMedicalData(value);
      diagnosisDataValue = jsonDecode(value);
    }
  }

  Future<void> readCachedRecord() async {
    if (patientCode.isNotEmpty) {
      // TextStorage cachedRecord = TextStorage(
      //   fileName: 'JKJC',
      //   directory: "patient/$patientCode",
      // );
      String? value = Store.resident.residentMedicalData;
      print('🍖');
      print(value);
      print('🍖');
      if (value == null) {
        diagnosisDataValue = {};
        return;
      }
      diagnosisDataValue = jsonDecode(value);
    }
  }

  Future<bool?> saveCachedAppDataId() async {
    appDataId = const Uuid().v4().replaceAll('-', '');
    TextStorage cachedRecord = TextStorage(
      fileName: 'appDataId',
      directory: "patient/$patientCode",
    );
    Get.back();
    return cachedRecord.save(appDataId);
  }

  Future<String?> readCachedAppDataId() async {
    TextStorage cachedRecord = TextStorage(
      fileName: 'appDataId',
      directory: "patient/$patientCode",
    );
    return cachedRecord.read();
  }

  Future<bool?> saveCachedRecord() async {
    Store.resident.handleSaveMedicalData(jsonEncode(diagnosisDataValue));
    TextStorage cachedRecord = TextStorage(
      fileName: 'JKJC',
      directory: "patient/$patientCode",
    );
    return cachedRecord.save(jsonEncode(diagnosisDataValue));
  }

  Future<bool?> deleteDirectory() async {
    TextStorage cachedRecord = TextStorage(
      fileName: 'JKJC',
      directory: "patient/$patientCode",
    );
    return cachedRecord.deleteDirectory();
  }

  Future<void> submitDiagnosis(List<DiagnosisItem> diagnosisItems) async {
    state.currentTab = '-1';
    await recordDataCacheManager.saveRecordData(
      appDataId,
      patientCode,
      diagnosisDataValue,
    );
    if (kIsOnline) {
      SubmitDiagnosisRequest submitDiagnosisRequest = SubmitDiagnosisRequest(
        appDataId: appDataId,
        patientCode: patientCode,
        diagnosisItems: diagnosisItems,
        diagnosisTime: DateTime.now().toUtc(),
      );
      print(submitDiagnosisRequest.toJson());
      busy = true;
      final result =
          await _diagnosisManager.submitDiagnosisAsync(submitDiagnosisRequest);
      if (result) {
        await _submitHistory();
        busy = false;
        recordDataCacheManager.recordSyncStateChange(appDataId);
        PromptBox.toast('提交成功');
        await saveCachedAppDataId();

        await deleteDirectory();
        await readCachedRecord();
        Future.delayed(const Duration(milliseconds: 10), () {
          state.currentTab = state.medicalMenuList[0].key;
        });
      } else {
        PromptBox.toast('提交失败');
      }
      if (busy) {
        busy = false;
      }
    } else {
      PromptBox.toast("已缓存至本地");
      Get.back();
    }
  }

  Future<void> createDiagnosis() async {
    if (Store.user.teamName.isEmpty) {
      PromptBox.toast('未设置团队无法提交检测数据');
      return;
    }
    if (patientCode.isEmpty ||
        patientCode != Store.user.currentSelectPatientInfo?.code) {
      initData();
    }
    List<DiagnosisItem> diagnosisItems = await recordDataCacheManager
        .convertDiagnosisDataToList(diagnosisDataValue);


    if (diagnosisItems.isEmpty) {
      PromptBox.toast('不能提交空数据');
      return;
    }
    if (state.medicalMenuList.length > diagnosisDataValue.length) {
      Get.dialog(
        VAlertDialog(
          title: '提示',
          content: Container(
            margin: const EdgeInsets.only(bottom: 20),
            child: const Text(
              '当前检测项目未完成，请确定是否提交本次检测',
              style: TextStyle(fontSize: 20),
              textAlign: TextAlign.center,
            ),
          ),
          showCancel: true,
          onConfirm: () {
            submitDiagnosis(diagnosisItems);
          },
          onCanceled: () {},
        ),
      );
      return;
    }
  }

  @override
  void dispose() {
    print('MedicalController dispose');
    super.dispose();
  }

  ///提交历史记录
  Future<void> _submitHistory() async {
    var existDatas = await recordDataCacheManager.getNoSubmitRecords();
    var historyDatas = existDatas.where((element) => element.code != appDataId);
    if (historyDatas.isEmpty) {
      return;
    }

    for (DiagnosisEntity data in historyDatas) {
      try {
        Map<String, dynamic> jsonData = jsonDecode(data.dataJson);
        var diagnosisItems =
            await recordDataCacheManager.convertDiagnosisDataToList(jsonData);
        SubmitDiagnosisRequest submitDiagnosisRequest = SubmitDiagnosisRequest(
          appDataId: data.code,
          patientCode: data.patientCode,
          diagnosisItems: diagnosisItems,
          diagnosisTime: data.updateTime ?? data.createTime,
        );
        var submitResult = await _diagnosisManager
            .submitDiagnosisAsync(submitDiagnosisRequest);
        OfflineDataSyncState state;
        if (submitResult) {
          state = OfflineDataSyncState.success;
          logger.i('提交历史记录：$patientCode 成功');
        } else {
          state = OfflineDataSyncState.fail;
        }
        recordDataCacheManager.recordSyncStateChange(data.code, state: state);
      } catch (e) {
        logger.e('MedicalController _submitHistory ex:', e);
      }
    }
  }
}
