import 'package:eitc_erm_dental_flutter/db_util.dart';
import 'package:eitc_erm_dental_flutter/entity/db/local_patient_info.dart';
import 'package:eitc_erm_dental_flutter/entity/dict_info.dart';
import 'package:eitc_erm_dental_flutter/entity/patient_info.dart';
import 'package:eitc_erm_dental_flutter/exts.dart';
import 'package:eitc_erm_dental_flutter/funcs.dart';
import 'package:eitc_erm_dental_flutter/global.dart';
import 'package:eitc_erm_dental_flutter/http/api_exception.dart';
import 'package:eitc_erm_dental_flutter/http/api_service.dart';
import 'package:eitc_erm_dental_flutter/http/http.dart';
import 'package:eitc_erm_dental_flutter/sp_util.dart';
import 'package:flutter/foundation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'patient_view_model.g.dart';

///本地咨询人列表
@riverpod
class LocalPatientList extends _$LocalPatientList {
  @override
  FutureOr<List<LocalPatientInfo>> build() async {
    //未登录
    if (!hasToken) {
      return SynchronousFuture([]);
    }
    return DbUtil.instance.getLocalPatientList();
  }

  ///同步咨询人列表
  ///
  /// [list] 用来同步的服务器咨询人列表,如果为空就会先从服务器读取列表
  void syncPatientList([List<PatientInfo>? list]) async {
    //未登录
    if (!hasToken) {
      return;
    }
    state = AsyncLoading();
    try {
      //服务器列表
      List<PatientInfo> serverList;
      //如果list为空就从服务器读取
      list ??= await _getPaitienInfoList();
      //如果list仍然为空,表示从服务器获取列表出了异常,就返回
      if (list == null) {
        ref.invalidateSelf();
        return;
      }
      serverList = list;
      List<LocalPatientInfo> localList =
          await DbUtil.instance.getLocalPatientList();
      //服务器列表为空
      if (serverList.isEmpty) {
        logd("同步咨询人列表,服务器列表为空");
        await DbUtil.instance.deleteAllLocalPatients();
        setSelectedPatientId(-1);
        ref.invalidateSelf();
        return;
      }

      //转换服务器列表到本地列表方法
      Future<List<LocalPatientInfo>> convertList(
          List<PatientInfo> toConvert) async {
        String userId = await SpUtil.getUserId();
        return toConvert
            .map((info) => LocalPatientInfo(
                name: info.patientName,
                //加密身份证
                idCard: aesEncrypt(info.identificationCard ?? ""),
                relation: info.relationship,
                userId: userId,
                namePic: info.patientNamePic,
                serverId: info.appUserPatientsId))
            .toList();
      }

      //本地列表为空
      if (localList.isEmpty) {
        logd("同步咨询人列表,本地列表为空");
        List<int> ids = await DbUtil.instance
            .putLocalPatients(await convertList(serverList));
        setSelectedPatientId(ids.first);
        ref.invalidateSelf();
        return;
      }
      //同步服务器列表和本地列表
      //本地已选择的咨询人信息
      LocalPatientInfo? selectedInfo =
          localList.where((info) => info.id == selectedPatientId).firstOrNull;
      //服务器列表转换为本地列表
      List<LocalPatientInfo> newList = await convertList(serverList);
      int index = -1;
      //如果已选择的信息不为空,则找到新本地列表里相同数据的信息的索引
      if (selectedInfo != null) {
        logd("同步咨询人列表,存在已选择的咨询人信息");
        index = newList
            .indexWhere((info) => info.serverId == selectedInfo.serverId);
      }
      //删除所有的本地数据
      await DbUtil.instance.deleteAllLocalPatients();
      //把服务器数据保存到本地
      List<int> ids = await DbUtil.instance.putLocalPatients(newList);
      //检查已选择的信息的ID并更新
      int id = (index >= 0 && index < ids.length) ? ids[index] : -1;
      setSelectedPatientId(id);

      ref.invalidateSelf();
    } catch (e) {
      //记录日志,不设置为error状态
      loge("同步咨询人数据异常", error: e, stackTrace: StackTrace.current);
      ref.invalidateSelf();
    }
  }
}

///咨询人列表
@riverpod
class PatientList extends _$PatientList {
  @override
  FutureOr<List<PatientInfo>> build() async {
    try {
      return await _getPaitienInfoList() ?? [];
    } catch (e) {
      throw ApiException.from(e);
    }
  }

  ///添加咨询人
  Future<String?> addPatient(
      String name, String idCard, String relation) async {
    try {
      await Http.instance.request(
          ApiService(Http.instance.dio).addPatient(name, idCard, relation));
    } catch (e) {
      loge("增加咨询人异常", error: e);
      return ApiException.from(e).message;
    }
    return null;
  }
}

///获取咨询人列表
Future<List<PatientInfo>?> _getPaitienInfoList() async {
  try {
    List<PatientInfo>? list = await Http.instance
        .request(ApiService(Http.instance.dio).getPatientList());
    return list;
  } catch (e) {
    loge("读取咨询人列表异常", error: e);
  }
  return null;
}

///咨询人关系列表
@riverpod
Future<List<String>> patientRelationList(PatientRelationListRef ref) async {
  try {
    List<DictInfo>? list = await Http.instance.request(
        ApiService(Http.instance.dio).dictList("erm_personal_relationship"));
    if (list.isNullOrEmpty) {
      return [];
    }
    return list!
        .where((info) => !info.dictValue.isNullOrEmpty)
        .map((info) => info.dictValue!)
        .toList();
  } catch (e) {
    loge("获取咨询人关系列表异常", error: e);
  }
  return [];
}
