/*
 * @Author: XianKaiQun
 * @LastEditors: ChenYaJin
 * @Date: 2020-11-09 11:08:11
 * @LastEditTime: 2023-06-01 09:17:22
 */
import 'dart:async';
import 'dart:convert';

import 'package:app_package/app_package.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:service_package/src/api/api.dart';
import 'package:service_package/src/models/cascade_house.dart';
import 'package:service_package/src/models/enum.dart';
import 'package:service_package/src/models/inner_sort_list.dart';
import 'package:service_package/src/models/sort_list.dart';
import 'package:service_package/src/models/staff.dart';
import 'package:service_package/src/models/type_list.dart';
import 'package:service_package/src/pages/success/index.dart';
import 'package:wisdom_cli/wisdom_cli.dart';
import 'index.dart';
part 'store.g.dart';

class IndexPageStore = _IndexPageStore with _$IndexPageStore, ChangeNotifier;

abstract class _IndexPageStore with Store {
  final BuildContext context1;
  IndexPageArguments get arguments =>
      IndexPageArguments.fromRouteArguments(context1);
  _IndexPageStore(this.context1) {
    getRegion();
  }
  final communityGlobalStore = GetIt.I.get<CommunityGlobalStore>();

  final scrollKey = GlobalKey<WisScrollViewState>();

  // 业主手机号类别 是否是手机号
  @observable
  bool isPhoneNumber = true;
  @action
  setContactType(bool isPhone) {
    isPhoneNumber = isPhone;
  }

  ///受理报修？
  @observable
  int tabIndex = 0;
  @action
  onRepairTab(int index) {
    tabIndex = index;
  }

  @computed
  bool get isRepair => tabIndex == 1;

  @computed
  String get placeStr => isRepair ? '修' : '事';

  final formKey = GlobalKey<WFormState>();

  WFormState? get formState => formKey.currentState;

  Map<String, dynamic> formValue = {};

  @observable
  dynamic appointedTime;

  @action
  Future setTime(value) async {
    appointedTime = value;
  }

  @observable
  ObservableList dealPersonList = ObservableList.of([]);

  /// 获取处理人列表
  @action
  Future getPersonList() async {
    var res = await RequestApi()
        .getDealPerson({'communityId': communityGlobalStore.data.id});
    var res1 = await RequestApi().getDealPerson({
      'communityId': communityGlobalStore.data.id,
      'openHris': true,
    });
    List ids = [];
    res1.data!.forEach((item) {
      item.child!.forEach((item1) {
        ids.add(item1.id);
      });
    });
    res.data?.forEach((item) {
      item.child!.forEach((item1) {
        if (ids.contains(item1.id)) {
          item1.name = '【排班人员】' + item1.name!;
        }
      });
    });
    dealPersonList = ObservableList.of(jsonDecode(jsonEncode(res.data)) ?? []);
  }

  @observable
  String dealPersonId = '';

  @action
  setDealPerson(v) {
    dealPersonId = v;
  }

  @observable
  ObservableList copyPerson = ObservableList.of([]);

  @action
  setCopyPerson(v) {
    copyPerson = ObservableList.of(v ?? []);
  }

  ///房号==============
  Future<List<CascadeHouseModel>> getHouseData(
      List<CascadeHouseModel> list) async {
    List<CascadeHouseModel>? back = [];

    final build = list.firstWhereOrNull((e) => e.status == 'build');
    final unit = list.firstWhereOrNull((e) => e.status == 'unit');
    final floor = list.firstWhereOrNull((e) => e.status == 'floor');
    final last = list.lastWhereOrNull((e) => true);

    final communityId = communityGlobalStore.data.id;
    switch (last?.status) {
      case 'build':
        final res = await RequestApi().getUnitInfo({
          'communityId': communityId,
          'buildId': build!.id,
        });
        back = res.data;
        break;
      case 'unit':
        final res = await RequestApi().getFloorInfo({
          'communityId': communityId,
          'buildId': build!.id,
          'unitId': unit!.id,
        });
        back = res.data;
        break;
      case 'floor':
        final res = await RequestApi().getHouseInfo({
          'communityId': communityId,
          'buildId': build!.id,
          'unitId': unit!.id,
          'houseFloor': floor!.id,
        });
        back = res.data;
        break;

      default:
        final res = await RequestApi().getBuildInfo({
          'communityId': communityGlobalStore.data.id,
        });
        back = res.data;
    }
    return back ?? [];
  }

  ///枚举==========
  ///
  ///
  ///缓存一下下
  Map<String, Object?> _enumCache = {};

  ///报修区域
  @observable
  ObservableList<EnumModel>? regionList;
  @action
  setregionList(ObservableList<EnumModel> value) => regionList = value;

  @observable
  EnumModel? region;
  @action
  setregion(EnumModel value) => region = value;

  Future<void> getRegion() async {
    final res = await RequestApi().getEnum('repairRegion');
    regionList = ObservableList.of(res.data ?? []);
    try {
      region = regionList!.firstWhere((e) => e.code == 'outPublic');
    } catch (e) {}
  }

  Future<List<EnumModel>> getRegionSort() async {
    if (_enumCache['getRegionSort'] == null) {
      final res = await RequestApi().getEnum('repairRegionSort');
      _enumCache['getRegionSort'] = res.data;
    }
    return _enumCache['getRegionSort'] as FutureOr<List<EnumModel>>? ?? [];
  }

  ///业务类型
  Future getBusiness() async {
    final res = await RequestApi().getEnum('reportBusiness');
    _enumCache['reportBusiness'] = res.data;
  }

  List repairTypeList = [];
  List repairSortList = [];
  List reportTypeList = [];
  List reportSortList = [];
  List reportInnerSortList = [];
  List repairInnerSortList = [];

  Future<List<TypeListModel>> getRepairTypeList() async {
    final values = formKey.currentState?.values;
    values!['repairSort'] = null;
    final res = await RequestApi().getRepairTypeList();
    repairTypeList = res.data!;
    return res.data!;
  }

  Future<List<SortListModel>?> getRepairSortList() async {
    final values = formKey.currentState?.values;
    if (values!['repairBusinessType']?.id == null ||
        values['repairBusinessType']?.id == '') {
      WToastUtil.show('请先选择提报类型');
      return [];
    }
    final res = await RequestApi().getRepairSortList({
      'businessTypeId': values['repairBusinessType']?.id,
    });
    repairSortList = res.data!;
    if (res.data?.isEmpty == true) {
      values['repairSort'] = null;
    }
    return res.data;
  }

  Future<List<TypeListModel>> getReportTypeList() async {
    final values = formKey.currentState?.values;
    values!['reportSort'] = null;
    final res = await RequestApi().getReportTypeList();
    reportTypeList = res.data!;
    return res.data!;
  }

  Future<List<SortListModel>?> getReportSortList() async {
    final values = formKey.currentState?.values;
    if (values!['reportBusinessType']?.id == null ||
        values['reportBusinessType']?.id == '') {
      WToastUtil.show('请先选择提报类型');
      return [];
    }
    final res = await RequestApi().getReportSortList({
      'businessTypeId': values['reportBusinessType']?.id,
    });
    reportSortList = res.data!;
    if (res.data?.isEmpty == true) {
      values['reportSort'] = null;
    }
    return res.data!;
  }

// 报事内部分类列表
  Future<List<InnerSortListModel>> getReportInnerSortList() async {
    final res = await RequestApi().getReportInnerSortList();
    reportInnerSortList = res.data!;
    return res.data!;
  }

  // 报修内部分类列表
  Future<List<InnerSortListModel>> getRepairInnerSortList() async {
    final res = await RequestApi().getRepairInnerSortList();
    repairInnerSortList = res.data!;
    return res.data!;
  }

  Future<List<EnumModel>> getReportOrStatus() async {
    if (_enumCache['reportOrRepairStatus'] == null) {
      final res = await RequestApi().getEnum('reportOrRepairStatus');
      _enumCache['reportOrRepairStatus'] = res.data;
    }
    return _enumCache['reportOrRepairStatus'] as FutureOr<List<EnumModel>>? ??
        [];
  }

  ///分类（报事）
  Future<List<EnumModel>> getReportList() async {
    if (_enumCache['getReportList'] == null) {
      final res = await RequestApi().getReportList();
      _enumCache['getReportList'] = res.data;
    }
    return _enumCache['getReportList'] as FutureOr<List<EnumModel>>? ?? [];
  }

  ///受理人
  Future<List<StaffModel>> getStaffList() async {
    if (_enumCache['getStaffList'] == null) {
      final res = await RequestApi().getStaffList(communityGlobalStore.data.id);
      _enumCache['getStaffList'] = res.data;
    }
    return _enumCache['getStaffList'] as FutureOr<List<StaffModel>>? ?? [];
  }

  ///图片选择
  @observable
  ObservableList<FileEntity> fileEntities = ObservableList.of([]);
  @computed
  List<FileImage> get files =>
      fileEntities.map((e) => FileImage(e.file!)).toList();
  @action
  filesChanged(List<FileEntity> _files) {
    fileEntities.addAll(_files);
  }

  @action
  filesDelete(int index) {
    fileEntities.removeAt(index);
  }

  Map<String, String> uploadeds = {}; //已上传(缓存)

  Future<List<String?>> upLoad() async {
    ///未上传的
    final waitUpLoads =
        fileEntities.where((e) => uploadeds[e.file!.path] == null).toList();

    final futures =
        waitUpLoads.map((e) => GlobalApi.postUploadImage(e.file)).toList();

    final res = await Future.wait(futures);

    for (var i = 0; i < waitUpLoads.length; i++) {
      final path = waitUpLoads[i].file!.path;
      if (res[i]!.data != null) {
        uploadeds[path] = res[i]!.data!;
      }
    }
    return fileEntities.map((e) => uploadeds[e.file!.path]).toList();
  }

  ///新增报事
  ///
  Future<String?> addReport() async {
    final Map<String, dynamic>? values = formKey.currentState!.values;
    CascadeHouseModel? house = values?['house']?.firstWhere(
      (e) => e.status == 'house',
    );
    SortListModel? sort = values?['reportSort'] ?? null;
    TypeListModel? businessType = values?['reportBusinessType'] ?? null;
    final entCode = WisStorageUtil.get(key: 'storage-user-entCode');

    final errorList = [
      () => WValidatorUtil.isRequired('请输入姓名').validate(values?['name']),
      () => WValidatorUtil.isRequired('请输入联系号码').validate(values?['mobile']),
      () => isPhoneNumber
          ? WValidatorUtil.isPhoneNumber('手机号格式不正确').validate(values?['mobile'])
          : WValidatorUtil.isRequired('请输入联系号码').validate(values?['mobile']),
      () => WValidatorUtil.isRequired('请选择业主提报类型').validate(businessType?.id),
      () =>
          WValidatorUtil.isRequired('请输入内容描述').validate(values?['description']),
      () => entCode != 460102 && entCode != 460101
          ? null
          : WValidatorUtil.isRequired('请选择内部分类')
              .validate(values?['reportInternalSortId']?.id),
      () => WValidatorUtil.isRequired('请选择处理人').validate(dealPersonId),
    ];

    for (var item in errorList) {
      final text = item();
      if (text != null) {
        WToastUtil.show(text);
        return null;
      }
    }

    // if (entCode == 460102 || entCode == 460101) {
    //   if (values?['reportInternalSortId'] == null ||
    //       values?['reportInternalSortId'].id == null ||
    //       values?['reportInternalSortId'].id == '') {
    //     WToastUtil.show('请选择内部分类');
    //     return null;
    //   }
    // }

    final photos = await upLoad();
    final data = {
      'description': values?['description'],
      'houseId': house?.id,
      'name': values?['name'],
      'mobile': values?['mobile'],
      'businessTypeId': businessType?.id,
      'sortId': sort?.id,
      'photos': photos,
      'remark': values?['remark'],
      'communityId': communityGlobalStore.data.id,
      'dealPersonId': dealPersonId,
      'source': 'hgjMobile',
      'mailToIds': copyPerson,
      'appointedTime': appointedTime != null ? '$appointedTime:00' : null,
      'internalSortId': values?['reportInternalSortId']?.id
    };
    final res = await RequestApi().postReport(data);
    return res.data;
  }

  ///新增报修
  ///
  Future<String?> addRepair() async {
    final Map<String, dynamic>? values = formKey.currentState!.values;
    CascadeHouseModel? house = values?['house']?.firstWhere(
      (e) => e.status == 'house',
    );
    SortListModel? sort = values?['repairSort'] ?? null;
    TypeListModel? businessType = values?['repairBusinessType'] ?? null;
    final entCode = WisStorageUtil.get(key: 'storage-user-entCode');

    final errorList = [
      () => WValidatorUtil.isRequired('请输入姓名').validate(values?['name']),
      () => WValidatorUtil.isRequired('请输入联系号码').validate(values?['mobile']),
      () => isPhoneNumber
          ? WValidatorUtil.isPhoneNumber('手机号格式不正确').validate(values?['mobile'])
          : WValidatorUtil.isRequired('请输入联系号码').validate(values?['mobile']),
      () => WValidatorUtil.isRequired('请选择业主提报类型').validate(businessType?.id),
      () =>
          WValidatorUtil.isRequired('请输入内容描述').validate(values?['description']),
      () => entCode != 460102 && entCode != 460101
          ? null
          : WValidatorUtil.isRequired('请选择内部分类')
              .validate(values?['repairInternalSortId']?.id),
      () => WValidatorUtil.isRequired('请选择处理人').validate(dealPersonId),
    ];

    for (var item in errorList) {
      final text = item();
      if (text != null) {
        WToastUtil.show(text);
        return null;
      }
    }
    // if (entCode == 460102 || entCode == 460101) {
    //   if (values?['repairInternalSortId'] == null ||
    //       values?['repairInternalSortId'].id == null ||
    //       values?['repairInternalSortId'].id == '') {
    //     WToastUtil.show('请选择内部分类');
    //     return null;
    //   }
    // }
    final photos = await upLoad();
    final data = {
      'description': values?['description'],
      'businessTypeId': businessType?.id,
      'sortId': sort?.id,
      'name': values?['name'],
      'mobile': values?['mobile'],
      'photos': photos,
      'dealPersonId': dealPersonId,
      'remark': values?['remark'],
      'communityId': communityGlobalStore.data.id,
      'houseId': house?.id,
      'source': 'hgjMobile',
      'mailToIds': copyPerson,
      'appointedTime': appointedTime != null ? '$appointedTime:00' : null,
      'internalSortId': values?['repairInternalSortId']?.id,
    };

    final res = await RequestApi().postRepair(data);
    return res.data;
  }

  ///整合
  Future<void> submit() async {
    String? id;
    if (isRepair) {
      id = await addRepair();
    } else {
      id = await addReport();
    }
    if (id != null) {
      Navigator.popAndPushNamed(
        context1,
        'service/success',
        arguments: SuccessPageArguments(id: id, isRepair: isRepair).toJson(),
      );
    }
  }
}
