import 'dart:convert';
import 'dart:typed_data';

import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/extensions/index.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/define.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/keyboard.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/pages/organization/org_info/state.dart';
import 'package:flyinsono/pages/remedical/vocabulary_entry/controller/organization_entry_controller.dart';
import 'package:flyinsono/pages/remedical/vocabulary_entry/controller/personal_entry_controller.dart';
import 'package:flyinsono/pages/remedical/vocabulary_entry/widgets/edit_thesaurus_dialog.dart';
import 'package:flyinsono/pages/remedical/vocabulary_entry/widgets/entry_classification_dialog.dart';
import 'package:flyinsono/pages/remedical/vocabulary_entry/widgets/import_thesarus_dialog.dart';
import 'package:flyinsono/rpc.dart';
import 'package:fis_ui/widgets/tree/flutter_treeview/lib/flutter_treeview.dart';
import 'package:get/get.dart' hide Node;

import 'index.dart';

class VocabularyEntryController extends FControllerBase
    with EnterPressListenOnControllerMixin {
  /// 是否是机构
  late bool isOrg = false;

  final state = VocabularyEntryState();
  final entryCardController = ScrollController();

  ///加载完成时触发
  FEventHandler<String> onLoaded = FEventHandler();

  /// 个人词条库控制器
  late PersonalEntryController personalEntryController;

  /// 机构词条库控制器
  late OrganizationEntryController organizationEntryController;

  final searchFocusNode = FocusNode();

  final searchThesaurusItemInputFocusNode = FocusNode();
  final searchEntryInfoInputFocusNode = FocusNode();
  final serachInput = TextEditingController();

  bool _isThesaurusItemHasFocus = false;
  bool _isEntryInfoHasFocus = false;

  VocabularyEntryController() {
    personalEntryController = PersonalEntryController(this);
    organizationEntryController = OrganizationEntryController(this);
  }

  /// 下拉项点击
  void onExpansionChanged(String code, bool isDrop) async {
    state.getTreeView = getThesaurusItemsAsyncList(
      state.thesaurusItem.length != 0
          ? state.thesaurusItem
          : state.allThesaurusItem,
      code,
      isDrop,
    );
  }

  /// 词条分类的选中
  void onNodeTap(String code) {
    state.selectedKey = code;
    if (code.isEmpty) {
      state.vocabularyCard = [];
      return;
    }
    state.vocabularyCard = state.allThesaurusItem
        .where((element) => element.parentItemCode == code)
        .toList();
  }

  /// 数据处理
  ///
  /// [allThesaurusItemsAsyncList] 所有词条项
  ///
  /// [thesaurusItemCode] 当前点击的词条code
  ///
  /// [isExpanded] 是否展开
  List<Node> getThesaurusItemsAsyncList(
      List<ThesaurusItemDTO> allThesaurusItemsAsyncList,
      [String thesaurusItemCode = '',
      bool isExpanded = false]) {
    List<Node> treeView = [];
    allThesaurusItemsAsyncList.forEach(
      (element) {
        List<Node> treeviewChild = [];
        final lista = allThesaurusItemsAsyncList.where(
          (e) => e.parentItemCode == element.thesaurusItemCode,
        );
        lista.forEach((element) {
          if (element.thesaurusItemType != ThesaurusItemTypeEnum.Contents) {
            treeviewChild.add(
              Node(
                key: element.thesaurusItemCode ?? '',
                label: element.thesaurusItemName ?? '',
              ),
            );
          }
        });
        if (element.parentItemCode == '' || element.parentItemCode == null) {
          if (element.thesaurusItemCode == thesaurusItemCode) {
            treeView.add(
              Node(
                key: element.thesaurusItemCode!,
                label: element.thesaurusItemName!,
                children: treeviewChild,
                expanded: isExpanded,
              ),
            );
          } else {
            treeView.add(
              Node(
                key: element.thesaurusItemCode!,
                label: element.thesaurusItemName!,
                children: treeviewChild,
              ),
            );
          }
        }
      },
    );
    return treeView;
  }

  /// 搜索的方法
  void getEntryByKeyWords() {
    List<ThesaurusItemDTO> thesaurusItem = [];
    state.allThesaurusItem.forEach(
      (e) {
        if (e.thesaurusItemName
                    ?.toLowerCase()
                    .contains(state.keyWords.toLowerCase()) ==
                true ||
            e.thesaurusItemConclusion
                    ?.toLowerCase()
                    .contains(state.keyWords.toLowerCase()) ==
                true ||
            e.thesaurusItemDescription
                    ?.toLowerCase()
                    .contains(state.keyWords.toLowerCase()) ==
                true) {
          if (e.parentItemCode != '') {
            state.allThesaurusItem.forEach((element) {
              if (element.thesaurusItemCode == e.parentItemCode) {
                thesaurusItem.add(element);
                if (element.parentItemCode != '') {
                  state.allThesaurusItem.forEach((key) {
                    if (key.thesaurusItemCode == element.parentItemCode) {
                      thesaurusItem.add(key);
                    }
                  });
                }
              }
            });
          }
          if (e.thesaurusItemCode != '') {
            state.allThesaurusItem.forEach((element) {
              if (element.parentItemCode == e.thesaurusItemCode) {
                thesaurusItem.add(element);
              }
            });
          }
          thesaurusItem.add(e);
        }
      },
    );
    state.thesaurusItem = thesaurusItem.toSet().toList();
    state.getTreeView = getThesaurusItemsAsyncList(state.thesaurusItem);
  }

  /// 新增 编辑词条分类弹窗
  void openEntryClassifcationDialog(String? key) async {
    await getThesaurusClassifyByParentCode();
    if (key != null) {
      ThesaurusItemDTO thesaurusItemDTO =
          await getThesaurusItemByCodeAsync(key);
      state.createClassification['thesaurusItemName'] =
          thesaurusItemDTO.thesaurusItemName;
      state.createClassification['parentItemCode'] =
          thesaurusItemDTO.parentItemCode;

      /// 编辑上级词条的时候需要做层过滤去掉他自己的
      List<OrgModel> editClassification = [];
      state.classification.forEach(
        (element) {
          if (element.code != key) {
            editClassification.add(element);
            state.editClassification = editClassification;
          }
        },
      );
    }
    await router.dialog(
      () => EntryClassifcationDialog(
        thesaurusInfoKey: key,
        onOkTap: (value) => value
            ? organizationEntryController.updateThesaurusClassifyAsync(key!)
            : organizationEntryController.addThesaurusClassifyAsync(),
        onCancelTap: () => closeEntryClassifcationDialog(),
      ),
    );
  }

  /// 打开创建 编辑自定义的词条库弹窗
  void openEditThesaurusDialog(ThesaurusDTO? thesaurusInfo) async {
    if (thesaurusInfo != null) {
      state.createThesaurus['thesaurusName'] = thesaurusInfo.thesaurusName;
    } else {
      Get.back();
    }
    Future.delayed(Duration(milliseconds: 500), () async {
      await router.dialog(
        () => EditThesaurusDialog(
          onOkTap: (value) => value
              ? isOrg
                  ? organizationEntryController.addOrgThesaurusAsync()
                  : personalEntryController.addThesaurusAsync()
              : updateThesaurusAsync(thesaurusInfo),
          thesaurusInfo: thesaurusInfo,
          onCancelTap: () => personalEntryController.closeEditThesaurusDialog(),
        ),
      );
    });
  }

  /// 更新词条库
  void updateThesaurusAsync(ThesaurusDTO? thesaurusInfo) async {
    final thesaurusName = state.createThesaurus['thesaurusName'];
    if (thesaurusName == null || thesaurusName.toString().isNullOrWhiteSpace) {
      PromptBox.toast(i18nBook.remedical.thesaurusNameInputTip.t);
      return;
    }
    if (thesaurusInfo?.thesaurusName ==
        state.createThesaurus['thesaurusName']) {
      PromptBox.toast(i18nBook.remedical.toast4NotEditYet.t);
      return;
    }
    try {
      final updateThesaurusAsync = await rpc.report.updateThesaurusAsync(
        UpdateThesaurusRequest(
          thesaurusName: state.createThesaurus['thesaurusName'],
          thesaurusCode: thesaurusInfo?.thesaurusCode,
          token: Store.user.token,
        ),
      );
      if (updateThesaurusAsync && !isOrg) {
        PromptBox.toast(i18nBook.remedical.updateVocSuccess.t);
        getThesaurusPage();
        Get.back();
      } else if (updateThesaurusAsync && isOrg) {
        PromptBox.toast(i18nBook.remedical.updateVocBaseSuccess.t);
        getOrgThesaurusPageAsync();
        Get.back();
      } else {
        PromptBox.toast(i18nBook.remedical.updateFailed.t);
      }
      state.createThesaurus = <String, dynamic>{};
    } catch (e) {
      logger.e('updateThesaurusAsync', e);
    }
  }

  /// 点击词条卡片 拉取所有的词条库
  ///
  /// [index] 选中的下标
  ///
  /// [thesaurusDTO] 词条库项
  void clickEntryCard(int index, ThesaurusDTO thesaurusDTO) async {
    if (kIsMobile) {
      return personalEntryController.openEntryInfoMobilePage(
        index,
        thesaurusDTO,
      );
    }
    state.activeEntryIndex = index;
    state.thesaurusCode = thesaurusDTO.thesaurusCode!;
    state.thesaurusName = thesaurusDTO.thesaurusName!;
    state.isEnableEdit =
        thesaurusDTO.thesaurusType == ThesaurusTypeEnum.Personal ||
            (thesaurusDTO.thesaurusType == ThesaurusTypeEnum.Organization &&
                isOrg &&
                Store.user.isPrincipal);

    await getThesaurusItemsAsync();
    state.selectedKey = "";
    state.vocabularyCard = [];
  }

  /// 点击词条卡片 拉取所有的词条库
  ///
  /// [index] 选中的下标
  ///
  /// [code] 词条库编码
  void clickReportEntry(int index, String code) async {
    state.activeEntryIndex = index;
    state.thesaurusCode = code;
    await getThesaurusItemsAsync();
    state.selectedKey = "";
    state.vocabularyCard = [];
  }

  /// 关闭词条分类的弹窗及数据清空
  void closeEntryClassifcationDialog() {
    state.createClassification = <String, dynamic>{};
    state.classification = [];
    Get.back();
  }

  /// 获取所有词条数据
  Future<void> getThesaurusItemsAsync() async {
    try {
      busy = true;
      final getThesaurusItemsAsync = await rpc.report.getThesaurusItemsAsync(
        GetThesaurusItemsRequest(
          token: Store.user.token,
          thesaurusCode: state.thesaurusCode,
        ),
      );
      state.allThesaurusItem = getThesaurusItemsAsync;
      busy = false;
      state.getTreeView = getThesaurusItemsAsyncList(getThesaurusItemsAsync);
      state.thesaurusItem = [];
    } catch (e) {
      busy = false;
      logger.e('getThesaurusItemsAsync', e);
    }
  }

  /// 获取词条项详情
  Future<ThesaurusItemDTO> getThesaurusItemByCodeAsync(
      String? thesaurusItemCode) async {
    try {
      final getThesaurusItemByCodeAsync =
          await rpc.report.getThesaurusItemByCodeAsync(
        GetThesaurusItemByCodeRequest(
          thesaurusCode: state.thesaurusCode,
          token: Store.user.token,
          thesaurusItemCode: thesaurusItemCode,
        ),
      );
      return getThesaurusItemByCodeAsync;
    } catch (e) {
      logger.e('getThesaurusItemByCodeAsync', e);
      throw e;
    }
  }

  /// 获取词条分类
  Future getThesaurusClassifyByParentCode() async {
    try {
      final result = await rpc.report.getThesaurusClassifyByParentCodeAsync(
        GetThesaurusClassifyByParentCodeRequest(
          token: Store.user.token,
          thesaurusCode: state.thesaurusCode,
          parentItemCode: '',
        ),
      );
      List<Node> treeView = [];
      List<OrgModel> classification = [];
      if (result.length != 0) {
        result.forEach(
          (element) {
            classification.add(
              OrgModel(
                name: element.thesaurusItemName!,
                code: element.thesaurusItemCode!,
              ),
            );
            if (element.hasChildren) {
              treeView.add(
                Node(
                  key: element.thesaurusItemCode!,
                  label: element.thesaurusItemName!,
                  parent: true,
                ),
              );
            } else {
              treeView.add(
                Node(
                  key: element.thesaurusItemCode!,
                  label: element.thesaurusItemName!,
                ),
              );
            }
            // state.getTreeView = treeView;
          },
        );
      } else {
        state.getTreeView = [];
        classification = [];
      }
      state.classification = classification;
      state.selectedKey = "";
      state.vocabularyCard = [];
    } catch (e) {
      logger.e('getThesaurusClassifyByParentCode', e);
    }
  }

  /// 点击下拉词条项
  Future<void> thesaurusClickitem(String parentItemCode) async {
    final result = await rpc.report.getThesaurusContentByParentCodeAsync(
        GetThesaurusContentByParentCodeRequest(
      token: Store.user.token,
      thesaurusCode: state.thesaurusCode,
      parentItemCode: parentItemCode,
    ));
    state.selectedKey = parentItemCode;
    state.vocabularyCard = result;
  }

  Future<List<ThesaurusDTO>> getThesaurusPageAsync(
      {String keyword = ''}) async {
    final getThesaurusPage = await rpc.report.getThesaurusPageAsync(
      GetThesaurusPageRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 100,
        thesaurusName: keyword,
        languageCode: i18nBook.locale.toCodeString('-'),
      ),
    );
    return getThesaurusPage.pageData ?? <ThesaurusDTO>[];
  }

  /// 获取个人词条库
  ///
  /// [isDelete] 可选参数 删除时候列表刷新
  Future<void> getThesaurusPage([bool? isDelete = false]) async {
    final getThesaurusPage = await getThesaurusPageAsync();
    state.entryInfos = getThesaurusPage;

    /// 系统词条
    state.systemEntryInfos = getThesaurusPage
        .where(
          (element) => element.isDefault == true,
        )
        .toList();
    if ((state.entryInfos.length != 0 && state.thesaurusCode.isEmpty) ||
        isDelete!) {
      state.activeEntryIndex = 0;
      state.thesaurusCode = state.entryInfos[0].thesaurusCode!;
      state.thesaurusName = state.entryInfos[0].thesaurusName!;
      state.isEnableEdit =
          state.entryInfos[0].thesaurusType == ThesaurusTypeEnum.Personal ||
              (state.entryInfos[0].thesaurusType ==
                      ThesaurusTypeEnum.Organization &&
                  isOrg &&
                  Store.user.isPrincipal);
    }
    onLoaded.emit(this, '');
    getThesaurusItemsAsync();
    getCreateThesaurusPage();
  }

  /// 获取个人词条库 创建前调用
  Future<void> getCreateThesaurusPage() async {
    List<ThesaurusDTO> entryInfos;
    if (isOrg) {
      entryInfos = await getOrgThesaurusPage();
    } else {
      entryInfos = await getThesaurusPageAsync();
    }
    state.createEntryInfos = entryInfos;
  }

  Future<List<ThesaurusDTO>> getOrgThesaurusPage({String? keyword}) async {
    final getOrgThesaurusPageAsync = await rpc.report.getOrgThesaurusPageAsync(
      GetThesaurusPageRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 100,
        thesaurusName: keyword,
        languageCode: i18nBook.locale.toCodeString('-'),
      ),
    );
    return getOrgThesaurusPageAsync.pageData ?? [];
  }

  /// 搜索词条库
  Future<void> searchEntryInfos() async {
    List<ThesaurusDTO> entryInfos;
    if (isOrg) {
      entryInfos = await getOrgThesaurusPage(keyword: state.thesaurusKeyWord);
    } else {
      entryInfos = await getThesaurusPageAsync(keyword: state.thesaurusKeyWord);
    }
    if (entryInfos.length == 0) {
      //PromptBox.toast(i18nBook.remedical.inputExistedTerm.t);
      state.getTreeView = [];
      state.vocabularyCard = [];
    }
    state.entryInfos = entryInfos;
    if (state.entryInfos.isNotEmpty) {
      clickEntryCard(0, state.entryInfos[0]);
    }
  }

  /// 获取组织词条库
  Future<void> getOrgThesaurusPageAsync([bool? isDelete = false]) async {
    final pageData = await getOrgThesaurusPage();
    state.entryInfos = pageData;
    state.systemEntryInfos = state.entryInfos
        .where(
          (element) => element.isDefault == true,
        )
        .toList();
    if (state.entryInfos.length != 0 && state.thesaurusCode.isEmpty ||
        isDelete!) {
      state.thesaurusCode = state.entryInfos[0].thesaurusCode!;
      state.thesaurusName = state.entryInfos[0].thesaurusName!;
      state.activeEntryIndex = 0;
      state.isEnableEdit =
          state.entryInfos[0].thesaurusType == ThesaurusTypeEnum.Personal ||
              (state.entryInfos[0].thesaurusType ==
                      ThesaurusTypeEnum.Organization &&
                  isOrg &&
                  Store.user.isPrincipal);
    }
    onLoaded.emit(this, '');

    /// 获取所有的词条
    getThesaurusItemsAsync();
    getCreateOrgThesaurusPageAsync();
  }

  ///  获取组织词条库 创建前调用这个接口
  Future<void> getCreateOrgThesaurusPageAsync() async {
    final getOrgThesaurusPageAsync = await rpc.report.getOrgThesaurusPageAsync(
      GetThesaurusPageRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 100,
        languageCode: i18nBook.locale.toCodeString('-'),
      ),
    );

    /// 非默认的词条
    state.createEntryInfos = getOrgThesaurusPageAsync.pageData!;
  }

  @override
  Future<void> onLoad() async {
    Future.delayed(Duration(milliseconds: 200), () async {
      await Future.wait(
        [
          isOrg ? getOrgThesaurusPageAsync() : getThesaurusPage(),
        ],
      );
    });
  }

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

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

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

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

  @override
  void onEnterPressed() {
    if (_isThesaurusItemHasFocus) {
      getEntryByKeyWords();
    }
    if (_isEntryInfoHasFocus) {
      searchEntryInfos();
    }
  }

  void getEntrysByKeyWords() {
    return personalEntryController.getKeyWordsEntry();
  }

  ///移除词条
  Future<void> removeThesaurusAsync(String thesaurusCode) async {
    final removeThesaurusAsync = await rpc.report.removeThesaurusAsync(
      RemoveThesaurusRequest(
        thesaurusCode: thesaurusCode,
        token: Store.user.token,
      ),
    );
    if (removeThesaurusAsync) {
      PromptBox.toast(i18nBook.remedical.deleteVocBaseSuccess.t);
      onNodeTap('');
      await getThesaurusPage(true);
    } else {
      PromptBox.toast(i18nBook.remedical.deleteFailed.t);
    }
  }

  void _listenSearchFocusNode() {
    searchThesaurusItemInputFocusNode.addListener(() {
      if (searchThesaurusItemInputFocusNode.hasFocus) {
        _isThesaurusItemHasFocus = true;
      } else {
        Future.delayed(
          const Duration(milliseconds: 10),
          () {
            _isThesaurusItemHasFocus = false;
          },
        );
      }
    });

    searchEntryInfoInputFocusNode.addListener(() {
      if (searchEntryInfoInputFocusNode.hasFocus) {
        _isEntryInfoHasFocus = true;
      } else {
        Future.delayed(
          const Duration(milliseconds: 10),
          () {
            _isEntryInfoHasFocus = false;
          },
        );
      }
    });
  }

  Future<ThesaurusExportDto> getVocJsonBinary() async {
    final getThesaurusItemsAsync = await rpc.report.exportThesaurusAsync(
      FindThesaurusByCodeRequest(
        token: Store.user.token,
        thesaurusCode: state.thesaurusCode,
      ),
    );

    var jsonString = jsonEncode(_getJsonList(
        getThesaurusItemsAsync.thesaurusTemplateInfo!.thesaurusList));
    return ThesaurusExportDto(state.thesaurusName, _jsonToUint8List(jsonString),
        base64.encode(utf8.encode(jsonString)));
  }

  Uint8List _jsonToUint8List(String jsonString) {
    List<int> utf8Data = utf8.encode(jsonString);
    Uint8List uint8List = Uint8List.fromList(utf8Data);
    return uint8List;
  }

  Future openVocImportPage() async {
    return await router.dialog(
      () => ImportThesaurusDialog(),
    );
  }

  Future importVoc() async {
    final getThesaurusItemsAsync = await rpc.report.importThesaurusAsync(
      ImportThesaurusInfoRequest(
        token: Store.user.token,
        thesaurusName: state.editingThesaurusName,
        thesaurusTemplateInfo: state.importThesaurusTemplateInfoDTO,
        thesaurusType:
            isOrg ? ThesaurusTypeEnum.Organization : ThesaurusTypeEnum.Personal,
        languageCode: i18nBook.locale.toCodeString('-'),
      ),
    );
    await searchEntryInfos();
  }

  void changeVocType(ThesaurusUsageTypeEnum value) {
    state.selectedVocType = value;
  }

  List<Map<String, dynamic>> _getJsonList(
      List<ThesaurusInfoDTO>? thesaurusList) {
    List<Map<String, dynamic>> list = [];
    if (thesaurusList == null) {
      return list;
    }
    thesaurusList.forEach((element) {
      list.add(element.toJson());
    });
    return list;
  }
}

class ThesaurusExportDto {
  final String name;
  final Uint8List data;
  final String dataStr;
  ThesaurusExportDto(this.name, this.data, this.dataStr);
}
