/*
 * @Author: XianKaiQun
 * @Date: 2020-07-15 08:56:23
 * @LastEditors: wuwei
 * @LastEditTime: 2023-12-12 15:47:49
 * @Description: 账单明细
 */
import 'dart:convert';
import 'package:get/get.dart';
import 'package:app_package/app_package.dart';
import 'package:flutter/material.dart';
import 'package:wisdom_cli/wisdom_cli.dart';
import 'package:intl/intl.dart' show DateFormat;
import '../api/asset_bill.dart';
import '../models/asset_list.dart';
import '../models/deposite_charge_item.dart';
import '../models/deposite_detail.dart';
import '../models/fee_type.dart';
import '../models/identification.dart';
import '../models/owe_fee_count.dart';
import '../models/prefee_charge_item.dart';
import '../models/prefee_detail.dart';

class BillPlatformStore with ChangeNotifier {
  final scrollViewKey = GlobalKey<WisScrollViewState>();
  final BuildContext context, providerContext;
  Map<String, dynamic>? routingArgs;
  BillPlatformStore(this.context, this.providerContext) {
    this.routingArgs = json.decode(
            json.encode(ModalRoute.of(context)?.settings.arguments ?? {}))
        as Map<String, dynamic>;
    if (routingArgs!['assetFullName'] != null) {
      assetFullName = routingArgs!['assetFullName'];
    }
    if (routingArgs!['assetType'] != null) {
      assetType = routingArgs!['assetType'];
    }
    if (routingArgs!['assetId'] != null) {
      assetId = routingArgs!['assetId'];
    }
  }

  final appGlobalStore = GetIt.I.get<AppGlobalStore>();
  final communityGlobalStore = GetIt.I.get<CommunityGlobalStore>();

  CommunityModel? get community => communityGlobalStore.data;

  ///----------------------------------变量---------------------------
  String? assetId;
  String? assetType;

  /// 当前选中资产全称
  String? assetFullName;
  OweFeeCountModel? data;

  get startTime => chargeYearMonthStart != null &&
          DateFormat('yyyy').format(chargeYearMonthStart!) != '1900'
      ? DateFormat('yyyyMM').format(chargeYearMonthStart!)
      : '';
  get endTime => DateFormat('yyyyMM').format(chargeYearMonthEnd);
  DateTime? chargeYearMonthStart;
  DateTime chargeYearMonthEnd = DateTime.now();

  /// 预存款金额
  num preFee = 0;

  /// 押金金额
  num depositeFee = 0;

  /// 账单费用
  num payFee = 0;

  /// 总计金额
  get allTotalFee =>
      ((data?.payFee ?? 0) + (preFee) + (depositeFee)).toStringAsFixed(2);

  /// 收费项目id
  IdentificationModel? identificationItem = IdentificationModel(
    feeName: '全部',
    identification: '',
  );

  String get identification => identificationItem?.identification ?? '';

  /// 费用类型id
  FeeTypeModel? feeTypeItem = FeeTypeModel(
    feeType: '全部',
    feeTypeId: '',
  );

  String get feeTypeId => feeTypeItem?.feeTypeId ?? '';

  ///----------------------------------全局方法初始化---------------------------

  /// 初始化数据
  Future<void> getData() async {
    await getTotalCount();
    await getAssetList();
    await getDepositeDetail();
    await getPreDetail();
  }

  ///----------------------------------底部录单---------------------------

  ///去录单
  Future<void> route2submit() async {
    if (preFeeChargeItem.identification != null && preFee <= 0) {
      WToastUtil.show('请输入预存金额');
      return;
    }
    if (depositeChargeItem.identification != null && depositeFee <= 0) {
      WToastUtil.show('请选择押金项目');
      return;
    }
    await Get.toNamed('receipt/submit', arguments: {
      'total': allTotalFee,
      'assetId': assetId,
      'assetName': assetFullName,
      'chargeSubject': assetType,
      'preFee': preFee,
      'depositeFee': depositeFee,
      'payFee': payFee,
      'preAssetItem': preAssetItem,
      'preFeeChargeItem': preFeeChargeItem,
      'depositeAssetItem': depositeAssetItem,
      'depositeChargeItem': depositeChargeItem,
      'liquidatedDamagesFee': data?.liquidatedDamagesFee ?? 0,
      'bills': data!.billIds
          ?.map((e) => {
                'id': e,
                'payFee': 0,
                'discountFee': 0,
              })
          .toList(),
      'liquidatedDamagesBills': data?.liquidatedDamagesBills ?? [],
    })!
        .then((res) => {
              if (res is Map &&
                  res['isRefresh'] != null &&
                  res['isRefresh'] == true)
                {
                  resetForm(),
                  resetFilter(),
                  scrollViewKey.currentState?.initTrigger(),
                }
            });
  }

  ///----------------------------------顶部标题栏操作---------------------------
  /// 去催缴
  void toUrgeToPay() {
    Get.toNamed(
      'bill/urge_pay',
      arguments: {
        'assetId': assetId,
        'assetType': assetType,
        'assetFullName': assetFullName,
      },
    );
  }

  /// 去收支记录
  void toRecord() {
    Get.toNamed(
      'pay_record/index',
      arguments: {
        'appBarTitle': '收支记录',
        'assetId': assetId,
        'assetType': assetType,
      },
    );
  }

  ///----------------------------------顶部资产卡片---------------------------

  /// 是否展开更多资产
  bool isShowAssetlist = false;

  /// 收起|展开 更多资产
  void changeShowAssetList() {
    isShowAssetlist = !isShowAssetlist;
    notifyListeners();
  }

  /// 切换当前资产
  Future<void> changeAsset(AssetsOfAssetListModel value, type) async {
    /// 水电表
    if (type == 'electricMeter' || type == 'waterMeter') {
      Get.toNamed('metered/detail', arguments: {
        'id': value.code,
        'source': 'house',
      });
      return;
    }

    assetId = value.code;
    assetFullName = value.name;
    assetType = type;
    isShowAssetlist = false;
    notifyListeners();
    await resetFilter();
    await resetForm();
    scrollViewKey.currentState?.refreshTrigger();
  }

  /// 重置顶部卡片

  /// 重置账单筛选
  Future<void> resetFilter() async {
    feeTypeItem = null;
    identificationItem = null;
    chargeYearMonthStart = null;
    chargeYearMonthEnd = DateTime.now();
    notifyListeners();
  }

  /// 重置预存款、押金表单
  Future<void> resetForm() async {
    isShowAssetlist = false;
    isShowDepositeFee = false;
    isShowPreFee = false;
    assetList = [];
    prepayBillAssetList = [];
    depositepayBillAssetList = [];
    preFee = 0;
    depositeFee = 0;
    payFee = 0;
    preAssetItem = AssetsOfAssetListModel();
    preFeeChargeItem = PrefeeChargeItemModel();
    depositeAssetItem = AssetsOfAssetListModel();
    depositeChargeItem = DepositeChargeItemModel();
    notifyListeners();
  }

  List<AssetListModel> assetList = [];
  List<AssetsOfAssetListModel> prepayBillAssetList = [];
  List<AssetsOfAssetListModel> depositepayBillAssetList = [];

  /// 按资产id获取全部关联资产
  Future<void> getAssetList() async {
    var res = await AssetBillApi.getAssetListByAssetId({
      'assetId': assetId,
      'treeSelection': assetType,
    });
    List<AssetListModel> _list = [];
    /// 预存款资产列表
    List<AssetsOfAssetListModel> _list1 = [];
    /// 押金资产列表
    List<AssetsOfAssetListModel> _list2 = [];
    var _asset = AssetsOfAssetListModel(
      code: assetId,
      name: assetFullName,
      type: assetType,
    );
    if (assetType != 'owner') {
      preAssetItem = _asset;
      _list1.add(_asset);
      if (assetType == 'house') {
        depositeAssetItem = _asset;
        _list2.add(_asset);
      }
    }

    res.data?.forEach((item) {
      /// 暂时不显示关联住户
      // if ((item.type == 'owner' ||
      if ((item.type == 'owner' ||
              item.type == 'house' ||
              item.type == 'car' ||
              item.type == 'parkingSpace' ||
              item.type == 'waterMeter' ||
              item.type == 'electricMeter') &&
          item.assets != null &&
          item.assets!.length > 0) {
        _list.add(item);
        item.assets?.forEach((element) {
          element.type = item.type;

          if (item.type != 'owner' &&
              item.type != 'electricMeter' &&
              item.type != 'waterMeter' &&
              assetType != 'parkingSpace' &&
              assetType != 'car') {
            _list1.add(element);
          }
          if (item.type != 'owner' &&
              item.type == 'house' &&
              assetType != 'parkingSpace' &&
              assetType != 'car') {
            _list2.add(element);
          }
        });
      }
      ;
    });
    assetList = _list;
    prepayBillAssetList = _list1;
    depositepayBillAssetList = _list2;
    notifyListeners();
    if (assetType != 'owner') {
      await getPreChargeItemList();
      await getDepositeChargeItemList();
    }
  }

  AssetsOfAssetListModel assetItem = AssetsOfAssetListModel(
    name: '全部',
    code: '',
  );

  ///----------------------------------账单-------------------------------

  /// 获取账单总计-------------------------------------------
  Future<void> getTotalCount() async {
    Map<String, dynamic> params = {
      'assetId': assetItem.code != null && assetItem.code != ''
          ? assetItem.code
          : assetId,
      'treeSelection': assetItem.type != '' && assetItem.type != null
          ? assetItem.type
          : assetType,
      'identification': identificationItem?.identification,
      'feeTypeId': feeTypeItem?.feeTypeId,
      'communityId': community?.id,
      'chargeYearMonthEnd': DateFormat('yyyy-MM').format(chargeYearMonthEnd),
    };
    // if (assetItem.code != null && assetItem.code != '') {
    //   params['assetId'] = assetItem.code;
    //   params['treeSelection'] = assetItem.type;
    // } else {
    //   params['houseId'] = assetId;
    // }
    if (chargeYearMonthStart != null &&
        DateFormat('yyyy').format(chargeYearMonthStart!) != '1900') {
      params['chargeYearMonthStart'] =
          DateFormat('yyyy-MM').format(chargeYearMonthStart!);
    }

    var res = await AssetBillApi.getOweFeeCount(params);
    data = res.data ?? OweFeeCountModel();
    payFee = data?.payFee ?? 0;
    notifyListeners();
  }

  /// 跳转账单明细
  void toOweFeeDetail() {
    Get.toNamed('bill/detail', arguments: {
      'assetId': assetId,
      'assetType': assetType,
      'assetFullName': assetFullName,
    });
  }

  /// 跳转欠费筛选
  Future<void> toOweFeeFilter() async {
    await Get.toNamed('bill/platform/owe_filter', arguments: {
      'assetId': assetId,
      'feeTypeItem': feeTypeItem,
      'identificationItem': identificationItem,
      'assetItem': assetItem,
      'chargeYearMonthEnd': chargeYearMonthEnd,
      'chargeYearMonthStart': chargeYearMonthStart,
      'assetType': assetType,
      'assetFullName': assetFullName,
    })!
        .then((res) => {
              if (res is Map && res['isRefresh'] == true)
                {
                  chargeYearMonthStart = res['chargeYearMonthStart'],
                  chargeYearMonthEnd = res['chargeYearMonthEnd'],
                  assetItem = res['assetItem'],
                  feeTypeItem = res['feeTypeItem'],
                  identificationItem = res['identificationItem'],
                  getTotalCount(),
                },
            });
  }

  ///----------------------------------预存款-------------------------------
  ///
  ///

  /// 是否显示预存款缴费录单
  bool isShowPreFee = false;

  /// 切换预存款缴费录单显示
  void changeShowPreFee(flag) {
    isShowPreFee = flag;
    notifyListeners();
  }

  PrefeeDetailModel preDetail = PrefeeDetailModel();

  /// 获取预存款余额
  Future<void> getPreDetail() async {
    var res = await AssetBillApi.getPreFeeDetail({
      "id": assetId,
      "treeSelection": assetType,
    });
    preDetail = res.data ?? PrefeeDetailModel();
    notifyListeners();
  }

  /// 跳转预存款详情
  toPreFee() async {
    Get.toNamed('bill/prefee', arguments: {
      'type': assetType,
      'id': assetId,
      'name': assetFullName,
    })!
        .then((value) => {
              getPreDetail(),
            });
  }

  List<PrefeeChargeItemModel> preFeeChargeList = [];

  /// 获取预存款收费项目
  Future<void> getPreChargeItemList() async {
    var res = await AssetBillApi.getPrefeeChargeItemList({
      'assetId': preAssetItem.code,
      'chargeSubject': preAssetItem.type,
    });
    res.data?.forEach((item) {
      if (item.prepay == true) {
        item.feeName = '${item.feeName}【按月预存】';
      }
      ;
      if (item.prePayFee != null) {
        item.feeName =
            '${item.feeName}${item.prePayFee! > 0 ? '【余额：${item.prePayFee}】' : ''}';
      }
      ;
    });
    List<PrefeeChargeItemModel>? res1 = await getGeneralPrefee();
    if (res1 != null &&
        preAssetItem.type != 'parkingSpace' &&
        preAssetItem.type != 'car') {
      preFeeChargeList = [...res1, ...(res.data ?? [])];
    } else {
      preFeeChargeList = res.data ?? [];
    }
    notifyListeners();
  }

  /// 获取通用预存款是否可用
  Future getGeneralPrefee() async {
    var res = await AssetBillApi.getGeneralPrefee({
      'houseId': preAssetItem.code,
      'communityId': community?.id,
    });

    if (res.data?.prePayGeneralPay == true) {
      return [
        PrefeeChargeItemModel(
          identification: '',
          feeName: '通用预存款',
          type: 'general',
        )
      ];
    }

    return null;
  }

  AssetsOfAssetListModel preAssetItem = AssetsOfAssetListModel();

  AssetsOfAssetListModel depositeAssetItem = AssetsOfAssetListModel();

  /// 选择预存款资产
  Future<void> choosePreAsset() async {
    var res = await WPickerUtil.single<AssetsOfAssetListModel>(
      Get.context!,
      title: WisText('选择预存款资产'),
      getData: () async => await prepayBillAssetList,
      initialValue: preAssetItem,
    );
    if (res != null) {
      preAssetItem = res;
      preFeeChargeItem = PrefeeChargeItemModel();
      preFee = 0;
      notifyListeners();
      await getPreChargeItemList();
    }
  }

  PrefeeChargeItemModel preFeeChargeItem = PrefeeChargeItemModel();

  /// 选择预存款项目
  Future<void> choosePrefeeCharge() async {
    if (preAssetItem.code == null) {
      WToastUtil.show('请先选择缴费预存资产');
      return;
    }
    var res = await WPickerUtil.single<PrefeeChargeItemModel>(
      Get.context!,
      title: WisText('选择预存款项目'),
      getData: () async => await preFeeChargeList,
      initialValue: preFeeChargeItem,
    );
    if (res != null) {
      preFeeChargeItem = res;
      preFee = 0;
      notifyListeners();
    }
  }

  /// 月份输入
  Future<void> inputPrefee(value) async {
    if (preFeeChargeItem.prepay == true) {
      if (value != null && value != '') {
        var _value = int.parse(value);
        preFee = double.parse(((preFeeChargeItem.receivableFeeDB ?? 0) * _value).toStringAsFixed(2));
      } else {
        preFee = 0;
      }
    } else {
      if (value != null && value != '') {
        var _value = double.parse(value);
        preFee = _value;
      } else {
        preFee = 0;
      }
    }
    notifyListeners();
  }

  /// -------------------------------押金------------------------------------
  ///
  /// 是否显示押金缴费录单
  bool isShowDepositeFee = false;

  /// 切换押金缴费录单显示
  void changeShowDepositeFee(flag) {
    isShowDepositeFee = flag;
    notifyListeners();
  }

  DepositeDetailModel depositeDetail = DepositeDetailModel();

  /// 获取押金详情
  Future<void> getDepositeDetail() async {
    var res = await AssetBillApi.getDepositeFeeDetail({
      "assetId": assetId,
      "treeSelection": assetType,
    });
    depositeDetail = res.data ?? DepositeDetailModel();
    notifyListeners();
  }

  /// 跳转押金详情
  Future<void> toDepositeFee() async {
    Get.toNamed('bill/deposite_fee', arguments: {
      'type': assetType,
      'id': assetId,
      'name': assetFullName,
    })!
        .then((value) => {
              getDepositeDetail(),
            });
    ;
  }

  /// 选择押金资产
  Future<void> chooseDepositeAsset() async {
    var res = await WPickerUtil.single<AssetsOfAssetListModel>(
      Get.context!,
      title: WisText('选择押金资产'),
      getData: () async => await depositepayBillAssetList,
      initialValue: depositeAssetItem,
    );
    if (res != null) {
      depositeAssetItem = res;
      notifyListeners();
      await getDepositeChargeItemList();
    }
  }

  DepositeChargeItemModel depositeChargeItem = DepositeChargeItemModel();

  /// 选择押金项目
  Future<void> chooseDepositeCharge() async {
    if (depositeAssetItem.code == null) {
      WToastUtil.show('请先选择缴费押金资产');
      return;
    }
    var res = await WPickerUtil.single<DepositeChargeItemModel>(
      Get.context!,
      title: WisText('选择押金项目'),
      getData: () async => await depositeChargeItemList,
      initialValue: depositeChargeItem,
    );
    if (res != null) {
      depositeChargeItem = res;
      depositeFee = depositeChargeItem.fee ?? 0;
      notifyListeners();
    }
  }

  List<DepositeChargeItemModel> depositeChargeItemList = [];

  /// 获取押金收费项目列表
  Future<void> getDepositeChargeItemList() async {
    var res = await AssetBillApi.getDepositeChargeItemList({
      'communityId': community?.id,
    });
    depositeChargeItemList = res.data ?? [];
    notifyListeners();
  }
}
