import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/router/index.dart';

import 'package:flutter/widgets.dart';
import 'package:flyinsono/architecture/services/modules/area_region.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/widget/select_area.dart';
import 'package:flyinsono/pages/organization/org_info/widget/select_organization.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';

import 'index.dart';

///组织信息控制器
class OrgInfoController extends GetxController
    with EnterPressListenOnControllerMixin {
  OrgInfoController();

  final state = OrgInfoState();

  ///搜索机构Controller
  final TextEditingController searchOrgController = TextEditingController();

  ///获取地区信息服务
  final areaRegionService = Get.find<AreaRegionService>();

  ///组织名称
  final TextEditingController orgName = TextEditingController();

  ///超时时限
  final TextEditingController timeoutLimit = TextEditingController();

  /// 手机端地区显示列表
  List<String> regionList = [];
  @override
  Future<void> onEnterPressed() async {
    bool isSearchReferOrg = state.isSearchReferOrg;
    if (isSearchReferOrg) {
      state.referOrgOptions =
          await getOrgModels(keyword: searchOrgController.text);
    } else {
      state.orgOptions = state.allOrgOptions
          .where((element) => element.name.contains(searchOrgController.text))
          .toList();
    }
  }

  /// 关闭完善机构信息弹窗
  void onCancel() {
    router.back(id: NavIds.HOME);
  }

  /// 手机端打开选择地区
  void openSelectArea() async {
    final result = await SelectArea.open();
    state.cityCode = result![1];
    state.areaName = areaRegionService
        .findListName(
          result[0],
          result[1],
        )
        .join('-');
  }

  /// 手机端选择上级机构
  void openSelectOrganization() async {
    final result = await SelectOrganization.open(
      state.orgOptions,
      title: i18nBook.organization.selectSuperiorOrg.t,
    );
    state.parentCode = result![0];
  }

  /// 初始化数据加载
  Future<void> loadData() async {
    try {
      var result = await rpc.organization.getOrganizationByCodeAsync(
        GetOrganizationByCodeRequest(
          organizationCode: Store.user.rootOrganizationCode,
          token: Store.user.token,
        ),
      );
      List<OrgModel> selectReferOrgList = [];
      state.organizationName = result.organizationName ?? "";
      state.organizationCode = result.organizationCode ?? "";
      state.timeoutLimit = result.referralLimitHours;
      result.referralOrganizations?.forEach((element) {
        selectReferOrgList.add(
          OrgModel(
            name: element.organizationName ?? '',
            code: element.organizationCode ?? '',
          ),
        );
      });
      state.selectReferOrgList = selectReferOrgList;
      state.logoUrl = result.logoUrl ?? "";
      state.parentCode = result.parentCode;
      state.parentOrganizationName = result.parentOrganizationName;
      state.cityCode = result.regionCode ?? '';
      state.isSafeMode = result.isEncryptedShow;
      state.patientType =
          result.patientType == OrganizationPatientTypeEnum.Person ? "0" : "1";
      orgName.text = state.organizationName!;
      state.orgShortCode = result.shortCode ?? '';
      timeoutLimit.text = state.timeoutLimit!.toString();
      _initOrganization();
      _initReferOrganization();
      _initRegion();
    } catch (ex) {
      PromptBox.toast(i18nBook.organization.loadOrgInfoFailedTip.t);
      printError(info: ex.toString());
    }
  }

  /// 上传Logo
  Future<void> uploadImage() async {
    try {
      final xFile = await ImagePicker().pickImage(source: ImageSource.gallery);
      if (xFile != null) {
        state.loadding = true;
      }
      final url = await rpc.storage.upload(xFile!);

      if (url != null || url != '') {
        state.loadding = false;
        state.logoUrl = url ?? '';
      }
    } catch (ex) {}
  }

  /// 保存
  Future<void> onSubmit() async {
    try {
      List<String> referralOrganizationCodes = [];
      state.selectReferOrgList.forEach((element) {
        referralOrganizationCodes.add(element.code);
      });
      final saveResult = await rpc.organization.savePersonOrganizationAsync(
        SavePersonOrganizationRequest(
          token: Store.user.token,
          organizationCode: state.organizationCode,
          logoUrl: state.logoUrl,
          organizationName: state.organizationName,
          parentCode: state.parentCode ?? "",
          regionCode: _regionCode(),
          patientType: state.patientType == '1'
              ? OrganizationPatientTypeEnum.Animals
              : OrganizationPatientTypeEnum.Person,
          isEncryptedShow: state.isSafeMode,
          referralLimitHours: state.timeoutLimit!,
          referralOrganizationCodes: referralOrganizationCodes,
        ),
      );
      if (saveResult) {
        PromptBox.toast(i18nBook.organization.saveSuccess.t);
        router.back();
      } else {
        PromptBox.toast(i18nBook.user.saveFailed.t);
      }
    } catch (ex) {
      printError(info: ex.toString());
    }
  }

  String? _checkBlankCharacters(String? code) {
    if (code != null && code.isNotEmpty) {
      return code;
    }
    return null;
  }

  String _regionCode() {
    return _checkBlankCharacters(state.cityCode) ??
        _checkBlankCharacters(state.provinceCode) ??
        _checkBlankCharacters(state.countryCode) ??
        '';
  }

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

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

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

  /// 根据传的code生成地区
  void _generateRegionListByCode(String code) {
    final children = areaRegionService.findListByCode(code);
    regionList.add(children.first.code);

    /// 判断是否到顶级
    if (children.first.parentCode != '0') {
      _generateRegionListByCode(children.first.parentCode);
    }
  }

  /// 获取当前Code下的地区名
  String _getAreaName(String areaCode) {
    return areaRegionService.allList
        .firstWhere(
          (element) => element.code == areaCode,
        )
        .name;
  }

  /// 手机端省市区初始化
  void _initRegion() {
    try {
      // regionList = [];
      _generateRegionListByCode(_regionCode());
      final List<String> regionListReversed =
          regionList.reversed.toSet().toList();
      if (regionListReversed.length == 0) {
        return;
      } else {
        state.areaName = _getAreaName(regionListReversed[0]);
        if (regionListReversed.length == 2) {
          state.areaName = [
            _getAreaName(regionListReversed[0]),
            _getAreaName(regionListReversed[1])
          ].join('-');
        }
        if (regionListReversed.length == 3) {
          state.areaName = [
            _getAreaName(regionListReversed[0]),
            _getAreaName(regionListReversed[1]),
            _getAreaName(regionListReversed[2]),
          ].join('-');
        }
      }
    } catch (ex) {
      printError(info: ex.toString());
    }
  }

  Future<void> _initReferOrganization() async {
    final List<OrgModel> options = await getOrgModels();
    state.referOrgOptions = options;
    state.allReferOrgOptions = options;
  }

  Future<List<OrgModel>> getOrgModels({String? keyword}) async {
    final findOrganizations =
        await rpc.organization.findOrganizationsByPageAsync(
      FindOrganizationListRequest(
        token: Store.user.token,
        pageIndex: 1,
        pageSize: 2000,
        keyWord: keyword,
      ),
    );
    final List<OrgModel> options = [];
    findOrganizations.pageData?.forEach(
      (element) {
        if (element.organizationCode != Store.user.rootOrganizationCode) {
          options.add(
            OrgModel(
              name: element.organizationName!,
              code: element.organizationCode!,
            ),
          );
        }
      },
    );
    return options;
  }

  /// 组织信息初始化
  Future<void> _initOrganization() async {
    final paraentInfos = await rpc.organization.getParentOrganizationListAsync(
      GetParentOrganizationListRequest(
        token: Store.user.token,
      ),
    );
    final List<OrgModel> options = [];
    paraentInfos.forEach(
      (element) {
        options.add(
          OrgModel(
            name: element.organizationName!,
            code: element.organizationCode!,
          ),
        );
      },
    );
    state.orgOptions = options;
    state.allOrgOptions = options;
    state.parentCode = options
        .firstWhereOrNull(
          (element) => element.code == state.parentCode,
        )
        ?.code;
  }
}
