package cn.com.countrygarden.bi.main.service.twerp.hm.impl;

import cn.com.countrygarden.bi.main.core.AbstractService;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbDesktop经营主题Mapper;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbDesktop经营主题;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysOrgan;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbDesktop经营主题Service;
import cn.com.countrygarden.bi.main.util.MD5;
import cn.com.countrygarden.bi.main.util.RedisCacheUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;


/**
 * Created by CodeGenerator on 2017/08/10.
 */
@Service
@Transactional
public class TbDesktop经营主题ServiceImpl extends AbstractService<TbDesktop经营主题> implements TbDesktop经营主题Service {
    @Resource
    private TbDesktop经营主题Mapper mapper;

    protected final Logger logger = LoggerFactory.getLogger(TbDesktop经营主题ServiceImpl.class);

    private String TW_ERP_UPLOADFILES_PREFIX = "http://218.13.58.36:8008/HM/M_Main";

    /**
     * 获取用户资源数据
     *
     * @param userCode
     * @param organCode
     * @param commID
     * @return
     */
    public Map<String, Object> findByUserSysOrganFromCache(String userCode, String organCode, String commID) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", userCode);
            put("organCode", organCode);
            put("commID", commID);
        }};
        Function<Map<String, String>, Map<String, Object>> function = p -> sumByUserCodeFromMapperToMap(p);

        Map<String, Object> resource = RedisCacheUtils.rememberMap(
                "biapp:desktop:operation:subject:coreindex:" ,
                1800 /* 15 * 60 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 根据参数获取各种率
     *
     * @param param
     * @return
     */
    public TbDesktop经营主题 findByUserSysOrganFromMapper(Map<String, String> param) {
        int commID = Integer.parseInt(param.getOrDefault("commID", "0"));
        commID = commID > 0 ? commID : -1;
        param.put("commID", String.valueOf(commID));
        return mapper.findByUserSysOrgan(param);
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private Map<String, Object> sumByUserCodeFromMapperToMap(Map<String, String> param) {
        Map<String, Object> data = new HashMap<>();
        TbDesktop经营主题 rate = findByUserSysOrganFromMapper(param);

        if (rate == null) {
            return data;
        }

        data.put("recovery", rate.get本年累计追缴率());
        data.put("charge", rate.get本年综合收费率());
        data.put("arrearsRecovery", rate.get本年欠费追缴率());

        float recoveryRate = rate.getRecoveryrate();
        if (recoveryRate == 0) {
            recoveryRate = 80;
        }
        data.put("recoveryIntent", recoveryRate);
        float chargerate = rate.getChargerate();
        if (chargerate == 0) {
            chargerate = 80;
        }
        data.put("chargeIntent", chargerate);
        float arrearsRecoveryRate = rate.getArrearsrecoveryrate();
        if (arrearsRecoveryRate == 0) {
            arrearsRecoveryRate = 80;
        }
        data.put("arrearsRecoveryIntent", arrearsRecoveryRate);

        return data;
    }


    /**
     * 获取首页收入数据
     *
     * @param userCode
     * @param organCode
     * @param commID
     * @return
     */
    public Map<String, Object> sumHomeMainIncomeFromCache(String userCode, String organCode, String commID) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", userCode);
            put("organCode", organCode);
            put("commID", commID);
        }};
        Function<Map<String, String>, Map<String, Object>> function = p -> sumHomeMainIncomeFromMapperToMap(p);

        Map<String, Object> resource = RedisCacheUtils.rememberMap(
                "biapp:desktop:operation:subject:home:income:",
                1800 /* 15 * 60 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 根据参数获取各种收入数据
     *
     * @param param
     * @return
     */
    public TbDesktop经营主题 sumHomeMainIncomeFromMapper(Map<String, String> param) {
        TbDesktop经营主题 data;
        String userCode = param.getOrDefault("userCode", "");
        String organCode = param.getOrDefault("organCode", "");
        String commID = param.getOrDefault("commID", "");

        if (userCode != null && !userCode.equals("")
                && organCode != null && !organCode.equals("")
                && commID != null && !commID.equals("")) {
            data = mapper.sumHomeMainIncomeByUserCodeAndOrganCodeAndCommID(new HashMap<String, String>() {{
                put("userCode", userCode);
                put("organCode", organCode);
                put("commID", commID);
            }});
        } else if (userCode != null && !userCode.equals("")
                && organCode != null && !organCode.equals("")) {
            data = mapper.sumHomeMainIncomeByUserCodeAndOrganCode(new HashMap<String, String>() {{
                put("userCode", userCode);
                put("organCode", organCode);
            }});
        } else if (userCode != null && !userCode.equals("")) {
            data = mapper.sumHomeMainIncomeByUserCode(userCode);
        } else {
            data = null;
        }
        return data;
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private Map<String, Object> sumHomeMainIncomeFromMapperToMap(Map<String, String> param) {
        Map<String, Object> data = new HashMap<>();
        TbDesktop经营主题 rate = sumHomeMainIncomeFromMapper(param);

        if (rate == null) {
            return data;
        }

        data.put("receivableThisYear", rate.get本年理论应收());
        data.put("receivableThisMonth", rate.get本月应收());

        data.put("receiptsThisYear", rate.get本年累计实收());
        data.put("receiptsThisMonth", rate.get本月实收());

        data.put("parkings", rate.get车位数量());
        data.put("parkingIncome", rate.get车位收入());

        data.put("arrearsPreviousYears", rate.get年初往年欠费());
        data.put("arrearsRecovery", rate.get本年累计追缴金额());

        return data;
    }


    /**
     * 区域收费率排行
     *
     * @param userCode
     * @return
     */
    public List<Map<String, String>> rankingChargeRateFromCache(String userCode, boolean yesterday) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", userCode);
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> rankingChargeRateFromMapperToArrayList(p);

        String dateString = yesterday ? getYesterdayString() : getTodayString();
        List<Map<String, String>> resource = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:charge:rate:" + dateString + ":" + MD5.GetMD5Code(param.toString()),
                604800 /* 7 * 86400 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 区域收费率排行
     *
     * @param sysOrgan
     * @return
     */
    public List<Map<String, String>> rankingChargeRateFromCache(TbSysOrgan sysOrgan, boolean yesterday) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", sysOrgan.getUserCode());
            put("isCommLimited", sysOrgan.isCommLimited() ? "1" : "0");
            put("isHeadquarters", sysOrgan.isHeadquarters() ? "1" : "0");
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> rankingChargeRateFromMapperToArrayList(p);

        String dateString = yesterday ? getYesterdayString() : getTodayString();
        List<Map<String, String>> resource = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:charge:rate:"
                        + dateString + ":"
                        + sysOrgan.getUserCode() + ":"
                        + sysOrgan.isHeadquarters() + ":"
                        + sysOrgan.isCommLimited(),
                604800 /* 7 * 86400 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @return
     */
    public List<TbDesktop经营主题> rankingChargeRateFromMapper(String userCode) {
        return mapper.rankingChargeRate(userCode);
    }

    /**
     * 解析成 ArrayList 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> rankingChargeRateFromMapperToArrayList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktop经营主题> states = mapper.rankingChargeRate(param);

        if (states == null) {
            return data;
        }

        Integer count = 1;
        for (TbDesktop经营主题 state : states) {
            Map<String, String> item = new HashMap<String, String>() {{
                put("organName", state.getOrganname());
                put("photo", prefixERPPhoto(state.getOrganmanagephoto()));
                put("general", String.valueOf(state.get本年综合收费率())); // zh
                put("received", String.valueOf(state.get本年已收收费率()));
                put("receivableNotReceived", String.valueOf(state.get本年应收未收收费率()));
                put("vacancy", String.valueOf(state.get本年空置收费率()));
            }};

            item.put("sort", String.valueOf(count++));

            data.add(item);
        }

        return data;
    }


    /**
     * 区域追缴率排行
     *
     * @param userCode
     * @return
     */
    public List<Map<String, String>> rankingChaseRateFromCache(String userCode, boolean yesterday) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", userCode);
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> rankingChaseRateFromMapperToArrayList(p);
        String dateString = yesterday ? getYesterdayString() : getTodayString();
        List<Map<String, String>> resource = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:chase:rate:" + dateString + ":" + MD5.GetMD5Code(param.toString()),
                1800 /* 15 * 60 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 区域追缴率排行
     *
     * @param sysOrgan
     * @return
     */
    public List<Map<String, String>> rankingChaseRateFromCache(TbSysOrgan sysOrgan, boolean yesterday) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", sysOrgan.getUserCode());
            put("isCommLimited", sysOrgan.isCommLimited() ? "1" : "0");
            put("isHeadquarters", sysOrgan.isHeadquarters() ? "1" : "0");
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> rankingChaseRateFromMapperToArrayList(p);
        String dateString = yesterday ? getYesterdayString() : getTodayString();
        List<Map<String, String>> resource = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:chase:rate:"
                        + dateString + ":"
                        + sysOrgan.getOrganCode() + ":"
                        + sysOrgan.isHeadquarters() + ":"
                        + sysOrgan.isCommLimited(),
                1800 /* 15 * 60 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @return
     */
    public List<TbDesktop经营主题> rankingChaseRateFromMapper(String userCode) {
        return mapper.rankingChaseRate(userCode);
    }

    /**
     * 解析成 ArrayList 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> rankingChaseRateFromMapperToArrayList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktop经营主题> states = mapper.rankingChaseRate(param);

        if (states == null) {
            return data;
        }

        Integer count = 1;
        for (TbDesktop经营主题 state : states) {
            Map<String, String> item = new HashMap<String, String>() {{
                put("organName", state.getOrganname());
                put("photo", prefixERPPhoto(state.getOrganmanagephoto()));
                put("recovered", String.valueOf(state.get本年累计追缴率())); // zh
                put("recoveredReceived", String.valueOf(state.get本年累计追缴已收追缴率()));
                put("receivableNotReceived", String.valueOf(state.get本年累计追缴应收未收追缴率()));
                put("vacancy", String.valueOf(state.get本年累计追缴空置追缴率()));
            }};

            item.put("sort", String.valueOf(count++));

            data.add(item);
        }

        return data;
    }

    /**
     * 处理天问图片路径
     *
     * @param photo
     * @return
     */
    private String prefixERPPhoto(String photo) {
        if (photo == "" || photo.equals("") || photo == null) {
            return photo;
        }

        if (photo.equals("img/res/logo.jpg")) {
            return TW_ERP_UPLOADFILES_PREFIX + "/" + photo;
        }

        if (photo.length() > 14 && !photo.substring(0, 14).equals("../UploadFiles/")) {
            return TW_ERP_UPLOADFILES_PREFIX + photo.substring(2);
        }

        return photo;
    }

    private String getTodayString() {
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        return dateTime.format(formatter);
    }

    private String getYesterdayString() {
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
        LocalDateTime yesterdayDateTime = dateTime.minusDays(1);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        return yesterdayDateTime.format(formatter);
    }
}
