package com.persagy.dmp.rwd.demand.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.persagy.dmp.common.constant.CommonConstant;
import com.persagy.dmp.common.constant.ValidEnum;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.common.model.entity.AuditableEntity;
import com.persagy.dmp.common.model.entity.BaseEntity;
import com.persagy.dmp.common.model.response.CommonResult;
import com.persagy.dmp.common.utils.JsonHelper;
import com.persagy.dmp.common.utils.ParamCheckUtil;
import com.persagy.dmp.common.utils.ResultHelper;
import com.persagy.dmp.rwd.demand.constant.DemandBillState;
import com.persagy.dmp.rwd.demand.entity.AnswerDemandVO;
import com.persagy.dmp.rwd.demand.entity.DictionaryDemand;
import com.persagy.dmp.rwd.demand.entity.QueryDemandVO;
import com.persagy.dmp.rwd.demand.service.IDictionaryDemandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 字典需求Controller
 * @author Charlie Yu
 * @date 2021-09-16
 */
@RestController
@RequestMapping("/rwdedit/demand")
public class DictionaryDemandController {

    /** 可回复的状态 */
    private static final Set<Integer> STATE_SET = CollUtil.newHashSet(
            DemandBillState.APPROVED_ACCEPT.getIndex(), DemandBillState.APPROVED_REJECT.getIndex(),
            DemandBillState.PROOFING.getIndex(), DemandBillState.SEND_BACK.getIndex());

    @Autowired
    private IDictionaryDemandService service;

    /**
     * 保存需求
     * @param vo
     * @return
     */
    @PostMapping("/save")
    public CommonResult<DictionaryDemand> save(@Valid @RequestBody DictionaryDemand vo) {
        ParamCheckUtil.checkParam(CommonConstant.QUERY_USERID);
        // 校验
        boolean canEdit = vo.getBillState() != null && (DemandBillState.SAVING.getIndex().equals(vo.getBillState())
                || DemandBillState.SEND_BACK.getIndex().equals(vo.getBillState()));
        if(!canEdit) {
            throw new BusinessException("只有待提交和待完善的需求可以修改");
        }
        vo = service.saveOrSubmit(vo, false);
        return ResultHelper.single(vo);
    }

    /**
     * 提交需求
     * @param vo
     * @return
     */
    @PostMapping("/submit")
    public CommonResult<DictionaryDemand> submit(@Valid @RequestBody DictionaryDemand vo) {
        ParamCheckUtil.checkParam(CommonConstant.QUERY_USERID);
        // 校验
        boolean canEdit = vo.getBillState() != null && (DemandBillState.SAVING.getIndex().equals(vo.getBillState())
                || DemandBillState.SEND_BACK.getIndex().equals(vo.getBillState()));
        if(!canEdit) {
            throw new BusinessException("只有待提交和待完善的需求可以修改");
        }
        vo = service.saveOrSubmit(vo, true);
        return ResultHelper.single(vo);
    }

    /**
     * 删除需求
     * @return
     */
    @PostMapping("/delete")
    public CommonResult delete(@RequestBody List<String> ids) {
        ParamCheckUtil.checkParam(CommonConstant.QUERY_USERID);
        if(CollUtil.isEmpty(ids)) {
            throw new BusinessException("没有选择待删除的需求");
        }
        service.deleteByIds(ids);
        return ResultHelper.success();
    }

    /**
     * 答复需求
     * @return
     */
    @PostMapping("/answer")
    public CommonResult<List<DictionaryDemand>> answer(@Valid @RequestBody AnswerDemandVO answer) {
        ParamCheckUtil.checkParam(CommonConstant.QUERY_USERID);
        // 如果不是处理状态
        if(!STATE_SET.contains(answer.getBillState())) {
            throw new BusinessException("处理状态有误！");
        }
        // 保存
        List<DictionaryDemand> vos = service.answer(answer.getIds(), answer.getBillState(),
                answer.getRespondent(), answer.getReply(), answer.getEstimateTime());
        return ResultHelper.multi(vos);
    }

    /**
     * 查询草稿箱
     * @return
     * @throws IOException
     */
    @PostMapping("/queryDraft")
    public CommonResult<List<DictionaryDemand>> queryDraft(@RequestBody Map<String, Object> map) {
        return queryDemandByState(map, DemandBillState.SAVING.getIndex());
    }

    /**
     * 查询已提交
     * @return
     * @throws IOException
     */
    @PostMapping("/querySubmitted")
    public CommonResult<List<DictionaryDemand>> querySubmitted(@RequestBody Map<String, Object> map) {
        return queryDemandByState(map, DemandBillState.SUBMITTED.getIndex(),
                DemandBillState.APPROVED_ACCEPT.getIndex(), DemandBillState.APPROVED_REJECT.getIndex(),
                DemandBillState.SEND_BACK.getIndex(), DemandBillState.PROOFING.getIndex());
    }

    /**
     * 查询待办
     * @return
     * @throws IOException
     */
    @PostMapping("/queryTodo")
    public CommonResult<List<DictionaryDemand>> queryTodo(@RequestBody Map<String, Object> map) {
        return queryDemandByState(map, DemandBillState.SUBMITTED.getIndex(), DemandBillState.PROOFING.getIndex());
    }

    /**
     * 查询已办
     * @return
     * @throws IOException
     */
    @PostMapping("/queryDone")
    public CommonResult<List<DictionaryDemand>> queryDone(@RequestBody Map<String, Object> map) {
        return queryDemandByState(map, DemandBillState.APPROVED_ACCEPT.getIndex(), DemandBillState.APPROVED_REJECT.getIndex(), DemandBillState.SEND_BACK.getIndex());
    }

    /**
     * 按状态查询
     * @param map
     * @param states
     * @return
     */
    private CommonResult<List<DictionaryDemand>> queryDemandByState(Map<String, Object> map, Integer... states) {
        ParamCheckUtil.checkParam(CommonConstant.QUERY_USERID);
        QueryDemandVO cond = JsonHelper.toSingleEntityQuietly(map, QueryDemandVO.class);
        Page pageable = JsonHelper.toSingleEntityQuietly(map, Page.class);
        resetOrderItem(pageable);
        // 组装查询条件
        QueryWrapper<DictionaryDemand> wrapper = new QueryWrapper<>();
        wrapper.eq("valid", ValidEnum.TRUE.getType());
        // 查询待回复和论证中
        wrapper.in("bill_state", (Integer[]) states);
        ensureQueryCond(wrapper, cond);
        Page page = service.page(pageable, wrapper);
        return ResultHelper.multi(page.getRecords(), page.getTotal());
    }

    /**
     * 排序驼峰转下划线
     * @param pageable
     */
    private void resetOrderItem(Page pageable) {
        if(pageable == null) {
            return;
        }
        // MySQL默认排序不可靠，分页查询时会出现跨页结果重复，因此加上默认排序
        if(CollUtil.isEmpty(pageable.getOrders())) {
            List<OrderItem> defaultOrders = CollUtil.newArrayList(OrderItem.asc(BaseEntity.PROP_ID));
            pageable.setOrders(defaultOrders);
            return;
        }
        // 转下划线
        List<OrderItem> orders = pageable.getOrders();
        for(OrderItem order:orders) {
            order.setColumn(StrUtil.toUnderlineCase(order.getColumn()));
        }
    }

    /**
     * 拼接查询条件
     * @param wrapper
     * @param cond
     */
    private void ensureQueryCond(QueryWrapper<DictionaryDemand> wrapper, QueryDemandVO cond) {
        if(cond == null) {
            return;
        }
        // 只查看我的需求
        wrapper.eq(cond.getCreatorCond()!=null&&1==cond.getCreatorCond(),
                AuditableEntity.PROP_CREATOR, AppContext.getContext().getAccountId());
        // 模糊匹配
        String matchColumn = " concat(ifnull(code, ''), '@', ifnull(subject, '')) ";
        wrapper.like(StrUtil.isNotBlank(cond.getMatchingCond()), matchColumn, cond.getMatchingCond());
        // 产线
        wrapper.in(CollUtil.isNotEmpty(cond.getProductCond()), "product_line", cond.getProductCond());
        // 状态
        wrapper.in(CollUtil.isNotEmpty(cond.getStateCond()), "bill_state", cond.getStateCond());
    }
}
