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.ChargeMapper;
import cn.com.countrygarden.bi.main.dao.marketing.CommOperationHistoryMapper;
import cn.com.countrygarden.bi.main.dao.marketing.ProposalMapper;
import cn.com.countrygarden.bi.main.dao.marketing.QuotaMapper;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbDeskTopFeesDailyMapper;
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.common.Comm;
import cn.com.countrygarden.bi.main.model.common.CommConstant;
import cn.com.countrygarden.bi.main.model.marketing.*;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbDeskTopFeesDaily;
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.ChargeService;
import cn.com.countrygarden.bi.main.service.marketing.model.ChargeData;
import cn.com.countrygarden.bi.main.service.marketing.model.ChargeSeasonsReport;
import cn.com.countrygarden.bi.main.service.marketing.model.ChargeSummaryReport;
import cn.com.countrygarden.bi.main.service.marketing.model.ProposalData;
import cn.com.countrygarden.bi.main.util.DateUtil;
import cn.com.countrygarden.bi.main.util.NumberUtil;
import cn.com.countrygarden.bi.main.util.RedisUtils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

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


    @Autowired
    private CommService commService;

    @Autowired
    private CommMapper commMapper;

    @Autowired
    private CommOperationHistoryMapper commOperationHistoryMapper;

    @Autowired
    private ChargeMapper chargeMapper;

    @Autowired
    private QuotaMapper quotaMapper;

    @Autowired
    private TbDesktopResourceMapper tbDesktopResourceMapper;

    @Resource
    private TbDeskTopFeesDailyMapper tbDeskTopFeesDailyMapper;

    @Transactional(readOnly = false)
    @Override
    public void parseUploadFile(List<ChargeData> dataList, String userCode, boolean isIncrease) {
        if (dataList.size() == 0) {
            return;
        }

        //verify data
        Map<String, Object> organNameMap = commService.findOrganNameMapCache();
        List<String> projectNums = new ArrayList<String>();
        //检证：项目类型、项目性质、合作类型、接管区域
        for (ChargeData data : dataList) {
            projectNums.add(data.getProjectNum());

            if (!StringUtils.isEmpty(data.getOrgan())) {
                String organCode = (String) organNameMap.get(data.getOrgan());
                if (organCode == null) {
                    throw new ServiceException("数据不正确, '" + data.getOrgan() + "'非系统可区域，请填入ERP系统现有区域");
                }
                data.setOrganId(organCode);
            }
        }

        List<Comm> dbList = commMapper.searchByCommNums(projectNums);
        if (dbList.size() != dataList.size()) {
            throw new ServiceException("数据不正确, 导出数据中有项目未在系统创建,请先到系统中创建并导出项目编号");
        }
        List<Comm> updateList = new ArrayList<Comm>();
        List<Charge> newData = new ArrayList<Charge>();

        Map<String, Comm> commMap = new HashMap<String, Comm>();
        for (Comm comm : dbList) {
            commMap.put(comm.getCommNum(), comm);
        }
        Date current = new Date();
        for (ChargeData data : dataList) {
            Comm comm = commMap.get(data.getProjectNum());
            if (!isIncrease) {

                comm.setName(data.getProjectName());
                comm.setOrganId(data.getOrganId());
                comm.setAdditionalCharge(data.getAdditionalCharge() ? (byte) 1 : (byte) 0);
                comm.setGmtModified(current);
                comm.setModifiedBy(userCode);
                comm.setNcAccount(data.getNcAccount());
                comm.setNcNumber(data.getNcNumber());
                comm.setDevelopSubject(data.getDevelopSubject());
                comm.setChargeArea(data.getChargeArea());
                updateList.add(comm);

                Charge charge = new Charge();
                charge.setCommId(comm.getId());
                charge.setAdditionalCharge(data.getAdditionalCharge());
                charge.setChargeArea(data.getChargeArea());
                charge.setStartDate(data.getStartDate());
                charge.setEndDate(data.getEndDate());
                charge.setNcSystemCode(data.getNcNumber());
                charge.setNcSystemName(data.getNcAccount());
                charge.setIsDelete(new Byte((byte) 0));
                charge.setIncreaseCharge(isIncrease);
                charge.setCreateBy(userCode);
                charge.setModifiedBy(userCode);
                charge.setGmtCreate(current);
                charge.setGmtModified(current);
                charge.setMemo(data.getMemo());
                newData.add(charge);
            } else {
                //季度数为复盖
                Charge chargeQuery = new Charge();
                chargeQuery.setCommId(comm.getId());
                chargeQuery.setIncreaseCharge(isIncrease);
                chargeQuery.setStartDate(data.getStartDate());
                chargeQuery.setIsDelete((byte) 0);
                chargeQuery.setEndDate(data.getEndDate());
                List<Charge> chargeList = chargeMapper.select(chargeQuery);
                if (chargeList.size() > 0) {
                    Charge charge = chargeList.get(0);
                    charge.setAdditionalCharge(data.getAdditionalCharge());
                    charge.setChargeArea(data.getChargeArea());
                    charge.setStartDate(data.getStartDate());
                    charge.setEndDate(data.getEndDate());
                    charge.setNcSystemCode(data.getNcNumber());
                    charge.setNcSystemName(data.getNcAccount());
                    charge.setIsDelete(new Byte((byte) 0));
                    charge.setModifiedBy(userCode);
                    charge.setGmtModified(current);
                    charge.setMemo(data.getMemo());
                    chargeMapper.updateByPrimaryKey(charge);
                } else {
                    Charge charge = new Charge();
                    charge.setCommId(comm.getId());
                    charge.setAdditionalCharge(data.getAdditionalCharge());
                    charge.setChargeArea(data.getChargeArea());
                    charge.setStartDate(data.getStartDate());
                    charge.setEndDate(data.getEndDate());
                    charge.setNcSystemCode(data.getNcNumber());
                    charge.setNcSystemName(data.getNcAccount());
                    charge.setIsDelete(new Byte((byte) 0));
                    charge.setIncreaseCharge(isIncrease);
                    charge.setCreateBy(userCode);
                    charge.setModifiedBy(userCode);
                    charge.setGmtCreate(current);
                    charge.setGmtModified(current);
                    charge.setMemo(data.getMemo());
                    newData.add(charge);
                }
            }


        }
        if (newData.size() > 0) {
            chargeMapper.insertList(newData);
        }

        for (Comm comm : updateList) {
            commMapper.updateByPrimaryKey(comm);
        }
    }


    public ChargeSummaryReport chargeSummaryReportOld() {
        ChargeSummaryReport report = new ChargeSummaryReport();
        List<ChargeSeasonsReport> seasons = new ArrayList<ChargeSeasonsReport>();
        report.setSeasons(seasons);
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        Map<String, Object> quotaQuery = new HashMap<String, Object>();
        quotaQuery.put("year", Short.parseShort(year + ""));
        Quota quotaSummary = quotaMapper.sum(quotaQuery);
        if (quotaSummary == null) {
            quotaSummary = new Quota();
            quotaSummary.setChargeArea1st(new BigDecimal(0));
            quotaSummary.setChargeArea2nd(new BigDecimal(0));
            quotaSummary.setChargeArea3rd(new BigDecimal(0));
            quotaSummary.setChargeArea4th(new BigDecimal(0));
        }
        BigDecimal quota = new BigDecimal(0);

        SimpleDateFormat firstDateFormat = new SimpleDateFormat("yyyy-01-01");
        SimpleDateFormat lastDateFormat = new SimpleDateFormat("yyyy-01-01");
        Date startDate = DateUtil.parseDate(firstDateFormat.format(calendar.getTime()));
        Date endDate = DateUtil.parseDate(lastDateFormat.format(calendar.getTime()));
        Map<String, Object> chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", startDate);
        chargeQuery.put("endDate", endDate);
        chargeQuery.put("additionalCharge", Boolean.TRUE);
        BigDecimal special = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        chargeQuery.put("additionalCharge", Boolean.FALSE);
        BigDecimal normal = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        special = NumberUtil.toTenOfThousand(special);
        normal = NumberUtil.toTenOfThousand(normal);
        BigDecimal area = special.add(normal);
        report.setNormal(normal);
        report.setArea(area);
        report.setSpecial(special);

        Date[] dateRang = DateUtil.getQuarterTime(year, 1);
        chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", dateRang[0]);
        chargeQuery.put("endDate", dateRang[1]);
        BigDecimal areaSeason1 = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        areaSeason1 = NumberUtil.toTenOfThousand(areaSeason1);
        ChargeSeasonsReport season1 = new ChargeSeasonsReport();
        season1.setArea(areaSeason1);
        BigDecimal quotaSeason1 = quotaSummary.getChargeArea1st();
        quotaSeason1 = NumberUtil.toTenOfThousand(quotaSeason1);
        season1.setQuota(quotaSeason1);
        quota = quota.add(quotaSeason1);
        season1.setX("第一季度");
        seasons.add(season1);


        dateRang = DateUtil.getQuarterTime(year, 2);
        chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", dateRang[0]);
        chargeQuery.put("endDate", dateRang[1]);
        BigDecimal areaSeason2 = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        areaSeason2 = NumberUtil.toTenOfThousand(areaSeason2);
        ChargeSeasonsReport season2 = new ChargeSeasonsReport();
        season2.setArea(areaSeason2);
        BigDecimal quotaSeason2 = quotaSummary.getChargeArea2nd();
        quotaSeason2 = NumberUtil.toTenOfThousand(quotaSeason2);
        season2.setQuota(quotaSeason2);
        quota = quota.add(quotaSeason2);
        season2.setX("第二季度");
        seasons.add(season2);

        dateRang = DateUtil.getQuarterTime(year, 3);
        chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", dateRang[0]);
        chargeQuery.put("endDate", dateRang[1]);
        BigDecimal areaSeason3 = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        areaSeason3 = NumberUtil.toTenOfThousand(areaSeason3);
        ChargeSeasonsReport season3 = new ChargeSeasonsReport();
        season3.setArea(areaSeason3);
        BigDecimal quotaSeason3 = quotaSummary.getChargeArea3rd();
        quotaSeason3 = NumberUtil.toTenOfThousand(quotaSeason3);
        season3.setQuota(quotaSeason3);
        quota = quota.add(quotaSeason3);
        season3.setX("第三季度");
        seasons.add(season3);

        dateRang = DateUtil.getQuarterTime(year, 4);
        chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", dateRang[0]);
        chargeQuery.put("endDate", dateRang[1]);
        BigDecimal areaSeason4 = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        areaSeason4 = NumberUtil.toTenOfThousand(areaSeason4);
        ChargeSeasonsReport season4 = new ChargeSeasonsReport();
        season4.setArea(areaSeason4);
        BigDecimal quotaSeason4 = quotaSummary.getChargeArea4th();
        quotaSeason4 = NumberUtil.toTenOfThousand(quotaSeason4);
        season4.setQuota(quotaSeason4);
        quota = quota.add(quotaSeason4);
        season4.setX("第四季度");
        seasons.add(season4);

        report.setQuota(quota);
        return report;
    }

    /**
     * 本年收费面积完成率
     *
     * @return
     */
    @Override
    public ChargeSummaryReport chargeSummaryReport() {
        ChargeSummaryReport report = new ChargeSummaryReport();
        //先读缓存，加快速度
        String key = "biapp:marketing:chargeSummaryReport";
        String s = RedisUtils.get(key);
        if (s != null && !"".equals(s)) {
            report = JSONObject.parseObject(s,ChargeSummaryReport.class);
            return report;
        }



        List<ChargeSeasonsReport> seasons = new ArrayList<ChargeSeasonsReport>();
        report.setSeasons(seasons);
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        Map<String, Object> quotaQuery = new HashMap<String, Object>();
        quotaQuery.put("year", Short.parseShort(year + ""));
        Quota quotaSummary = quotaMapper.sum(quotaQuery);
        if (quotaSummary == null) {
            quotaSummary = new Quota();
            quotaSummary.setChargeArea1st(new BigDecimal(0));
            quotaSummary.setChargeArea2nd(new BigDecimal(0));
            quotaSummary.setChargeArea3rd(new BigDecimal(0));
            quotaSummary.setChargeArea4th(new BigDecimal(0));
        }
        Map<String, Object> realChargeAreaMap = new HashMap<>();
        List<TbDeskTopFeesDaily> tbDeskTopFeesDailyList = tbDeskTopFeesDailyMapper.seasonRealChargeArea();
        for (int i = 0; i < tbDeskTopFeesDailyList.size(); i++) {
            realChargeAreaMap.put("season" + (i + 1), tbDeskTopFeesDailyList.get(i).getChargeArea());
        }

        //TODO 中常规业态面积和特殊业态面积逻辑未清晰，暂时使用旧的逻辑
        SimpleDateFormat firstDateFormat = new SimpleDateFormat("yyyy-01-01");
        SimpleDateFormat lastDateFormat = new SimpleDateFormat("yyyy-01-01");
        Date startDate = DateUtil.parseDate(firstDateFormat.format(calendar.getTime()));
        Date endDate = DateUtil.parseDate(lastDateFormat.format(calendar.getTime()));
        Map<String, Object> chargeQuery = new HashMap<String, Object>();
        chargeQuery.put("startDate", startDate);
        chargeQuery.put("endDate", endDate);
        chargeQuery.put("additionalCharge", Boolean.TRUE);
        BigDecimal special = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        chargeQuery.put("additionalCharge", Boolean.FALSE);
        BigDecimal normal = chargeMapper.sumIncreaseChargeArea(chargeQuery);
        special = NumberUtil.toTenOfThousand(special);
        normal = NumberUtil.toTenOfThousand(normal);
        BigDecimal area = special.add(normal);
        report.setNormal(normal);//中常规业态面积
        report.setArea(area);//已完成签约面积,前端已经不用了
        report.setSpecial(special);//特殊业态面积


        BigDecimal quota = new BigDecimal(0);


        ChargeSeasonsReport season1 = new ChargeSeasonsReport();
        BigDecimal quotaSeason1 = quotaSummary.getChargeArea1st();
        quotaSeason1 = NumberUtil.toTenOfThousand(quotaSeason1);
        //设置第一季度的目标收费面积
        season1.setQuota(quotaSeason1);
        // 设置第一季度的实际收费面积
        season1.setArea(BigDecimal.valueOf(realChargeAreaMap.get("season1") == null ? 0 : Double.valueOf(realChargeAreaMap.get("season1").toString()) / 10000));
        quota = quota.add(quotaSeason1);
        season1.setX("第一季度");
        seasons.add(season1);

        //第二季度
        ChargeSeasonsReport season2 = new ChargeSeasonsReport();
        BigDecimal quotaSeason2 = quotaSummary.getChargeArea2nd();
        quotaSeason2 = NumberUtil.toTenOfThousand(quotaSeason2);
        //设置第一季度的目标收费面积
        season2.setQuota(quotaSeason2);
        // 设置第一季度的实际收费面积
        season2.setArea(BigDecimal.valueOf(realChargeAreaMap.get("season2") == null ? 0 : Double.valueOf(realChargeAreaMap.get("season2").toString()) / 10000));
        quota = quota.add(quotaSeason2);
        season2.setX("第二季度");
        seasons.add(season2);

        //第三季度
        ChargeSeasonsReport season3 = new ChargeSeasonsReport();
        BigDecimal quotaSeason3 = quotaSummary.getChargeArea3rd();
        quotaSeason3 = NumberUtil.toTenOfThousand(quotaSeason3);
        //设置第一季度的目标收费面积
        season3.setQuota(quotaSeason3);
        // 设置第一季度的实际收费面积
        season3.setArea(BigDecimal.valueOf(realChargeAreaMap.get("season3") == null ? 0 : Double.valueOf(realChargeAreaMap.get("season3").toString()) / 10000));
        quota = quota.add(quotaSeason3);
        season3.setX("第三季度");
        seasons.add(season3);

        //第四季度
        ChargeSeasonsReport season4 = new ChargeSeasonsReport();
        BigDecimal quotaSeason4 = quotaSummary.getChargeArea4th();
        quotaSeason4 = NumberUtil.toTenOfThousand(quotaSeason4);
        //设置第一季度的目标收费面积
        season4.setQuota(quotaSeason4);
        // 设置第一季度的实际收费面积
        season4.setArea(BigDecimal.valueOf(realChargeAreaMap.get("season4") == null ? 0 : Double.valueOf(realChargeAreaMap.get("season4").toString()) / 10000));
        quota = quota.add(quotaSeason4);
        season4.setX("第四季度");
        seasons.add(season4);


        report.setQuota(quota);//目标签约面积,前端已经不用了
        String jsonString = JSONObject.toJSONString(report);
        RedisUtils.put(key, jsonString, 60 * 60 * 12);
        return report;
    }

    /**
     * 当前收费面积排行
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> rankingThisYear() {
        List<Map<String, Object>> rankings = new ArrayList<>();

        Map<String, Object> organs = commService.findOrganMapCache();
        int year = DateUtil.getYear();
        List<ChargeResult> chargeResults = chargeMapper.ranking(year + "-01-01", year + "-12-31");
        for (ChargeResult chargeResult : chargeResults) {
            Map<String, Object> item = new HashMap<>();
            String organId = chargeResult.getOrganId();
            item.put("organId", organId);
            item.put("organName", organs.getOrDefault(organId, ""));
            item.put("chargeArea", chargeResult.getChargeArea());

            rankings.add(item);
        }

        return rankings;
    }

    @Override
    public List<Map<String, Object>> chargeAreaInTotalTakeoverArea() {
        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 currentChargeArea = commMapper.sumCurrentChargeArea();
        resultMap.put("takeoverArea", Float.parseFloat(takeoverArea));
        resultMap.put("currentChargeArea", currentChargeArea);
        resultMap.put("rate", currentChargeArea.floatValue() / Float.parseFloat(takeoverArea));
        resultList.add(resultMap);
        return resultList;
    }


}
