package cn.pluss.platform.ryx.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.pluss.platform.channel.MakeMoneyService;
import cn.pluss.platform.entity.MakeMoney;
import cn.pluss.platform.entity.MerchantBaseInfo;
import cn.pluss.platform.entity.MerchantChannelStatus;
import cn.pluss.platform.entity.RyxAccessResp;
import cn.pluss.platform.mapper.RyxTransMapper;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.ryx.RyxService;
import cn.pluss.platform.ryx.RyxTransService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.util.RyxConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 瑞银信结算相关方法实现类
 *
 * @author DJH
 */
@Service
@Slf4j
public class RyxTransServiceImpl implements RyxTransService {

    @Setter(onMethod_ = {@Autowired})
    private RyxTransMapper ryxTransMapper;

    @Setter(onMethod_ = {@Autowired})
    private RyxService ryxService;

    @Setter(onMethod_ = {@Autowired, @Qualifier("sxfMakeMoneyService")})
    private MakeMoneyService makeMoneyService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantBaseInfoService merchantBaseInfoService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantChannelStatusService channelStatusService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Override
    public RyxAccessResp reqHistoryTransRecord(String merInId, String tranDates, String transDateEnd) {
        log.info("查询记录开始时间：" + tranDates + "； 截止时间：" + transDateEnd);
        Map<String, Object> paramMap = new HashMap<>(4);
        paramMap.put("s_tranDates", tranDates);
        paramMap.put("s_tranDatee", merInId);
        paramMap.put("s_merInId", merInId);


        return ryxService.reqCommon(paramMap, null, RyxConfig.tranSt);
    }

    @Override
    public RyxAccessResp reqTodayTransRecord(String merInId) {
        Map<String, Object> paramMap = new HashMap<>(2);
        paramMap.put("s_merInId", merInId);

        return ryxService.reqCommon(paramMap, null, RyxConfig.tranStToday);
    }

    @Override
    public List<Map<String, Object>> getNoRecentDayUserPage(String lastDate, int page, int size) {
        return ryxTransMapper.selectRyxTrans(lastDate, page, size);
    }

    @Override
    public void pullTransRecord() {
        Calendar calendar = Calendar.getInstance();
        Date currentDate = calendar.getTime();
        String currentDateStr = DateUtil.format(currentDate, "yyyyMMdd");
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date lastDate = calendar.getTime();
        String lastDateStr = DateUtil.format(lastDate, "yyyyMMdd");

        int page = 1;
        int size = 20;

        List<Map<String, String>> cacheList = new ArrayList<>();

        List<Map<String, Object>> data;

        int count = 0;
        do {
            int preSize = cacheList.size();
            count++;
            log.info("===============开始操作：第{}次, 第{}页==============", count, page);
            data = getNoRecentDayUserPage(currentDateStr, page, size);
            for (Map<String, Object> item : data) {
                String lastSettleDate = (String) item.get("lastSettleDate");
                String merInId = ((String) item.get("merInId"));
                String merchantId = ((String) item.get("merchantId"));

                try {
                    if (!lastSettleDate.equals(lastDateStr)) {
                        // 遍历发现如果已经保存过对应的商编和最终结果时间，那么就跳过该数据
                        boolean flag = false;
                        for (Map<String, String> itemCache : cacheList) {
                            String itemMerInId = itemCache.get("merInId");
                            String itemLastSettleDate = itemCache.get("lastSettleDate");

                            if (merInId.equals(itemMerInId) && lastSettleDate.equals(itemLastSettleDate)) {
                                flag = true;
                                break;
                            }
                        }

                        if (flag) {
                            continue;
                        }

                        HashMap<String, String> cache = Maps.newHashMap();
                        cache.put("merInId", merInId);
                        cache.put("lastSettleDate", lastSettleDate);
                        cacheList.add(cache);

                        // 最后一条结算记录不是昨天，那么需要先使用查询历史数据的接口，查询历史的数据
                        DateTime lastSettleDateTime = DateUtil.parse(lastSettleDate, "yyyyMMdd");
                        calendar.setTime(lastSettleDateTime.toJdkDate());
                        calendar.add(Calendar.DAY_OF_MONTH, +1);
                        Date startTime = calendar.getTime();
                        String startTimeStr = DateUtil.format(startTime, "yyyyMMdd");

                        RyxAccessResp resp = reqHistoryTransRecord(merInId, startTimeStr, lastDateStr);
                        JSONObject result = resp.getResult();

                        save(result, merchantId);
                    }

                    RyxAccessResp resp = reqTodayTransRecord(merInId);
                    JSONObject result = resp.getResult();

                    save(result, merchantId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            /*
             * 长度没有发生变化，则说明当页数据已经被处理过，可能是冗余或者错误数据，可以对下一页数据进行操作
             */
            if (preSize == cacheList.size()) {
                page++;
            }
        } while (data.size() == size);
    }

    @Override
    public void pullYesterdayTransRecord() {
        int page = 1;
        int resolvedCount;
        Map<String, Integer> resolvedMap = new HashMap<>();
        while (true) {
            resolvedCount = 0;
            List<Map<String, Object>> listMap = ryxTransMapper.selectRyxInfoYesterday(page, 100);
            if (listMap == null || listMap.isEmpty()) {
                break;
            }

            for (Map<String, Object> item : listMap) {
                if (resolvedMap.containsKey((String) item.get("merchantId"))) {
                    continue;
                } else {
                    resolvedMap.put((String) item.get("merchantId"), 1);
                }

                try {
                    String merInId = ((String) item.get("merInId"));
                    String merchantId = ((String) item.get("merchantId"));

                    RyxAccessResp resp = reqTodayTransRecord(merInId);
                    JSONObject result = resp.getResult();

                    resolvedCount += save(result, merchantId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (resolvedCount == 0) {
                // 本轮未操作任何一个，就切换下一页
                page++;
            }
        }
    }

    /**
     * @param result  {
     *                "total": 1,
     *                "numberPersonalMessages": null,
     *                "list": [
     *                {
     *                "id": null,
     *                "merId": "390000000437793",
     *                "settDate": "20210225094700",
     *                "status": "出款成功",
     *                "cardName": "郑**",
     *                "cardNo": "6228*****5079",
     *                "amt": 2,
     *                "settFee": 0.01,
     *                "orgId": "OX0000000002983",
     *                "orgName": "J.H武汉融商创银科技有限公司",
     *                "orgMerName": "商户_郑丽端",
     *                "bankName": "中国农业银行云霄县支行营业部",
     *                "failReason": null
     *                }
     *                ],
     *                "numberPublicMessages": null
     * @param merInId 通道商编
     *                }
     */
    public int save(JSONObject result, String merInId) {
        int resolvedCount = 0;
        JSONArray list = result.getJSONArray("list");
        if (list == null) {
            return resolvedCount;
        }

        MerchantBaseInfo merchantBaseInfo = null;
        for (int i = 0; i < list.size(); i++) {
            try {
                JSONObject item = list.getJSONObject(i);
                String settDateTime = item.getString("settDate");
                String merId = item.getString("merId");

                if ("出款失败".equals(item.getString("status"))) {
                    continue;
                }

                if (merchantBaseInfo == null) {
                    MerchantChannelStatus channelStatus = new MerchantChannelStatus();
                    channelStatus.setChannel(3);
                    channelStatus.setMerchantId(merId);
                    channelStatus = channelStatusService.getOne(new QueryWrapper<>(channelStatus));
                    merchantBaseInfo = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(channelStatus.getMerchantCode());
                }

                String settDate = settDateTime.substring(0, 8);

                MakeMoney makeMoney = new MakeMoney();
                makeMoney.setRemark("具体到账时间以银行打款时间为准");
                makeMoney.setBankAccount(item.getString("cardNo"));
                makeMoney.setBankHolder(item.getString("cardName"));
                makeMoney.setBillId(merId + settDate);
                makeMoney.setCreateTime(DateUtil.format(DateUtil.parse(settDateTime, "yyyyMMddHHmmss"), "yyyy-MM-dd HH:mm:ss"));
                makeMoney.setMerchantId(merInId);
                // 单位转为分
                makeMoney.setPlanAmount(item.getBigDecimal("amt").doubleValue() * 100);
                makeMoney.setSuspendAmount(0d);
                makeMoney.setRealAmount(makeMoney.getPlanAmount());
                makeMoney.setState("1");
                if (item.get("failReason") != null) {
                    makeMoney.setFailReason(item.getString("failReason"));
                }
                makeMoney.setSettType("D1");
                makeMoney.setSettDate(settDate.substring(0, 4) + "-" + settDate.substring(4, 6) + "-" + settDate.substring(6, 8));
                makeMoney.setBankretTime(makeMoney.getCreateTime());
                makeMoney.setChannelId("3");
                makeMoney.setThirdStatus(item.getString("status"));

                makeMoneyService.save(makeMoney);
                resolvedCount++;

                List<String> userIds = Collections.singletonList(merchantBaseInfo.getUserId() + "");
                String title = "自动提现成功";
                String content = "到账金额" + (makeMoney.getRealAmount() / 100) + "元，提现门店【" + merchantBaseInfo.getAlias() + "】";
                generalPushUtil.sendAllPlatByAlias(userIds, title, content, "1");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return resolvedCount;
    }
}
