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

import cn.com.countrygarden.bi.main.core.AbstractService;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbDesktopResourceMapper;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbDesktopResource;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysOrgan;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbDesktopResourceService;
import cn.com.countrygarden.bi.main.util.MD5;
import cn.com.countrygarden.bi.main.util.RedisCacheUtils;
import cn.com.countrygarden.bi.main.util.RedisUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@Service
@Transactional
public class TbDesktopResourceServiceImpl extends AbstractService<TbDesktopResource> implements TbDesktopResourceService {

    protected final Logger log = LoggerFactory.getLogger(TbDesktopResourceServiceImpl.class);

    @Autowired
    private TbDesktopResourceMapper tbDesktopResourceMapper;

    public TbDesktopResource sumAllFromCache() {
        String redisKey = "bgywy:bi:desktop:resource:sum:all";
        String json;
        TbDesktopResource tbDesktopResource = null;
        ObjectMapper mapper = new ObjectMapper();

        json = RedisUtils.get(redisKey);
        if (json == null || json.equals(null) || json.equals("")) {
            List<TbDesktopResource> resourcesList = tbDesktopResourceMapper.sumAll();
            if (!resourcesList.isEmpty()) {
                tbDesktopResource = resourcesList.get(0);
                try {
                    json = mapper.writeValueAsString(tbDesktopResource);
                    RedisUtils.put(redisKey, json, 300);
                } catch (IOException e) {
                    throw new ServiceException("服务器错误，数据解析异常：" + e.getMessage());
                }
            }
        } else {
            try {
                tbDesktopResource = mapper.readValue(json, TbDesktopResource.class);
            } catch (IOException e) {
                throw new ServiceException("服务器错误，数据解析异常：" + e.getMessage());
            }
        }

        return tbDesktopResource;
    }

    /**
     * 获取用户资源数据
     *
     * @param userCode
     * @param organCode
     * @param commID
     * @return
     */
    public Map<String, Object> sumByUserCodeFromCache(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:resource:",
                900 /* 15 * 60 */,
                param,
                function
        );

        return resource;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @param param
     * @return
     */
    public TbDesktopResource sumByUserCodeFromMapper(Map<String, String> param) {
        TbDesktopResource tbDesktopResource;
        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("")) {
            tbDesktopResource = tbDesktopResourceMapper.sumByUserCodeAndOrganCodeAndCommID(new HashMap<String, Object>() {{
                put("userCode", userCode);
                put("organCode", organCode);
                put("commID", commID);
            }});
        } else if (userCode != null && !userCode.equals("")
                && organCode != null && !organCode.equals("")) {
            tbDesktopResource = tbDesktopResourceMapper.sumByUserCodeAndOrganCode(new HashMap<String, Object>() {{
                put("userCode", userCode);
                put("organCode", organCode);
            }});
        } else if (userCode != null && !userCode.equals("")) {
            tbDesktopResource = tbDesktopResourceMapper.sumByUserCode(userCode);
        } else {
            tbDesktopResource = null;
        }

        return tbDesktopResource;
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private Map<String, Object> sumByUserCodeFromMapperToMap(Map<String, String> param) {
        Map<String, Object> resource = new HashMap<>();
        TbDesktopResource tbDesktopResource = sumByUserCodeFromMapper(param);

        if (tbDesktopResource == null) {
            return resource;
        }

        resource.put("area", tbDesktopResource.getArea());
        resource.put("owner", tbDesktopResource.getOwner());
        resource.put("house", tbDesktopResource.getHouse());
        resource.put("parking", tbDesktopResource.getParking());
        resource.put("business", tbDesktopResource.getBusiness());
        resource.put("building", tbDesktopResource.getBuilding());
        resource.put("room", tbDesktopResource.getRoom());
        resource.put("customer", tbDesktopResource.getCustomer());
        resource.put("innerArea", tbDesktopResource.getInnerArea());
        resource.put("shareArea", tbDesktopResource.getShareArea());
        resource.put("gardenArea", tbDesktopResource.getGardenArea());
        resource.put("businessArea", tbDesktopResource.getBusinessArea());
        resource.put("basementArea", tbDesktopResource.getBasementArea());
        resource.put("houseArea", tbDesktopResource.getHouseArea());
        resource.put("monthNewArea", tbDesktopResource.getMonthNewArea());
        resource.put("monthNewOwner", tbDesktopResource.getMonthNewOwner());
        resource.put("monthNewHouse", tbDesktopResource.getMonthNewHouse());
        resource.put("monthNewParking", tbDesktopResource.getMonthNewParking());
        resource.put("monthNewBusiness", tbDesktopResource.getMonthNewBusiness());
        resource.put("monthNewBuilding", tbDesktopResource.getMonthNewBuilding());
        resource.put("monthNewRoom", tbDesktopResource.getMonthNewRoom());
        resource.put("monthNewCustomer", tbDesktopResource.getMonthNewCustomer());

        return resource;
    }


    /**
     * 基础数据，接管面积区域分布
     *
     * @param userCode
     * @param organCode
     * @param commID
     * @return
     */
    public List<Map<String, String>> sumByOrganByUserCodeFromCache(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>, List<Map<String, String>>> function = p -> sumByOrganByUserCodeFromMapperToList(p);

        List<Map<String, String>> data = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:takeover:organ:",
                900 /* 15 * 60 */,
                param,
                function
        );

        return data;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @param param
     * @return
     */
    public List<TbDesktopResource> sumByOrganByUserCodeFromMapper(Map<String, String> param) {
        List<TbDesktopResource> 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 = tbDesktopResourceMapper.sumByOrganByOrganByUserCodeAndOrganCodeAndCommID(new HashMap<String, Object>() {{
                put("userCode", userCode);
                put("organCode", organCode);
                put("commID", commID);
            }});
        } else if (userCode != null && !userCode.equals("")
                && organCode != null && !organCode.equals("")) {
            data = tbDesktopResourceMapper.sumByOrganByUserCodeAndOrganCode(new HashMap<String, Object>() {{
                put("userCode", userCode);
                put("organCode", organCode);
            }});
        } else if (userCode != null && !userCode.equals("")) {
            data = tbDesktopResourceMapper.sumByOrganByUserCode(userCode);
        } else {
            data = null;
        }

        return data;
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> sumByOrganByUserCodeFromMapperToList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktopResource> resources = sumByOrganByUserCodeFromMapper(param);

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

        for (TbDesktopResource resource : resources) {
            data.add(new HashMap<String, String>() {{
                put("organName", resource.getOrganName());
                put("houseArea", resource.getHouseArea());
                put("businessArea", resource.getBusinessArea());
                put("parking", resource.getParking());
                put("basementArea", resource.getBasementArea());
                put("total", resource.getTotal());
            }});
        }

        return data;
    }


    /**
     * 开发主体
     *
     * @param sysOrgan
     * @param organCode
     * @param commID
     * @return
     */
    public List<Map<String, String>> sumDevelopmentSubjectFromCache(TbSysOrgan sysOrgan, String organCode, String commID) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", sysOrgan.getUserCode());
            put("organCode", organCode);
            put("commID", commID);
            put("isCommLimited", sysOrgan.isCommLimited() ? "1" : "0");
            put("isHeadquarters", sysOrgan.isHeadquarters() ? "1" : "0");
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> sumDevelopmentSubjectFromMapperToList(p);

        List<Map<String, String>> data = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:development:subject:" ,
                1800 /* 15 * 60 */,
                param,
                function
        );

        return data;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @param param
     * @return
     */
    public List<TbDesktopResource> sumDevelopmentSubjectFromMapper(Map<String, String> param) {
        return tbDesktopResourceMapper.sumDevelopmentSubjectByUserCode(param);
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> sumDevelopmentSubjectFromMapperToList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktopResource> resources = sumDevelopmentSubjectFromMapper(param);

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

        for (TbDesktopResource resource : resources) {
            data.add(new HashMap<String, String>() {{
                put("name", resource.getDevelopmentSubject());
                put("value", resource.getRoom());
                put("valueArea", resource.getArea());
            }});
        }

        return data;
    }

    /**
     * 物业业态
     *
     * @param sysOrgan
     * @param organCode
     * @param commID
     * @return
     */
    public List<Map<String, String>> sumPropertyFormatFromCache(TbSysOrgan sysOrgan, String organCode, String commID) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", sysOrgan.getUserCode());
            put("organCode", organCode);
            put("commID", commID);
            put("isCommLimited", sysOrgan.isCommLimited() ? "1" : "0");
            put("isHeadquarters", sysOrgan.isHeadquarters() ? "1" : "0");
        }};
        Function<Map<String, String>, List<Map<String, String>>> function = p -> sumPropertyFormatFromMapperToList(p);

        List<Map<String, String>> data = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:property:format:" ,
                1800 /* 15 * 60 */,
                param,
                function
        );

        return data;
    }

    /**
     * 根据参数获取 resource 汇总
     *
     * @param param
     * @return
     */
    public List<TbDesktopResource> sumPropertyFormatFromMapper(Map<String, String> param) {
        return tbDesktopResourceMapper.sumPropertyFormatByUserCode(param);
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> sumPropertyFormatFromMapperToList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktopResource> resources = sumPropertyFormatFromMapper(param);

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

        for (TbDesktopResource resource : resources) {
            data.add(new HashMap<String, String>() {{
                put("name", resource.getPropertyForm());
                put("value", resource.getRoom());
                put("valueArea", resource.getArea());
            }});
        }

        return data;
    }

    /**
     * 物业业态
     *
     * @param userCode
     * @param organCode
     * @param commID
     * @return
     */
    public List<Map<String, String>> sumByUserCodeByProvinceFromCache(String userCode, String organCode, String commID) {
        Map<String, String> param = new HashMap<String, String>() {{
            put("userCode", userCode);
            put("organCode", organCode);
            put("commID", commID);
        }};
        log.info("param: " + param);
        Function<Map<String, String>, List<Map<String, String>>> function = p -> sumByUserCodeByProvinceFromMapperToList(p);

        List<Map<String, String>> data = RedisCacheUtils.rememberList(
                "biapp:desktop:resource:basic:province:" ,
                1800 /* 15 * 60 */,
                param,
                function
        );

        return data;
    }

    /**
     * 基础资源数据省份分布
     *
     * @param param
     * @return
     */
    public List<TbDesktopResource> sumByUserCodeByProvinceFromMapper(Map<String, String> param) {
        return tbDesktopResourceMapper.sumByUserCodeByProvince(param);
    }

    /**
     * 解析成 Map 以便于 redis 保存、解析
     *
     * @param param
     * @return
     */
    private List<Map<String, String>> sumByUserCodeByProvinceFromMapperToList(Map<String, String> param) {
        List<Map<String, String>> data = new ArrayList<>();
        List<TbDesktopResource> resources = tbDesktopResourceMapper.sumByUserCodeByProvince(param);

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

        for (TbDesktopResource resource : resources) {
            data.add(new HashMap<String, String>() {{
                put("province", resource.getProvince());
                put("area", resource.getArea());
                put("comms", String.valueOf(resource.getComms()));
            }});
        }

        return data;
    }
}
