package com.yizhi.application.research.controller.manage;

import com.baomidou.mybatisplus.plugins.Page;
import com.yizhi.application.accountUtil.AuthorizeQueryAccount;
import com.yizhi.application.research.exception.TypeErrorExeption;
import com.yizhi.application.util.TaskSendMessage;
import com.yizhi.core.application.cache.RedisCache;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.core.application.enums.InternationalEnums;
import com.yizhi.core.application.exception.BizException;
import com.yizhi.research.application.eum.ResearchState;
import com.yizhi.research.application.feign.ResearchAuthorizeClient;
import com.yizhi.research.application.feign.ResearchClient;
import com.yizhi.research.application.feign.ResearchQuestionClient;
import com.yizhi.research.application.model.CopyResearchModel;
import com.yizhi.research.application.vo.BaseModel;
import com.yizhi.research.application.vo.IdVo;
import com.yizhi.research.application.vo.domain.TrResearchAuthorizeVo;
import com.yizhi.research.application.vo.domain.TrResearchQuestionVo;
import com.yizhi.research.application.vo.domain.TrResearchRemindVo;
import com.yizhi.research.application.vo.manage.RemindTimeVo;
import com.yizhi.research.application.vo.manage.RemindVo;
import com.yizhi.research.application.vo.manage.ResearchVo;
import com.yizhi.site.application.feign.api.EventTrackApiClients;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.system.application.vo.OrgVO;
import com.yizhi.training.application.feign.TpPlanActivityClient;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.Response;
import com.yizhi.util.application.page.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * @Author: shengchenglong
 * @Date: 2018/3/13 11:03
 */
@Api(tags = "调研接口")
@RestController
@RequestMapping("/manage/research")
public class ResearchController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ResearchController.class);

    @Autowired
    private ResearchClient researchClient;

//    @Autowired
//    SystemMessageClient systemMessageClient;

    @Autowired
    ResearchAuthorizeClient researchAuthorizeClient;

    @Autowired
    TpPlanActivityClient tpPlanActivityClient;
    @Autowired
    private AuthorizeQueryAccount queryAccount;
    @Autowired
    private TaskSendMessage taskSendMessage;

    @Autowired
    private EventTrackApiClients eventTrackApiClients;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ResearchQuestionClient researchQuestionClient;

    /**
     * 新增调研接口
     *
     * @return
     */
    @PostMapping("/insert")
    @ApiOperation(value = "新增调研", notes = "返回保存的调研", response = ResearchVo.class)
    public Response<ResearchVo> insert(
            @ApiParam(name = "researchVo", value = "调研vo", required = true) @RequestBody ResearchVo researchVo
    ) {

        try {
            Date date = new Date();
            RequestContext context = ContextHolder.get();

            com.yizhi.research.application.vo.domain.ResearchVo research = new  com.yizhi.research.application.vo.domain.ResearchVo();
            research.setName(researchVo.getName());
            research.setStartTime(researchVo.getStartTime());
            research.setEndTime(researchVo.getEndTime());
            research.setVisibleRange(researchVo.getVisibleRange());
            research.setContent(researchVo.getContent());
            research.setRemark(researchVo.getRemark());
            research.setPoint(researchVo.getPoint());
            research.setDeleted(0);
            research.setState(0);
            research.setRemind(researchVo.getRemind());
            research.setSiteId(context.getSiteId());
            research.setCompanyId(context.getCompanyId());
            research.setImage(researchVo.getImage());
            research.setOrgId(context.getOrgId() == null ? new Long(0) : context.getOrgId());
            research.setKeywords(researchVo.getKeywords());
            research.setEnableTask(researchVo.getEnableTask());
            research.setVoteNum(researchVo.getVoteNum());
            research.setBizType(researchVo.getBizType());
            research.setPageMode(researchVo.getPageMode());
            research.setStyleType(researchVo.getStyleType());
            research.setLogoSrc(researchVo.getLogoSrc());
            // 审计字段
            research.setCreateById(context.getAccountId());
            research.setCreateByName(context.getAccountName());
            research.setCreateTime(date);
            //设置指定人员
            Integer visibleRange = research.getVisibleRange();
            if (visibleRange == null) {
                visibleRange = 1;
            }
            if (visibleRange.equals(2)) {
                List<TrResearchAuthorizeVo> trResearchAuthorizes = buildAuthorize(researchVo, context);
                research.setAuthorizes(trResearchAuthorizes);
            }
            // 设置提醒
            if (researchVo.getRemind() != null && researchVo.getRemind() == 1) {
//                research.setReminds(buildReminds(researchVo.getRemindVo(), research, date, context));
            }
            //设置提醒
            if (researchVo.getMessageRemindVo() != null) {
                research.setMessageRemindVo(researchVo.getMessageRemindVo());
            }

            com.yizhi.research.application.vo.domain.ResearchVo savedResearch = researchClient.insert(research);
            if (savedResearch != null) {
                return Response.ok(savedResearch);
            } else {
                return Response.fail();
            }
        }catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @PostMapping("/update")
    @ApiOperation(value = "编辑调研", notes = "编辑调研基本信息")
    public Response update(
            @ApiParam(name = "researchVo", value = "调研vo", required = true) @RequestBody ResearchVo researchVo
    ) {
        try {
            if (researchVo == null || researchVo.getId() == null || researchVo.getId() == 0) {
                return Response.fail("", InternationalEnums.RESEARCHCONTROLLER1.getCode());
            }

            Date date = new Date();
            RequestContext context = ContextHolder.get();

            com.yizhi.research.application.vo.domain.ResearchVo oldResearch = researchClient.viewOne(researchVo.getId());
            researchVo.setStartTime(researchVo.getStartTime() == null ? oldResearch.getStartTime() : researchVo.getStartTime());
            researchVo.setEndTime(researchVo.getEndTime() == null ? oldResearch.getEndTime() : researchVo.getEndTime());

            com.yizhi.research.application.vo.domain.ResearchVo research = new com.yizhi.research.application.vo.domain.ResearchVo();
            research.setId(researchVo.getId());
            research.setName(researchVo.getName());
            research.setStartTime(researchVo.getStartTime());
            research.setEndTime(researchVo.getEndTime());
            research.setVisibleRange(researchVo.getVisibleRange());
            research.setContent(researchVo.getContent());
            research.setRemark(researchVo.getRemark());
            research.setPoint(researchVo.getPoint());
            research.setRemind(researchVo.getRemind());
            research.setSiteId(context.getSiteId());
            research.setCompanyId(context.getCompanyId());

//            research.setCreateById(context.getAccountId());
//            research.setCreateByName(context.getAccountName());
//            research.setCreateTime(new Date());
            research.setKeywords(researchVo.getKeywords());
            research.setImage(researchVo.getImage());
            research.setEnableTask(researchVo.getEnableTask());

            research.setVoteNum(researchVo.getVoteNum());
            research.setBizType(researchVo.getBizType());
            research.setPageMode(researchVo.getPageMode());
            
            // 审计字段
            research.setUpdateById(context.getAccountId());
            research.setUpdateByName(context.getAccountName());
            research.setUpdateTime(date);
            //设置关联人员
            research.setAuthorizes(buildAuthorize(researchVo, context));
            // 设置提醒
            if (research.getRemind() != null && research.getRemind() == 1) {
                research.setReminds(buildReminds(researchVo.getRemindVo(), research, date, context));
            }
            research.setMessageRemindVo(researchVo.getMessageRemindVo());
            int saveCount = researchClient.update(research);


            return Response.ok(saveCount);
        } catch (TypeErrorExeption errorExeption) {
            LOGGER.error("", errorExeption);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }

    }

    @PostMapping("/copy")
    @ApiOperation(value = "复制调研", response = com.yizhi.research.application.vo.domain.ResearchVo.class)
    public Response<com.yizhi.research.application.vo.domain.ResearchVo> copy(
            @ApiParam(name = "id", value = "调研id，参数形式：{\"id\":111}", required = true) @RequestBody Map<String, Long> map
    ) {
        try {

            Long researchId = map.get("id");
            CopyResearchModel model = new CopyResearchModel();
            model.setDate(new Date());
            model.setRequestContext(ContextHolder.get());
            model.setResearchId(researchId);

            return Response.ok(researchClient.copy(model));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * 分页列表
     *
     * @return
     */
    @GetMapping("/page/list")
    @ApiOperation(value = "分页列表", notes = "查询未删除的")
    public Response<PageInfo> listPage(HttpServletRequest request,
                                       @ApiParam(name = "name", value = "调研关键字") @RequestParam(name = "name", required = false) String name,
                                       @ApiParam(name = "state", value = "状态，0草稿 1上架 2下架", required = false) @RequestParam(name = "state", required = false) Integer state,
                                       @ApiParam(name = "bizType", value = "业务类型:1调研；2投票，不传查询所有", required = false) @RequestParam(name = "bizType", required = false) Integer bizType,
                                       @ApiParam(name = "currentTime", value = "当前时间") @RequestParam(value = "currentTime", required = false) String currentTime,
                                       @ApiParam(name = "pageNo", value = "跳转页数,默认第一页", required = true) @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                       @ApiParam(name = "pageSize", value = "每页条数,默认20条", required = true) @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize

    ) {
        try {
            Map<String, Object> map = new HashMap<>();
            if (name != null) {
                name = name.replace(" ", "");
            }
            map.put("name", name);
            map.put("state", state);
            map.put("currentTime", currentTime);
            map.put("bizType", bizType);

            Page<com.yizhi.research.application.vo.domain.ResearchVo> page = new Page<>();
            page.setCondition(map);
            page.setCurrent(pageNo);
            page.setSize(pageSize);

            BaseModel<Page<com.yizhi.research.application.vo.domain.ResearchVo>> model = new BaseModel<>();
            model.setContext(ContextHolder.get());
            model.setObj(page);
            return Response.ok(researchClient.listPage(model));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }

    }

    /**
     * 批量删除
     *
     * @return
     */
    @PostMapping("/batch/delete")
    @ApiOperation(value = "批量删除", notes = "只能删除草稿状态的")
    public Response<Integer> batchDelete(
            @ApiParam(name = "ids", value = "调研id", required = true) @RequestBody ArrayList<Long> ids
    ) {
        try {
            Integer i = researchClient.batchDelete(ids);
            if (i > 0) {
                return Response.ok(ReturnCode.SUCCESS);
            } else {
                return Response.fail(ReturnCode.DELETE_FAIL.getCode(),ReturnCode.DELETE_FAIL.getMsg());
            }
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * 上架
     *
     * @param idVo
     * @return
     */
    @PostMapping("/putaway")
    @ApiOperation(value = "上架", notes = "")
    public Response<com.yizhi.research.application.vo.domain.ResearchVo> putaway(
            @ApiParam(name = "id", value = "调研id，", required = true) @RequestBody IdVo idVo
    ) {
        try {
            Long id = idVo.getId();

            // 判断当前调研下是否有添加问题
            List<TrResearchQuestionVo> researchQuestionVoList = researchQuestionClient.listAll(id);
            if (CollectionUtils.isEmpty(researchQuestionVoList)) {
                return Response.fail(ReturnCode.BIZ_FAIL.getCode(), "当前投票没有添加问题，禁止上架！");
            }

            Date date = new Date();
            RequestContext context = ContextHolder.get();

            com.yizhi.research.application.vo.domain.ResearchVo research = new com.yizhi.research.application.vo.domain.ResearchVo();
            research.setId(id);
            research.setPoint(idVo.getPoint());
            research.setState(ResearchState.RELEASED.getValue());

            research.setUpdateById(context.getAccountId());
            research.setUpdateByName(context.getAccountName());
            research.setUpdateTime(date);

            research.setReleaseById(context.getAccountId());
            research.setReleaseByName(context.getAccountName());
            research.setReleaseTime(date);

            com.yizhi.research.application.vo.domain.ResearchVo research1 = researchClient.upOrDown(research);
            if (research1 != null) {

            }
            return Response.ok(research1);
        } catch (Exception e) {
            LOGGER.error("", e);
            if (e.getMessage().indexOf("该调研下没有创建题目，上架失败！") != -1) {
                return Response.fail("4001", InternationalEnums.RESEARCHCONTROLLER2.getCode());
            }
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * @param idVo
     * @return
     */
    @PostMapping("/backout")
    @ApiOperation(value = "下架", notes = "")
    public Response<com.yizhi.research.application.vo.domain.ResearchVo> backout(
            @ApiParam(name = "id", value = "调研id，", required = true) @RequestBody IdVo idVo
    ) {
        try {

            List<Long> ids = new ArrayList<Long>();
            ids.add(idVo.getId());
            Set<String> tpNames = tpPlanActivityClient.checkBizIsExistInTpNames(ids);
            String tpName = "";
            boolean isUp = false;
            if (!CollectionUtils.isEmpty(tpNames)) {
                for (String s : tpNames) {
                    tpName = s;
                }
                isUp = true;
            }
            if (isUp) {
                return Response.fail("10000", "{{"+InternationalEnums.RESEARCHCONTROLLER3.getCode()+"}}" + tpName + "{{"+InternationalEnums.RESEARCHCONTROLLER4.getCode()+"}}");
            }

            Long id = idVo.getId();
            Date date = new Date();
            RequestContext context = ContextHolder.get();

            com.yizhi.research.application.vo.domain.ResearchVo research = new com.yizhi.research.application.vo.domain.ResearchVo();
            research.setId(id);
            research.setState(ResearchState.NO_RELEASED.getValue());

            research.setUpdateById(context.getAccountId());
            research.setUpdateByName(context.getAccountName());
            research.setUpdateTime(date);

            research.setUnReleaseById(context.getAccountId());
            research.setUnReleaseByName(context.getAccountName());
            research.setUnReleaseTime(date);
            research = researchClient.upOrDown(research);
            if (research != null) {

                return Response.ok(ReturnCode.SUCCESS);
            } else {
                return Response.fail(ReturnCode.UPDATE_FAIL.getCode(),ReturnCode.UPDATE_FAIL.getMsg());
            }
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @GetMapping("/view")
    @ApiOperation(value = "查看一个调研", notes = "", response = com.yizhi.research.application.vo.domain.ResearchVo.class)
    public Response<com.yizhi.research.application.vo.domain.ResearchVo> viewOne(
            @ApiParam(name = "id", value = "调研id", required = true) @RequestParam(name = "id") Long id
    ) {
        try {
            com.yizhi.research.application.vo.domain.ResearchVo research = researchClient.viewOne(id);
            if (research != null) {
                List<TrResearchAuthorizeVo> ranges = research.getAuthorizes();
                if (!CollectionUtils.isEmpty(ranges)) {
                    List<Long> accountIds = new ArrayList<>(ranges.size());
                    List<Long> orgIds = new ArrayList<>(ranges.size());
                    ranges.forEach(a -> {
                        if (a.getType().equals(1)) {
                            orgIds.add(a.getRelationId());
                        } else {
                            accountIds.add(a.getRelationId());
                        }
                    });
                    Map<Long, AccountVO> accountMap = queryAccount.queryAccountByIds(accountIds);
                    Map<Long, OrgVO> orgMap = queryAccount.queryOrgByIds(orgIds);
                    ranges.forEach(a -> {
                        if (null != accountMap) {
                            AccountVO accountVO = accountMap.get(a.getRelationId());
                            if (null != accountVO && a.getType().equals(2)) {
                                a.setWorkNum(accountVO.getWorkNum());
                                a.setFullName(accountVO.getFullName());
                                a.setName(accountVO.getName());
                            }
                        }
                        if (null != orgMap) {
                            OrgVO orgVO = orgMap.get(a.getRelationId());
                            if (null != orgVO && a.getType().equals(1)) {
                                a.setName(orgVO.getName());
                            }
                        }
                    });
                }
            }
            return Response.ok(research);
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * 检查提醒类型
     *
     * @param remindType
     * @return
     */
    private boolean checkRemindType(Integer remindType) {
        return remindType == 0
                || remindType == 1
                || remindType == 2;
    }

    /**
     * 组装调研提醒
     *
     * @param remindVo
     * @param research
     * @param date
     * @param context
     * @return
     */
    private List<TrResearchRemindVo> buildReminds(RemindVo remindVo, com.yizhi.research.application.vo.domain.ResearchVo research, Date date, RequestContext context) throws Exception {
        if (remindVo != null) {
            research.setEnableAppRemind(remindVo.getEnableApp());
            research.setEnableMailRemind(remindVo.getEnableMail());

            // 设置提醒
            List<TrResearchRemindVo> researchReminds = null;
            // 提醒时间可能多条
            List<RemindTimeVo> remindTimeVos = remindVo.getRemindTimes();
            if (!CollectionUtils.isEmpty(remindTimeVos)) {
                research.setRemind(1);
                researchReminds = new ArrayList<>();
                for (RemindTimeVo vo : remindTimeVos) {

//                    if (checkRemindType(vo.getType())) {
//                        throw new Exception("提醒时间类型不合规，请检查！！");
//                    }

                    TrResearchRemindVo remind = new TrResearchRemindVo();
                    remind.setType(vo.getType());
                    if (vo.getType() != 3) {
                        if (vo.getSeconds() == null) {
                            remind.setSeconds(0L);
                        } else {
                            remind.setSeconds(Long.valueOf(vo.getSeconds()));
                        }
                    }
                    remind.setCreateById(context.getAccountId());
                    remind.setCreateByName(context.getAccountName());
                    remind.setCreateTime(date);

                    // 开始时间之前
                    if (vo.getType() == 1 && research.getStartTime() != null) {
                        remind.setTime(new Date(research.getStartTime().getTime() + vo.getSeconds() * 1000));
                    }
                    // 结束时间之前
                    else if (vo.getType() == 2 && research.getEndTime() != null) {
                        remind.setTime(new Date(research.getEndTime().getTime() + vo.getSeconds() * 1000));
                    } else if (vo.getType() == 3) {
                        remind.setTime(vo.getTime());
                    } else {
                        throw new Exception("组装题项时间错误，请检查！！");
                    }
                    researchReminds.add(remind);
                }
                return researchReminds;
            }
        }
        return null;
    }

    /**
     * 提醒关键字替换
     *
     * @param value
     * @param researchVo
     * @return
     */
    private String replaceContent(String value, ResearchVo researchVo, String startTime, String endTime) {
        if (!StringUtils.isBlank(value)) {
            value = value.replace("{调研名称}", researchVo.getName());
            value = value.replace("{开始时间}", startTime);
            value = value.replace("{结束时间}", endTime);
        }

        return value;
    }

    public List<TrResearchAuthorizeVo> buildAuthorize(ResearchVo v, RequestContext context) {
        if (v.getTrResearchAuthorize() == null) {
            return null;
        }
        List<TrResearchAuthorizeVo> list = v.getTrResearchAuthorize();

        for (TrResearchAuthorizeVo trResearchAuthorize : list) {
            trResearchAuthorize.setCreateById(context.getAccountId());
            trResearchAuthorize.setCreateByName(context.getAccountName());
            trResearchAuthorize.setCreateTime(new Date());
            trResearchAuthorize.setSiteId(context.getSiteId());
            if (null == trResearchAuthorize.getSiteId()) {
                trResearchAuthorize.setState(1);
            }
        }

        return list;
    }

    /**
     * @param map
     * @return
     */
    @PostMapping("/delete")
    public Response<T> delete(@RequestBody Map map) {
        Integer i = 0;
        try {
            i = researchClient.delete(map);
            switch (i) {
                case 0:
                    return Response.fail(InternationalEnums.CLASSIFYCONTROLLER4.getCode());
                case 1:
                    return Response.ok(i);
                case -1:
                    return Response.fail(InternationalEnums.POINTACTIVITYCONTROLLER.getCode());
                case -2:
                    return Response.fail(InternationalEnums.RESEARCHCONTROLLER5.getCode());
                case -3:
                    return Response.fail(InternationalEnums.RESEARCHCONTROLLER6.getCode());
            }
        } catch (BizException e) {
            return Response.fail(e.getCode(), e.getMsg());
        }
        return Response.ok(i);
    }
}
