package com.gic.haoban.manage.web.controller.moment;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.AuthorizedUser;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanAttendDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanDTO;
import com.gic.haoban.manage.api.dto.moment.QwMomentPlanDataDTO;
import com.gic.haoban.manage.api.qdto.moment.PlanClerkListQDTO;
import com.gic.haoban.manage.api.qdto.moment.PlanDataListQDTO;
import com.gic.haoban.manage.api.qdto.moment.QwMomentPlanQDTO;
import com.gic.haoban.manage.api.service.moment.QwMomentApiService;
import com.gic.haoban.manage.web.log.LogRecordUserServiceImpl;
import com.gic.haoban.manage.web.qo.moment.PlanClerkListQO;
import com.gic.haoban.manage.web.qo.moment.PlanDataListQO;
import com.gic.haoban.manage.web.qo.moment.PlanListQO;
import com.gic.haoban.manage.web.qo.moment.QwMomentPlanQO;
import com.gic.haoban.manage.web.utils.CreatorUtils;
import com.gic.haoban.manage.web.vo.moment.ClerkVO;
import com.gic.haoban.manage.web.vo.moment.HaobanQwMomentPlanVO;
import com.gic.haoban.manage.web.vo.moment.QwMomentPlanAttendVO;
import com.gic.haoban.manage.web.vo.moment.QwMomentPlanDataVO;
import com.gic.log.record.anno.GicLogRecord;
import com.gic.log.record.util.GicLogRecordCategoryEnum;
import com.gic.log.record.util.GicLogRecordEvaluationContext;
import com.gic.log.record.util.GicLogRecordOptTypeEnum;
import com.gic.web.common.utils.SessionContextUtils;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 企微朋友圈
 */
@RestController
@RequestMapping("/qw-moment")
public class QwMomentController {

    private static Logger logger = LogManager.getLogger(QwMomentController.class);

    @Autowired
    private QwMomentApiService qwMomentApiService ;

    /**
     * 新建任务
     */
    @RequestMapping("add")
    @ResponseBody
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.QW_MOMENT, optType = GicLogRecordOptTypeEnum.QW_MOMENT_ADD, userFunc = LogRecordUserServiceImpl.class, optPage = "企微朋友圈-朋友圈列表-新建页面")
    public RestResponse<String> add(@RequestBody QwMomentPlanQO qo){
        logger.info("新建任务={}", JSONObject.toJSONString(qo));
        QwMomentPlanDTO plan = EntityUtil.changeEntityByJSON(QwMomentPlanDTO.class,qo) ;
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        plan.setEnterpriseId(loginUser.getEnterpriseId());
        plan.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        plan.setCreatorId(loginUser.getClerkId());
        plan.setCreatorName(loginUser.getClerkName());
        ServiceResponse<QwMomentPlanDTO> resp = this.qwMomentApiService.save(plan) ;
        String logContent = "新增企微朋友圈活动【" + resp.getResult().getTitle() + "-" + resp.getResult().getPlanId() + "】";
        GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
        return RestResponse.successResult(resp.getResult().getPlanId()+"")  ;
    }


    /**
     * 更新
     */
    @RequestMapping("update")
    @ResponseBody
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.QW_MOMENT, optType = GicLogRecordOptTypeEnum.QW_MOMENT_EIDT, userFunc = LogRecordUserServiceImpl.class, optPage = "企微朋友圈-朋友圈列表-编辑页面")
    public RestResponse<String> update(@RequestBody QwMomentPlanQO qo) {
        logger.info("更新任务={}", JSONObject.toJSONString(qo));
        if(null == qo.getPlanId()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure("9999","活动id为空") ;
        }
        ServiceResponse<QwMomentPlanDTO> planResp = this.qwMomentApiService.detail(qo.getPlanId()) ;
        if(null == planResp.getResult()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure("9999","导购任务不存在") ;
        }
        QwMomentPlanDTO oldPlan = planResp.getResult() ;

        QwMomentPlanDTO plan = EntityUtil.changeEntityByJSON(QwMomentPlanDTO.class,qo) ;
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        plan.setEnterpriseId(loginUser.getEnterpriseId());
        plan.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        plan.setCreatorId(loginUser.getClerkId());
        plan.setCreatorName(loginUser.getClerkName());

        ServiceResponse<QwMomentPlanDTO> resp = this.qwMomentApiService.save(plan) ;
        String logTitle = "编辑企微朋友圈活动【" + resp.getResult().getTitle() + "-" + resp.getResult().getPlanId() + "】";
        ServiceResponse<QwMomentPlanDTO> newPlanResp = this.qwMomentApiService.detail(qo.getPlanId()) ;
        String logContent = this.getLogContent(loginUser.getEnterpriseId(), oldPlan, newPlanResp.getResult());
        logger.info("日志内容logContent={}",logContent);
        if(StringUtils.isBlank(logContent.trim())) {
            GicLogRecordEvaluationContext.noWriteLog();
        }else {
            GicLogRecordEvaluationContext.putAttribute("logValue", logTitle + logContent);
        }
        return RestResponse.successResult(resp.getResult().getPlanId()+"")  ;
    }

    private String getLogContent(String enterpriseId ,QwMomentPlanDTO oldDTO , QwMomentPlanDTO newDTO) {
        List<String> logList = new ArrayList<>();
        this.otherLog("活动标题",oldDTO.getTitle(),newDTO.getTitle() , logList) ;
        this.otherLog("活动描述",oldDTO.getRemark(),newDTO.getRemark() , logList) ;

        String oldExecType = "" ;
        String newExecType = "" ;
        this.otherLog("执行方式",oldExecType,newExecType , logList) ;

        // 0全部导购 1部分导购
        int oldPlanClerkType = oldDTO.getPlanClerkType() ;
        int newPlanClerkTyp = newDTO.getPlanClerkType() ;
        if(oldPlanClerkType==0 && newPlanClerkTyp==1) {
            this.otherLog("执行人类型","全部导购","部分导购" , logList) ;
        }else  if(oldPlanClerkType==1 && newPlanClerkTyp==0) {
            this.otherLog("执行人类型","部分导购","全部导购" , logList) ;
        }else if(oldPlanClerkType==1 && newPlanClerkTyp==1) {
            List<String> oldClerkIdList = oldDTO.getClerkList().stream().map(o->o.getClerkId()).collect(Collectors.toList());
            List<String> newClerkIdList = newDTO.getClerkList().stream().map(o->o.getClerkId()).collect(Collectors.toList());
            String del = "" ;
            String add = "" ;
            for(String clerkId : oldClerkIdList) {
                List<String> nameList = new ArrayList<>() ;
                if(!newClerkIdList.contains(clerkId)) {
                    nameList.add(clerkId);
                }
                if(CollectionUtils.isNotEmpty(nameList)) {
                    del = "删除【"+nameList.stream().collect(Collectors.joining("、"))+"】" ;
                }
            }
            for(String clerkId : newClerkIdList) {
                List<String> nameList = new ArrayList<>() ;
                if(!oldClerkIdList.contains(clerkId)) {
                    nameList.add(clerkId);
                }
                if(CollectionUtils.isNotEmpty(nameList)) {
                    add = "新增【"+nameList.stream().collect(Collectors.joining("、"))+"】" ;
                }
            }
            if(StringUtils.isNotBlank(del) || StringUtils.isNotBlank(add)) {
                logList.add("修改部分导购："+ add +  ";" + del);
            }
        }
        if(!oldDTO.getMediaInfo().equals(newDTO.getMediaInfo())) {
            logList.add("变更朋友圈配置");
        }
        // 1立即发布2定时发布
        int oldPublishType = oldDTO.getPublishType() ;
        int newPublishType = newDTO.getPublishType() ;
        if(oldPublishType==2 && newPublishType==1) {
            Date publishTime = oldDTO.getPublishTime() ;
            this.otherLog("发送时间","定时发布-"+DateUtil.dateToStr(publishTime,"yyyy-MM-dd HH:mm:ss"),"立即发布" , logList) ;
        }else if(oldPublishType==2 && newPublishType==2) {
            Date oldPublishTime = oldDTO.getPublishTime() ;
            Date newPublishTime = oldDTO.getPublishTime() ;
            this.otherLog("发送时间",DateUtil.dateToStr(oldPublishTime,"yyyy-MM-dd HH:mm:ss"),DateUtil.dateToStr(newPublishTime,"yyyy-MM-dd HH:mm:ss") , logList) ;
        }

        int oldExpireDays = oldDTO.getExpireDays() ;
        int newExpireDays = newDTO.getExpireDays() ;
        this.otherLog("失效时间",oldExpireDays+"天后",newExpireDays+"天后" , logList) ;

        return logList.stream().filter(o->StringUtils.isNotBlank(o)).collect(Collectors.joining(";"));
    }

    private static List<String> differenceList(List<String> list1, List<String> list2) {
        if (CollectionUtils.isNotEmpty(list1) && CollectionUtils.isNotEmpty(list2)) {
            Sets.SetView<String> setView = Sets.difference(Sets.newHashSet(list1), Sets.newHashSet(list2));
            return setView.stream().collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    private String otherLog(String s1, String s2, String s3 , List<String> logList) {
        if(null == s2) {
            s2 = "" ;
        }
        if(null == s3) {
            s3 = "" ;
        }
        if (!s2.equals(s3)) {
            String s =  new StringBuilder(s1).append("从【").append(s2).append("】修改为【").append(s3).append("】").toString() ;
            if(null != logList) {
                logList.add(s);
            }
            return s ;
        }
        return "";
    }

    /**
     * 删除
     * @return
     */
    @RequestMapping("del")
    @ResponseBody
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.QW_MOMENT, optType = GicLogRecordOptTypeEnum.QW_MOMENT_DEL, userFunc = LogRecordUserServiceImpl.class, optPage = "企微朋友圈-朋友圈列表")
    public RestResponse<Void> del(Long planId){
        ServiceResponse<QwMomentPlanDTO> resp = this.qwMomentApiService.detail(planId) ;
        if(null == resp.getResult()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure("9999","活动不存在") ;
        }
        this.qwMomentApiService.del(planId) ;
        String logContent = "删除企微朋友圈活动任务【" + resp.getResult().getTitle() + "-" + planId + "】";
        GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
        return RestResponse.successResult() ;
    }

    /**
     * 终止
     * @return
     */
    @RequestMapping("stop")
    @ResponseBody
    @GicLogRecord(value = "${#logValue}", category = GicLogRecordCategoryEnum.QW_MOMENT, optType = GicLogRecordOptTypeEnum.QW_MOMENT_STOP, userFunc = LogRecordUserServiceImpl.class, optPage = "企微朋友圈-朋友圈列表")
    public RestResponse<Void> stop(Long planId){
        ServiceResponse<QwMomentPlanDTO> resp = this.qwMomentApiService.detail(planId) ;
        if(null == resp.getResult()) {
            GicLogRecordEvaluationContext.noWriteLog();
            return RestResponse.failure("9999","活动不存在") ;
        }
        this.qwMomentApiService.stop(planId) ;
        String logContent = "终止企微朋友圈活动【" + resp.getResult().getTitle() + "-" + planId + "】";
        GicLogRecordEvaluationContext.putAttribute("logValue", logContent);
        return RestResponse.successResult() ;
    }

    /**
     * 复制
     * @return
     */
    @RequestMapping("copy")
    @ResponseBody
    public RestResponse<HaobanQwMomentPlanVO> copy(Long planId){
        RestResponse<HaobanQwMomentPlanVO> detailResponse = this.detail(planId) ;
        // 删除ID
        HaobanQwMomentPlanVO vo = detailResponse.getResult() ;
        vo.setPlanId(null);
        boolean isAdmin = false ;
        AuthorizedUser loginUser = SessionContextUtils.getLoginUser() ;
        if (loginUser.getSuperAdmin() == 1 ||  null== loginUser.getDepartAuth() ||  3 == loginUser.getDepartAuth()) {
            isAdmin = true ;
        }
        vo.setBeginDate(null);
        vo.setEndDate(null);
        vo.setPublishTime(null);
        return RestResponse.successResult(vo) ;
    }


    /**
     * 活动列表
     */
    @RequestMapping("plan-list")
    public RestResponse<Page<HaobanQwMomentPlanVO>> planList(@RequestBody PlanListQO qo) {
        QwMomentPlanQDTO qdto =  EntityUtil.changeEntityByJSON(QwMomentPlanQDTO.class,qo) ;
        qdto.setCreatorIdList(CreatorUtils.getCreatorIdList(qo.getShowSelfFlag()));
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        qdto.setEnterpriseId(loginUser.getEnterpriseId());
        qdto.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        ServiceResponse<Page<QwMomentPlanDTO>> resp = this.qwMomentApiService.planList(qdto) ;
        Page<HaobanQwMomentPlanVO> retPage = PageHelperUtils.changePageToCurrentPage(resp.getResult(), HaobanQwMomentPlanVO.class);
        return RestResponse.successResult(retPage);
    }

    /**
     * 活动详情
     */
    @RequestMapping("detail")
    public RestResponse<HaobanQwMomentPlanVO> detail(Long planId) {
        ServiceResponse<QwMomentPlanDTO> detaiResp = this.qwMomentApiService.detail(planId) ;
        if (!detaiResp.isSuccess()) {
            return RestResponse.failure("1", "任务不存在");
        }
        // 查询素材列表
        HaobanQwMomentPlanVO vo = EntityUtil.changeEntityByJSON(HaobanQwMomentPlanVO.class, detaiResp.getResult());
        // 部分导购
        if(vo.getPlanClerkType()==1) {
            List<QwMomentPlanAttendDTO> clerkList = detaiResp.getResult().getClerkList() ;
            if(CollectionUtils.isNotEmpty(clerkList)) {
                List<ClerkVO> list = clerkList.stream().map(o->{
                    ClerkVO clerkVO = new ClerkVO();
                    clerkVO.setClerkId(o.getClerkId());
                    clerkVO.setClerkCode(o.getClerkCode());
                    clerkVO.setClerkName(o.getClerkName());
                    return clerkVO ;
                }).collect(Collectors.toList()) ;
                vo.setClerkVOList(list);
            }
        }
        return RestResponse.successResult(vo);
    }


    /**
     * 执行导购列表
     */
    @RequestMapping("clerk-list")
    public RestResponse<Page<QwMomentPlanAttendVO>> clerkList(@RequestBody PlanClerkListQO qo) {
        PlanClerkListQDTO qdto = EntityUtil.changeEntityByJSON(PlanClerkListQDTO.class,qo) ;
        ServiceResponse<Page<QwMomentPlanAttendDTO>> resp = this.qwMomentApiService.attendList(qdto) ;
        Page<QwMomentPlanAttendVO> retPage = PageHelperUtils.changePageToCurrentPage(resp.getResult(), QwMomentPlanAttendVO.class);
        return RestResponse.successResult(retPage);
    }

    /**
     * 统计
     */
    @RequestMapping("data-list")
    public RestResponse<Page<QwMomentPlanDataVO>> dataList(@RequestBody PlanDataListQO qo) {
        PlanDataListQDTO qdto = EntityUtil.changeEntityByJSON(PlanDataListQDTO.class,qo) ;
        ServiceResponse<Page<QwMomentPlanDataDTO>> resp = this.qwMomentApiService.dataList(qdto) ;
        Page<QwMomentPlanDataVO> retPage = PageHelperUtils.changePageToCurrentPage(resp.getResult(), QwMomentPlanDataVO.class);
        return RestResponse.successResult(retPage);
    }


    /**
     * 统计-导出
     */
    @RequestMapping("data-list-excel")
    public RestResponse<String> dataListExcel(@RequestBody PlanDataListQO qo) {
        PlanDataListQDTO qdto = EntityUtil.changeEntityByJSON(PlanDataListQDTO.class,qo) ;
        ServiceResponse<Page<QwMomentPlanDataDTO>> resp = this.qwMomentApiService.dataList(qdto) ;
        return RestResponse.successResult(null);
    }


    /**
     * 活动列表-导出
     * @param qo
     * @return
     */
    @RequestMapping("plan-list-excel")
    public RestResponse<String> planListExcel(@RequestBody PlanListQO qo) {
        QwMomentPlanQDTO qdto = new QwMomentPlanQDTO() ;
        ServiceResponse<Page<QwMomentPlanDTO>> resp = this.qwMomentApiService.planList(qdto) ;
        return RestResponse.successResult(null);
    }


    /**
     * 执行导购列表-导出
     * @param qo
     * @return
     */
    @RequestMapping("clerk-list-excel")
    public RestResponse<String> clerkListExcel(@RequestBody PlanClerkListQO qo) {
        PlanClerkListQDTO qdto = EntityUtil.changeEntityByJSON(PlanClerkListQDTO.class,qo) ;
        ServiceResponse<Page<QwMomentPlanAttendDTO>> resp = this.qwMomentApiService.attendList(qdto) ;
        return RestResponse.successResult(null);
    }

}
