package cn.com.countrygarden.bi.main.service.marketing.impl;

import cn.com.countrygarden.bi.main.dao.common.CommMapper;
import cn.com.countrygarden.bi.main.dao.marketing.CommOperationHistoryMapper;
import cn.com.countrygarden.bi.main.dao.marketing.ContractMapper;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbDesktopResourceMapper;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.MarketingContract;
import cn.com.countrygarden.bi.main.model.common.Comm;
import cn.com.countrygarden.bi.main.model.common.CommConstant;
import cn.com.countrygarden.bi.main.model.marketing.CommOperationHistory;
import cn.com.countrygarden.bi.main.model.marketing.Contract;
import cn.com.countrygarden.bi.main.model.marketing.ContractSummary;
import cn.com.countrygarden.bi.main.model.marketing.Proposal;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbDesktopResource;
import cn.com.countrygarden.bi.main.service.common.CommService;
import cn.com.countrygarden.bi.main.service.common.CooperationTypeService;
import cn.com.countrygarden.bi.main.service.common.ProjectNatureService;
import cn.com.countrygarden.bi.main.service.common.ProjectTypeService;
import cn.com.countrygarden.bi.main.service.marketing.ContractService;
import cn.com.countrygarden.bi.main.service.marketing.model.ContractData;
import cn.com.countrygarden.bi.main.util.DateUtil;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ComparatorUtils;
import org.apache.commons.collections4.comparators.ComparableComparator;
import org.apache.commons.collections4.comparators.ComparatorChain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * Created by chenweijiang on 2017/9/21.
 */
@Service
@Transactional(readOnly = true)
public class ContractServiceImpl implements ContractService {

    @Autowired
    private CooperationTypeService cooperationTypeService;

    @Autowired
    private ProjectNatureService projectNatureService;

    @Autowired
    private ProjectTypeService projectTypeService;

    @Autowired
    private CommService commService;

    @Autowired
    private CommMapper commMapper;

    @Autowired
    private CommOperationHistoryMapper commOperationHistoryMapper;

    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private TbDesktopResourceMapper tbDesktopResourceMapper;

    @Transactional(readOnly = false)
    @Override
    public void parseUploadFile(List<ContractData> dataList, String userCode) {

        if (dataList.size() == 0) {
            return;
        }

        //verify data
        Map<String, Object> projectTypeMap = projectTypeService.projectTypeCache();
        Map<String, Object> cooperationTypeMap = cooperationTypeService.cooperationTypeCache();

        List<String> projectNums = new ArrayList<String>();
        //检证：项目类型、项目性质、合作类型、接管区域
        for (ContractData data : dataList) {
            projectNums.add(data.getProjectNum());
            String projectType = (String) projectTypeMap.get(data.getProjectType());
            if (projectType == null) {
                throw new ServiceException("数据不正确, '" + data.getProjectType() + "'非系统可识别项目类型");
            }
            data.setProjectType(projectType);

            String cooperationType = (String) cooperationTypeMap.get(data.getCorpType());
            if (cooperationType == null) {
                throw new ServiceException("数据不正确, '" + data.getCorpType() + "'非系统可识别合作类型");
            }
            data.setCorpType(cooperationType);

        }

        List<Comm> dbList = commMapper.searchByCommNums(projectNums);
        if (dbList.size() != dataList.size()) {
            throw new ServiceException("数据不正确, 导出数据中有项目未在系统创建,请先到系统中创建并导出项目编号");
        }
        List<Comm> updateList = new ArrayList<Comm>();
        List<Contract> newData = new ArrayList<Contract>();
        List<CommOperationHistory> historyList = new ArrayList<CommOperationHistory>();
        Map<String, Comm> commMap = new HashMap<String, Comm>();
        for (Comm comm : dbList) {
            commMap.put(comm.getCommNum(), comm);
        }
        Date current = new Date();
        for (ContractData data : dataList) {
            Comm comm = commMap.get(data.getProjectNum());
            comm.setName(data.getProjectName());
//            comm.setProjectType(data.getProjectType());
//            comm.setCorpType(data.getCorpType());
            comm.setProjectType(1);
            comm.setCorpType(1);
            if (data.getSignDate() != null) {
                comm.setSignDate(data.getSignDate());
            }
            if (data.getContractCancelDate() != null) {
                comm.setContractCancelDate(data.getContractCancelDate());
            }
            comm.setContractArea(data.getContractArea());
            comm.setGmtModified(current);
            comm.setModifiedBy(userCode);
            comm.setStatus(data.getStatus());
            updateList.add(comm);


            Contract contract = new Contract();
            contract.setCommId(comm.getId());
            contract.setCancelDate(data.getContractCancelDate());
            contract.setContractArea(data.getContractArea());
            contract.setIsDelete((byte) 0);
            contract.setState(data.getStatus());
            contract.setContractDate(data.getSignDate());
            contract.setGmtCreate(current);
            contract.setCreateBy(userCode);
            contract.setGmtModified(current);
            contract.setModifiedBy(userCode);
            newData.add(contract);


            CommOperationHistory history = new CommOperationHistory();
            history.setCommId(comm.getId());
            history.setGmtCreate(current);
            history.setCreateBy(userCode);
            String operationName = "";
            switch (comm.getStatus()) {
                case CommConstant.CommStatus.contract:
                    operationName = CommConstant.OperationName.contract;
                    break;
                case CommConstant.CommStatus.release:
                    operationName = CommConstant.OperationName.release;
                    break;

            }
            history.setName(operationName);
            historyList.add(history);
        }

        commOperationHistoryMapper.insertList(historyList);
        contractMapper.insertList(newData);
        for (Comm comm : updateList) {
            commMapper.updateByPrimaryKey(comm);
        }
    }


    /**
     * 按合作类型汇总本年面积及项目数
     *
     * @return
     */
    public List<ContractSummary> sumThisYearByCorpType() {
        return contractMapper.sumBy(new HashMap<String, Object>() {{
            put("afterDate", DateUtil.getFirstDayOfThisYear());
            put("by", "corpType");
        }});
    }

    /**
     * 按项目类型汇总本年面积及项目数
     *
     * @return
     */
    public List<ContractSummary> sumThisYearByProjectType() {
        return contractMapper.sumBy(new HashMap<String, Object>() {{
            put("afterDate", DateUtil.getFirstDayOfThisYear());
            put("by", "projectType");
        }});
    }

    /**
     * 签约趋势
     *
     * @return
     */
    public List<ContractSummary> tendency() {
        List<ContractSummary> result = contractMapper.tendency(new HashMap<String, Object>() {{
            put("afterDate", DateUtil.getFirstDayOfThisYear());
        }});
        if (result.size() > 0) {
            Comparator cmp = ComparableComparator.comparableComparator();
            cmp = ComparatorUtils.nullLowComparator(cmp);
            ArrayList<Object> sortFields = new ArrayList<Object>();
            sortFields.add(new BeanComparator("month", cmp));
            ComparatorChain multiSort = new ComparatorChain(sortFields);
            Collections.sort(result, multiSort);
        }
        return result;
    }

    /**
     * top 5
     *
     * @return
     */
    public List<ContractSummary> ranking(int limit) {
        return contractMapper.ranking(new HashMap<String, Object>() {{
            put("afterDate", DateUtil.getFirstDayOfThisYear());
            put("year", DateUtil.getYear());
            put("limit", Math.max(5, limit));
        }});
    }

    /**
     * 总签约面积占总接管面积的比例
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> contractAreaInTotalTakeoverArea() {
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        String takeoverArea = "0";
        List<TbDesktopResource> tbDesktopResources = tbDesktopResourceMapper.sumAll();
        if (tbDesktopResources != null && tbDesktopResources.get(0) != null) {
            takeoverArea = tbDesktopResources.get(0).getArea();
        }
        BigDecimal currentContactArea = commMapper.sumCurrentContactArea();
        resultMap.put("takeoverArea", Float.parseFloat(takeoverArea));
        resultMap.put("currentContactArea", currentContactArea);
        resultMap.put("rate", currentContactArea.floatValue() / Float.parseFloat(takeoverArea));
        resultList.add(resultMap);
        return resultList;
    }
}
