package com.liquidnet.service.adam.service.impl;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.adam.constant.AdamDashboardConstants;
import com.liquidnet.service.adam.constant.AdamTransactionConstants;
import com.liquidnet.service.adam.mapper.AdamTransactionMapper;
import com.liquidnet.service.adam.service.IAdamDashboardService;
import com.liquidnet.service.adam.vo.AdamDashboardVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AdamDashboardServiceImpl implements IAdamDashboardService {

    @Autowired
    private AdamTransactionMapper adamTransactionMapper;

    @Override
    public Map<String, Map<String, Map<String, String>>> summaryOfWalletsTransaction(String finWalletNo, String period, String[] transactionStatusEnums) {
        Date beginDate = new Date();
        String periodFormat = null;
        String periodUnit = "";
        AdamDashboardConstants.PeriodEnum enumByCode = AdamDashboardConstants.PeriodEnum.getEnumByCode(period);
        if (enumByCode == null) {
            return null;
        }
        switch (enumByCode) {
            case TODAY:
                beginDate = DateUtil.addHour(new Date(), -24);
                periodFormat = "%H";
                periodUnit = ":00:00";
                break;
            case WEEKLY:
                beginDate = DateUtil.addDay(new Date(), -7);
                periodFormat = "%Y-%m-%d";
                break;
            case MONTHLY:
                beginDate = DateUtil.addMonth(new Date(), -1);
                periodFormat = "%Y-%m-%d";
                break;
        }

        List<String> transactionStatusList = null;
        if (transactionStatusEnums != null) {
            transactionStatusList = new ArrayList<>(transactionStatusEnums.length);
            Collections.addAll(transactionStatusList, transactionStatusEnums);
        }

        List<AdamDashboardVo> adamDashboardVos = adamTransactionMapper.dashboardSummaryOfWalletsTransaction(finWalletNo, periodFormat, periodUnit, transactionStatusList, beginDate);
        TreeMap<String, List<AdamDashboardVo>> collect = adamDashboardVos.stream().collect(Collectors.groupingBy(AdamDashboardVo::getDateTimeAt,TreeMap::new,Collectors.toList()));
        TreeMap<String, Map<String, Map<String, String>>> map = this.add(collect, transactionStatusEnums);

        return map;

    }

    @Override
    public Map<String, String> summaryOfTransactions(String comId, String period) {
        AdamDashboardConstants.PeriodEnum enumByCode = AdamDashboardConstants.PeriodEnum.getEnumByCode(period);
        Date beginDate = new Date();
        if (enumByCode == null) {
            return null;
        }
        switch (enumByCode) {
            case TODAY:
                beginDate = DateUtil.addHour(new Date(), -24);
                break;
            case WEEKLY:
                beginDate = DateUtil.addDay(new Date(), -7);
                break;
            case MONTHLY:
                beginDate = DateUtil.addMonth(new Date(), -1);
                break;
        }

        List<Map<String, String>> maps = adamTransactionMapper.dashboardSummaryOfTransaction(comId, beginDate);

        Map<String, String> map = new HashMap<>();
        map.put("AwaitingFunds", "0");
        map.put("FailedPayouts", "0");
        map.put("ProcessingTransactions", "0");
        map.put("CompletedFunding", "0");
        map.put("CompletedConversions", "0");
        map.put("CompletedPayouts", "0");

        if (CollectionUtils.isEmpty(maps)) {
            return map;
        }
        for (Map<String, String> stringMap : maps) {
            String s = stringMap.get("status");
            switch (s) {
                case "awaiting_funds":
                    map.put("AwaitingFunds", stringMap.get("FI"));
                    break;
                case "completed":
                    map.put("CompletedFunding", stringMap.get("FI"));
                    map.put("CompletedConversions", stringMap.get("FX"));
                    map.put("CompletedPayouts", stringMap.get("PO"));
                    break;
                case "failed":
                    map.put("FailedPayouts", stringMap.get("PO"));
                    break;
                case "processing":
                    map.put("ProcessingTransactions", String.valueOf(Integer.parseInt(stringMap.get("PO")) + Integer.parseInt(stringMap.get("FI")) + Integer.parseInt(stringMap.get("FX"))));
                    break;
            }
        }
        return map;

    }

    private TreeMap<String, Map<String, Map<String, String>>> add(Map<String, List<AdamDashboardVo>> source, String[] transactionStatusEnums) {

        if (transactionStatusEnums == null) {
            transactionStatusEnums = new String[]{"ready_to_process", "ready_to_settle", "awaiting_funds", "processing", "cancelled", "failed", "completed" };
        }

        String[] fundDirection = new String[]{AdamTransactionConstants.FundsDirectionEnum.CREDIT.getCode(), AdamTransactionConstants.FundsDirectionEnum.DEBIT.getCode()};

        TreeMap<String, Map<String, Map<String, String>>> map = new TreeMap<>();
        // 循环时间
        for (Map.Entry<String, List<AdamDashboardVo>> i : source.entrySet()) {

            List<AdamDashboardVo> listValue = i.getValue();
            String dateKey = i.getKey();

            Map<String, List<AdamDashboardVo>> collect = listValue.stream().collect(Collectors.groupingBy(AdamDashboardVo::getStatus));

            Map<String, Map<String, String>> map2 = new HashMap<>();

            for (String i1 : transactionStatusEnums) {

                Map<String, String> map3 = new HashMap<>();

                if (collect.containsKey(i1)) {
                    List<AdamDashboardVo> list = collect.get(i1);
                    Map<String, List<AdamDashboardVo>> collect1 = list.stream().collect(Collectors.groupingBy(AdamDashboardVo::getFundDirection));
                    for (String s : fundDirection) {
                        if (!collect1.containsKey(s)) {
                            map3.put(s, String.valueOf(BigDecimal.ZERO));
                        } else {
                            List<AdamDashboardVo> list1 = collect1.get(s);
                            if (s.equals("C")) {
                                map3.put(s, String.valueOf(list1.get(0).getFundAmount()));
                            } else if (s.equals("D")) {
                                map3.put(s, "-" + list1.get(0).getFundAmount());
                            }

                        }
                    }
                    map2.put(i1, map3);

                } else {
                    for (String s : fundDirection) {
                        map3.put(s, String.valueOf(BigDecimal.ZERO));
                    }
                    map2.put(i1, map3);
                }
            }
            map.put(dateKey, map2);

        }

        return map;

    }

//    private Map<String, List<AdamDashboardVo>> add1(Map<String, List<AdamDashboardVo>> source, String[] transactionStatusEnums) {
//
//        if (transactionStatusEnums == null) {
//            transactionStatusEnums = new String[]{"ready_to_process", "ready_to_settle", "awaiting_funds", "processing", "cancelled", "failed", "completed" };
//        }
//        String[] fundDirection = new String[]{AdamTransactionConstants.FundsDirectionEnum.CREDIT.getCode(), AdamTransactionConstants.FundsDirectionEnum.DEBIT.getCode()};
//
//        // 循环时间
//        for (Map.Entry<String, List<AdamDashboardVo>> i : source.entrySet()) {
//            List<AdamDashboardVo> listValue = i.getValue();
//            String dateKey = i.getKey();
//            Map<String, List<AdamDashboardVo>> collect = listValue.stream().collect(Collectors.groupingBy(AdamDashboardVo::getStatus));
//            for (String i1 : transactionStatusEnums) {
//                if (collect.containsKey(i1)) {
//                    List<AdamDashboardVo> list = collect.get(i1);
//                    Map<String, List<AdamDashboardVo>> collect1 = list.stream().collect(Collectors.groupingBy(AdamDashboardVo::getFundDirection));
//                    for (String s : fundDirection) {
//                        if (!collect1.containsKey(s)) {
//                            AdamDashboardVo v1 = new AdamDashboardVo();
//                            v1.setDateTimeAt(dateKey);
//                            v1.setStatus(i1);
//                            v1.setFundDirection(s);
//                            v1.setFundAmount(BigDecimal.ZERO);
//                            listValue.add(v1);
//                        }
//                    }
//
//                } else {
//                    for (String s : fundDirection) {
//                        AdamDashboardVo v1 = new AdamDashboardVo();
//                        v1.setDateTimeAt(dateKey);
//                        v1.setStatus(i1);
//                        v1.setFundDirection(s);
//                        v1.setFundAmount(BigDecimal.ZERO);
//                        listValue.add(v1);
//                    }
//                }
//            }
//            i.setValue(listValue);
//        }
//        return source;
//    }

}
