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

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.core.Result;
import cn.com.countrygarden.bi.main.dao.dup.BuoyDataMapper;
import cn.com.countrygarden.bi.main.dao.dup.BuoyDataStatusMapper;
import cn.com.countrygarden.bi.main.dao.sys.PilotCommMapper;
import cn.com.countrygarden.bi.main.dao.twerp.hm.TbHsprCommunityMapper;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.dup.BuoyData;
import cn.com.countrygarden.bi.main.model.dup.BuoyDataConstant;
import cn.com.countrygarden.bi.main.model.dup.BuoyDataStatus;
import cn.com.countrygarden.bi.main.model.dup.BuoyQueryData;
import cn.com.countrygarden.bi.main.model.sys.PilotComm;
import cn.com.countrygarden.bi.main.model.twerp.ErpCommunity;
import cn.com.countrygarden.bi.main.service.dup.BuoyDataService;
import cn.com.countrygarden.bi.main.util.DateUtil;
import cn.com.countrygarden.bi.main.util.NumberUtil;
import com.github.pagehelper.PageRowBounds;
import org.apache.commons.collections4.MultiMapUtils;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.util.*;

/**
 * Created by chenweijiang on 2017/9/12.
 */
@Service
@Transactional
public class BuoyDataServiceImpl implements BuoyDataService {
    @Autowired
    private BuoyDataMapper buoyDataMapper;
    @Autowired
    private BuoyDataStatusMapper buoyDataStatusMapper;

    @Autowired
    private PilotCommMapper pilotCommMapper;

    @Autowired
    private TbHsprCommunityMapper tbHsprCommunityMapper;

    @Override
    public Result query(Boolean isUnFinished,String userCode,String organCode, String commId, String startDateStr, String endDateStr,boolean isSum,int size, int page){
        List<BuoyQueryData> resultList = new ArrayList<BuoyQueryData>();
        Date[] dateRange = DateUtil.convertWeekRange(startDateStr,endDateStr);
        if(dateRange.length>12){
            throw new ServiceException("请选择时间跨度为6周时间");
        }
        for(int i=0;i<dateRange.length;i=i+2){
            prepareUnFillData(dateRange[i],dateRange[i+1],userCode);
        }
        int pilotNum = pilotCommMapper.selectCount(new PilotComm());
        PilotComm pilotQuery = new PilotComm();
        if(!StringUtils.isEmpty(organCode)){
            pilotQuery.setOrganCode(organCode);
        }

        if(!isSum){
            if(!StringUtils.isEmpty(commId)){
                pilotQuery.setCommId(commId);
            }

        }
        List<PilotComm> pilots = pilotCommMapper.select(pilotQuery);
        List<String> organCodes = new ArrayList<String>();
        List<String> commIds = new ArrayList<String>();
        MultiValuedMap<String,PilotComm> orgMaps = new ArrayListValuedHashMap<String,PilotComm>();
        Map<String,PilotComm> comMaps = new HashMap<String,PilotComm>();
        for(PilotComm pilot:pilots){
            orgMaps.put(pilot.getOrganCode(),pilot);
            comMaps.put(pilot.getCommId(),pilot);
        }
        Map<String,Object> queryMap = new HashMap<String,Object>();
        if(pilotNum != 0 && pilots.size() ==0){
            //无权限
            return Response.response(new PageData(resultList,null));
        }
        if(!StringUtils.isEmpty(commId) && !isSum){
            //查询用户可看范围
            queryMap.put("organCode",organCode);
            queryMap.put("commId",commId);
        } else {

            List<ErpCommunity> erpOrgs = tbHsprCommunityMapper.findOrganBaseByUserCode(userCode,organCode);
            List<ErpCommunity> erpComs = tbHsprCommunityMapper.findCommBaseByUserCode(userCode,organCode);
            if(pilots.size() == 0){

                for(ErpCommunity erpOrg: erpOrgs){
                    organCodes.add(erpOrg.getOrganCode());
                }
                for(ErpCommunity erpComm: erpComs){
                    commIds.add(erpComm.getCommId());
                }
                if(organCodes.size() == 0 && commIds.size() == 0 && StringUtils.isEmpty(organCode)){
                    return Response.response(new PageData(resultList,null));
                }
            } else {
                for(ErpCommunity erpOrg:erpOrgs){
                    List<PilotComm> codeList = MultiMapUtils.getValuesAsList(orgMaps,erpOrg.getOrganCode());
                    if(codeList!=null){
                        for(PilotComm code :codeList){
                            commIds.add(code.getCommId());
                        }
                    }
                }
                for(ErpCommunity erpCom:erpComs){

                    PilotComm code = comMaps.get(erpCom.getCommId());
                    if(code!=null){
                        commIds.add(code.getCommId());
                    }
                }
                if(organCodes.size() == 0 && commIds.size() == 0 && StringUtils.isEmpty(organCode)){
                    return Response.response(new PageData(resultList,null));
                }
            }
            if(!StringUtils.isEmpty(organCode)){
                queryMap.put("organCode",organCode);
                if(organCodes.contains(organCode) && pilots.size() == 0){
                    commIds = new ArrayList<String>();
                }
            }
            if(organCodes.size()>0){
                queryMap.put("organCodes",organCodes);
            }
            if(commIds.size()>0){
                queryMap.put("commIds",commIds);
            }
        }
        PageRowBounds pageRowBounds = new PageRowBounds(page,size);
        Date startDate  = dateRange[0];
        Date endDate = dateRange[dateRange.length-1];
        queryMap.put("beginDate",startDate);
        queryMap.put("endDate",endDate);
        if(isUnFinished){
            queryMap.put("status",BuoyDataConstant.BuoyDataStatus.unfill);
        }
        if(isSum){
            //按星期汇总
            resultList =buoyDataMapper.summaryByWeek(queryMap,pageRowBounds);
        } else {
            //查询
            resultList = buoyDataMapper.queryByDateRang(queryMap,pageRowBounds);
        }

        for(BuoyQueryData data : resultList){
            int managerTotal = 0;
            if(data.getManagerNum()!=null){
                managerTotal = data.getManagerNum().intValue();
            }
            data.setDateRang(DateUtil.weekFormat(data.getBeginDate(),data.getEndDate()));
            Double managerRecognitionPercentage = NumberUtil.avgPercentage(data.getManagerRecognitionPercentage(),managerTotal);
            data.setManagerRecognitionPercentage(managerRecognitionPercentage);
            Double phonePercentage = NumberUtil.avgPercentage(data.getPhonePercentage(),managerTotal);
            data.setPhonePercentage(phonePercentage);
            Double wechatPercentage = NumberUtil.avgPercentage(data.getWechatPercentage(),managerTotal);
            data.setWechatPercentage(wechatPercentage);
            Double wechatCoverPercentage = NumberUtil.avgPercentage(data.getWechatCoverPercentage(),managerTotal);
            data.setWechatCoverPercentage(wechatCoverPercentage);

            Double satisfaction = NumberUtil.avgPercentage(data.getSatisfaction(),managerTotal);
            data.setSatisfaction(satisfaction);
            Double solvedPercentage = NumberUtil.percentage(data.getRequestReceived(),data.getRequestSolved());
            data.setSolvedPercentage(solvedPercentage);

            int buoyTotal =0;
            if(isSum){
                if(!StringUtils.isEmpty(data.getCommName())){
                    buoyTotal = Integer.parseInt(data.getCommName());
                }
                Double recognitionPercentage = NumberUtil.avgPercentage(data.getRecognitionPercentage(),buoyTotal);
                data.setRecognitionPercentage(recognitionPercentage);
                Double visitSatisfaction = NumberUtil.avgPercentage(data.getVisitSatisfaction(),buoyTotal);
                data.setVisitSatisfaction(visitSatisfaction);
                data.setStatus(BuoyDataConstant.BuoyDataStatus.sum);
            }


        }
        PageData pageData = new PageData(resultList,pageRowBounds);
        return Response.response(pageData);
    }




    @Override
    public void deleteBuoyData(int buoyDataId,String userCode){
        BuoyData data = buoyDataMapper.selectByPrimaryKey(buoyDataId);
        if(data!=null){
            if(!BuoyDataConstant.BuoyDataStatus.unfill.equals(data.getStatus())){
                restData(data);
                data.setUpdatedDate(new Date());
                data.setUpdatedBy(userCode);
                data.setStatus(BuoyDataConstant.BuoyDataStatus.unfill);
                buoyDataMapper.updateByPrimaryKeySelective(data);
            }
        }
    }

    @Override
    public void updateBuoyData(BuoyData data, String userCode){
        data.setStatus(null);
        data.setCreatedDate(null);
        data.setCreatedBy(null);
        data.setBeginDate(null);
        data.setEndDate(null);
        data.setCommId(null);
        data.setCommName(null);
        data.setOrganCode(null);
        data.setOrganName(null);
        data.setUpdatedBy(userCode);
        data.setUpdatedDate(new Date());
        buoyDataMapper.updateByPrimaryKeySelective(data);
    }

    @Override
    public void addBuoyData(BuoyData data, String userCode){
        Date startDate = DateUtils.truncate(data.getBeginDate(), Calendar.DATE);
        Date endDate = DateUtils.truncate(data.getEndDate(), Calendar.DATE);


        prepareUnFillData(data.getBeginDate(),data.getEndDate(),userCode);
        BuoyData unfillQuery = new BuoyData();
        unfillQuery.setBeginDate(startDate);
        unfillQuery.setEndDate(endDate);
        unfillQuery.setCommId(data.getCommId());
        unfillQuery.setOrganCode(data.getOrganCode());

        List<BuoyData> dataList = buoyDataMapper.select(unfillQuery);
        if(dataList.size()>0){
            BuoyData oldData = dataList.get(0);
            if(BuoyDataConstant.BuoyDataStatus.unfill.equals(oldData.getStatus())){
                copyTo(data,oldData);
                data.setBeginDate(startDate);
                data.setEndDate(endDate);
                data.setUpdatedDate(new Date());
                data.setUpdatedBy(userCode);
                data.setId(oldData.getId());
                data.setStatus(BuoyDataConstant.BuoyDataStatus.completed);
                buoyDataMapper.updateByPrimaryKeySelective(data);
            } else {
                throw new ServiceException("该项目已有数据，请进入编辑页面进行编辑");
            }
        }
    }

    private void prepareUnFillData(Date startDate, Date endDate,String userCode){
        BuoyDataStatus statusQuery = new BuoyDataStatus();
        statusQuery.setBeginDate(startDate);
        statusQuery.setEndDate(endDate);

        int count = buoyDataStatusMapper.selectCount(statusQuery);
        if(count ==0){
            BuoyDataStatus status = new BuoyDataStatus();
            status.setBeginDate(startDate);
            status.setEndDate(endDate);
            status.setStatus(BuoyDataConstant.BuoyDataStatus.completed);
            status.setCreatedBy(userCode);
            status.setCreatedDate(new Date());
            buoyDataStatusMapper.insert(status);
            //generate unfill data
            List<BuoyData> unfillList =new ArrayList<BuoyData>();
            List<PilotComm> pilotComms = pilotCommMapper.selectAll();
            Date currentDate = new Date();
            List<ErpCommunity> communitis = null;
            if(pilotComms.size()!=0){
                List<String> commCodes = new ArrayList<String>();

                for(PilotComm comm : pilotComms){
                    commCodes.add(comm.getCommId());

                }
                communitis = tbHsprCommunityMapper.findBaseCommByCode(commCodes);

            } else {
                communitis = tbHsprCommunityMapper.findAllBaseComm();
            }
            for(ErpCommunity comm : communitis){
                BuoyData data = generateEmptyData(startDate,endDate);
                data.setOrganCode(comm.getOrganCode());
                data.setOrganName(comm.getOrganName());
                data.setCommId(comm.getCommId());
                data.setCommName(comm.getCommName());
                data.setCreatedDate(currentDate);
                data.setUpdatedDate(currentDate);
                data.setCreatedBy(userCode);
                data.setUpdatedBy(userCode);
                unfillList.add(data);
            }
            buoyDataMapper.insertList(unfillList);
        }
    }

    private BuoyData restData(BuoyData data){
        data.setVisitorNum(0l);
        data.setRecognitionPercentage(0.0d);
        data.setTraditionVisitors(0l);
        data.setAppointmentVisitors(0l);
        data.setAppointmentByDevice(0l);
        data.setOtherVisitors(0l);
        data.setVisitCustomerNum(0l);
        data.setVisitSatisfaction(0.0d);
        return data;
    }

    private BuoyData copyTo(BuoyData source, BuoyData target){
        target.setVisitorNum(source.getVisitorNum());
        target.setRecognitionPercentage(source.getRecognitionPercentage());
        target.setTraditionVisitors(source.getTraditionVisitors());
        target.setAppointmentVisitors(source.getAppointmentVisitors());
        target.setAppointmentByDevice(source.getAppointmentByDevice());
        target.setOtherVisitors(source.getOtherVisitors());
        target.setVisitCustomerNum(source.getVisitCustomerNum());
        target.setVisitSatisfaction(source.getVisitSatisfaction());
        return target;
    }

    private BuoyData generateEmptyData(Date startDate, Date endDate){
        BuoyData data =new BuoyData();
        data.setStatus(BuoyDataConstant.BuoyDataStatus.unfill);
        data.setBeginDate(startDate);
        data.setEndDate(endDate);
        restData(data);
        return data;
    }

    public void exportToExcel(OutputStream outputStream,PageData data){
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("浮标数");

    }
}
