package com.hzs.system.index.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.constant.msg.CommonMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.system.sys.SysApprovalBusinessDetail;
import com.hzs.common.domain.system.sys.SysApprovalBusinessReceive;
import com.hzs.common.domain.system.sys.ext.SysApprovalBusinessExt;
import com.hzs.common.domain.system.sys.ext.SysApprovalBusinessReceiveExt;
import com.hzs.common.domain.system.sys.ext.SysApprovalBusinessSendExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.common.util.TransactionUtils;
import com.hzs.system.index.param.CompleteApprovalParam;
import com.hzs.system.index.param.ReceiveApprovalParam;
import com.hzs.system.index.param.ReceiveApprovalQueryParam;
import com.hzs.system.index.vo.IndexApprovalDetailVO;
import com.hzs.system.index.vo.IndexApprovalReceiveVO;
import com.hzs.system.index.vo.IndexApprovalVO;
import com.hzs.system.index.vo.ReceiveApprovalVO;
import com.hzs.system.sys.service.ISysApprovalBusinessDetailService;
import com.hzs.system.sys.service.ISysApprovalBusinessReceiveService;
import com.hzs.system.sys.service.ISysApprovalBusinessSendService;
import com.hzs.system.sys.service.ISysApprovalBusinessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 后台首页控制器
 */
@RestController
@RequestMapping("/manage/index")
public class IndexController extends BaseController {

    @Autowired
    private ISysApprovalBusinessService iSysApprovalBusinessService;
    @Autowired
    private ISysApprovalBusinessDetailService iSysApprovalBusinessDetailService;
    @Autowired
    private ISysApprovalBusinessSendService iSysApprovalBusinessSendService;
    @Autowired
    private ISysApprovalBusinessReceiveService iSysApprovalBusinessReceiveService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    /**
     * 待办数量
     *
     * @return
     */
    @GetMapping("/wait-approval-num")
    public AjaxResult waitApprovalNum() {
        return AjaxResult.success(iSysApprovalBusinessService.waitApprovalNum(SecurityUtils.getUserId(), SecurityUtils.getPkCountry()));
    }

    /**
     * 待办数据
     *
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_WAIT, method = EOperationMethod.SELECT)
    @GetMapping("/wait-approval")
    public AjaxResult waitApproval(CompleteApprovalParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());

        Long userId = SecurityUtils.getUserId();

        // 返回前台数据
        List<IndexApprovalVO> resultList = new ArrayList<>();

        // 查询主数据
        List<SysApprovalBusinessExt> list = iSysApprovalBusinessService.waitApproval(param, userId, SecurityUtils.getPkCountry());
        if (!CollectionUtils.isEmpty(list)) {
            // 明细列表转map
            Map<Long, List<SysApprovalBusinessDetail>> detailMap = iSysApprovalBusinessDetailService.approvalBusinessMap(list.stream().map(SysApprovalBusinessExt::getPkId).collect(Collectors.toList()));

            // 返回数据处理
            for (SysApprovalBusinessExt sysApprovalBusinessExt : list) {
                // 审批用时
                Date useTime = sysApprovalBusinessExt.getCreationTime();
                // 返回明细数据列表
                List<IndexApprovalDetailVO> detailList = new ArrayList<>();
                // 发起人信息
                IndexApprovalDetailVO tmpIndexApprovalDetailVO = new IndexApprovalDetailVO();
                tmpIndexApprovalDetailVO.setNickName(sysApprovalBusinessExt.getUserName());
                tmpIndexApprovalDetailVO.setDeptName(sysApprovalBusinessExt.getDeptName());
                tmpIndexApprovalDetailVO.setUseTime("");
                detailList.add(tmpIndexApprovalDetailVO);

                // 审批进度下标
                Integer approvalIndex = null;

                // 遍历审批明细
                List<SysApprovalBusinessDetail> tmpDetailList = detailMap.get(sysApprovalBusinessExt.getPkId());
                for (int i = 0; i < tmpDetailList.size(); i++) {
                    SysApprovalBusinessDetail sysApprovalBusinessDetail = tmpDetailList.get(i);

                    // 返回明细数据
                    IndexApprovalDetailVO indexApprovalDetailVO = new IndexApprovalDetailVO();
                    indexApprovalDetailVO.setNickName(sysApprovalBusinessDetail.getApprover());
                    indexApprovalDetailVO.setDeptName(sysApprovalBusinessDetail.getApproverDept());
                    detailList.add(indexApprovalDetailVO);

                    // 处理审批用时
                    if (null != sysApprovalBusinessDetail.getApproverTime()) {
                        if (null != useTime) {
                            // 处理审核用时
                            indexApprovalDetailVO.setUseTime(DateUtils.getDateDifferenceVal(sysApprovalBusinessDetail.getApproverTime(), useTime));
                        }
                        useTime = sysApprovalBusinessDetail.getApproverTime();
                    } else {
                        // 记录审批到哪一步的下标
                        if (null == approvalIndex) {
                            approvalIndex = i;
                        }
                    }
                }

                resultList.add(IndexApprovalVO.builder()
                        .pkId(sysApprovalBusinessExt.getPkId())
                        .approvalCode(sysApprovalBusinessExt.getApprovalCode())
                        .approvalBusiness(sysApprovalBusinessExt.getApprovalBusiness())
                        .approvalBusinessVal(sysApprovalBusinessExt.getApprovalBusinessVal())
                        .approveStatus(sysApprovalBusinessExt.getApprovalStatus())
                        .signSource(sysApprovalBusinessExt.getSignSource())
                        .creationTime(sysApprovalBusinessExt.getCreationTime())
                        .creation(sysApprovalBusinessExt.getUserName())
                        .detailList(detailList)
                        .approvalIndex(approvalIndex)
                        .approvalFlag(userId.equals(sysApprovalBusinessExt.getPkUser()) ? EYesNo.YES.getIntValue() : EYesNo.NO.getIntValue())
                        .build());
            }
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 已办数据
     *
     * @param param
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_COMPLETE, method = EOperationMethod.SELECT)
    @GetMapping("/complete-approval")
    public TableDataInfo completeApproval(CompleteApprovalParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getEndTime());

        startPage();
        List<SysApprovalBusinessExt> list = iSysApprovalBusinessService.completeApproval(param, SecurityUtils.getUserId(), SecurityUtils.getPkCountry());

        // 返回前台数据
        List<IndexApprovalVO> resultList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(list)) {
            // 返回数据处理
            List<Long> pkIdList = list.stream().map(SysApprovalBusinessExt::getPkId).collect(Collectors.toList());
            // 批量查询审批明细数据
            Map<Long, List<SysApprovalBusinessDetail>> detailMap = iSysApprovalBusinessDetailService.approvalBusinessMap(pkIdList);
            // 批量查询审批抄送人数据
            Map<Long, List<SysApprovalBusinessSendExt>> sendMap = iSysApprovalBusinessSendService.approvalSendMap(pkIdList);

            for (SysApprovalBusinessExt sysApprovalBusinessExt : list) {
                // 审批用时
                Date useTime = sysApprovalBusinessExt.getCreationTime();
                // 返回明细数据列表
                List<IndexApprovalDetailVO> detailList = new ArrayList<>();
                // 返回抄送人数据
                String sendStr = "";

                // 发起人信息
                IndexApprovalDetailVO tmpIndexApprovalDetailVO = new IndexApprovalDetailVO();
                tmpIndexApprovalDetailVO.setNickName(sysApprovalBusinessExt.getUserName());
                tmpIndexApprovalDetailVO.setDeptName(sysApprovalBusinessExt.getDeptName());
                tmpIndexApprovalDetailVO.setUseTime("");
                detailList.add(tmpIndexApprovalDetailVO);

                // 审批进度下标
                Integer approvalIndex = null;

                // 遍历审批明细
                List<SysApprovalBusinessDetail> tmpDetailList = detailMap.get(sysApprovalBusinessExt.getPkId());
                for (int i = 0; i < tmpDetailList.size(); i++) {
                    SysApprovalBusinessDetail sysApprovalBusinessDetail = tmpDetailList.get(i);

                    IndexApprovalDetailVO indexApprovalDetailVO = new IndexApprovalDetailVO();
                    indexApprovalDetailVO.setNickName(sysApprovalBusinessDetail.getApprover());
                    indexApprovalDetailVO.setDeptName(sysApprovalBusinessDetail.getApproverDept());
                    detailList.add(indexApprovalDetailVO);

                    // 处理审批用时
                    if (null != sysApprovalBusinessDetail.getApproverTime()) {
                        if (null != useTime) {
                            // 处理审核用时
                            indexApprovalDetailVO.setUseTime(DateUtils.getDateDifferenceVal(sysApprovalBusinessDetail.getApproverTime(), useTime));
                        }
                        useTime = sysApprovalBusinessDetail.getApproverTime();
                    } else {
                        // 记录审批到哪一步的下标
                        if (null == approvalIndex) {
                            approvalIndex = i;
                        }
                    }
                }

                // 抄送人列表数据
                List<SysApprovalBusinessSendExt> approvalSendList = sendMap.get(sysApprovalBusinessExt.getPkId());
                // 抄送人返回VO列表
                List<IndexApprovalReceiveVO> receiveVOList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(approvalSendList)) {
                    // 处理抄送人
                    StringBuilder sb = new StringBuilder();
                    for (SysApprovalBusinessSendExt approvalBusinessSend : approvalSendList) {
                        sb.append(",").append(approvalBusinessSend.getNickName());

                        receiveVOList.add(IndexApprovalReceiveVO.builder()
                                .receiveName(approvalBusinessSend.getNickName())
                                .receiveStatus(approvalBusinessSend.getReceiveStatus())
                                .build());
                    }
                    sendStr = sb.substring(1);
                }

                resultList.add(IndexApprovalVO.builder()
                        .pkId(sysApprovalBusinessExt.getPkId())
                        .approvalCode(sysApprovalBusinessExt.getApprovalCode())
                        .approvalBusiness(sysApprovalBusinessExt.getApprovalBusiness())
                        .approvalBusinessVal(sysApprovalBusinessExt.getApprovalBusinessVal())
                        .approveStatus(sysApprovalBusinessExt.getApprovalStatus())
                        .approvalOperation(sysApprovalBusinessExt.getApprovalOperation())
                        .useTime(DateUtils.getDateDifferenceVal(sysApprovalBusinessExt.getModifiedTime(), sysApprovalBusinessExt.getCreationTime()))
                        .creation(sysApprovalBusinessExt.getUserName())
                        .creationTime(sysApprovalBusinessExt.getCreationTime())
                        .endTime(sysApprovalBusinessExt.getEndTime())
                        .signSource(sysApprovalBusinessExt.getSignSource())
                        .detailList(detailList)
                        .approvalIndex(approvalIndex)
                        .sendStr(sendStr)
                        .receiveList(receiveVOList)
                        .build());
            }
        }

        TableDataInfo tableDataInfo = getDataTable(list);
        tableDataInfo.setRows(resultList);
        return tableDataInfo;
    }

    /**
     * 导出已办数据
     *
     * @param response
     * @param param
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_COMPLETE, method = EOperationMethod.EXPORT)
    @PostMapping("/export-approval")
    public void exportApproval(HttpServletResponse response, CompleteApprovalParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getEndTime());

        List<SysApprovalBusinessExt> list = iSysApprovalBusinessService.completeApproval(param, SecurityUtils.getUserId(), SecurityUtils.getPkCountry());

        // 返回前台数据
        List<IndexApprovalVO> resultList = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(list)) {
            // 获取需要翻译的枚举翻译
            Map<String, String> transactionMap = iTransactionCommonService.exportEnumTransaction(ESignSource.values(), EApprovalBusiness.values(), EApproveStatus.values());

            // 返回数据处理
            List<Long> pkIdList = list.stream().map(SysApprovalBusinessExt::getPkId).collect(Collectors.toList());
            // 批量查询审批明细数据
            Map<Long, List<SysApprovalBusinessDetail>> detailMap = iSysApprovalBusinessDetailService.approvalBusinessMap(pkIdList);
            // 批量查询审批抄送人数据
            Map<Long, List<SysApprovalBusinessSendExt>> sendMap = iSysApprovalBusinessSendService.approvalSendMap(pkIdList);

            for (SysApprovalBusinessExt sysApprovalBusinessExt : list) {
                // 审批用时
                Date useTime = sysApprovalBusinessExt.getCreationTime();
                // 返回签呈进度数据
                String detailStr = "";
                // 返回抄送人数据
                String sendStr = "";

                StringBuilder detailSb = new StringBuilder();
                // 遍历审批明细
                for (SysApprovalBusinessDetail sysApprovalBusinessDetail : detailMap.get(sysApprovalBusinessExt.getPkId())) {
                    detailSb.append(sysApprovalBusinessDetail.getApprover()).append("(").append(sysApprovalBusinessDetail.getApproverDept()).append("),用时:").append(DateUtils.getDateDifferenceVal(sysApprovalBusinessDetail.getApproverTime(), useTime)).append("; \n");

                    useTime = sysApprovalBusinessDetail.getApproverTime();
                }
                detailStr = detailSb.toString();

                List<SysApprovalBusinessSendExt> approvalSendList = sendMap.get(sysApprovalBusinessExt.getPkId());
                if (CollectionUtil.isNotEmpty(approvalSendList)) {
                    // 处理抄送人
                    StringBuilder sendSb = new StringBuilder();
                    for (SysApprovalBusinessSendExt sysApprovalBusinessSend : approvalSendList) {
                        sendSb.append(",").append(sysApprovalBusinessSend.getNickName());
                    }
                    sendStr = sendSb.substring(1);
                }

                // 如果自定义签呈业务类型内容存在，则优先使用
                String approvalBusinessVal = sysApprovalBusinessExt.getApprovalBusinessVal();
                if (StringUtils.isEmpty(approvalBusinessVal)) {
                    approvalBusinessVal = transactionMap.get(EnumsPrefixConstants.APPROVAL_BUSINESS + sysApprovalBusinessExt.getApprovalBusiness());
                }

                resultList.add(IndexApprovalVO.builder()
                        .pkId(sysApprovalBusinessExt.getPkId())
                        .approvalCode(sysApprovalBusinessExt.getApprovalCode())
                        .approvalBusiness(sysApprovalBusinessExt.getApprovalBusiness())
                        .approvalBusinessVal(approvalBusinessVal)
                        .approveStatus(sysApprovalBusinessExt.getApprovalStatus())
                        .approveStatusVal(transactionMap.get(EnumsPrefixConstants.APPROVE_STATUS + sysApprovalBusinessExt.getApprovalStatus()))
                        .approvalOperation(sysApprovalBusinessExt.getApprovalOperation())
                        .useTime(DateUtils.getDateDifferenceVal(sysApprovalBusinessExt.getModifiedTime(), sysApprovalBusinessExt.getCreationTime()))
                        .creationTime(sysApprovalBusinessExt.getCreationTime())
                        .endTime(sysApprovalBusinessExt.getEndTime())
                        .signSource(sysApprovalBusinessExt.getSignSource())
                        .signSourceVal(transactionMap.get(EnumsPrefixConstants.SIGN_SOURCE + sysApprovalBusinessExt.getSignSource()))
                        .creationTime(sysApprovalBusinessExt.getCreationTime())
                        .creation(sysApprovalBusinessExt.getUserName())
                        .detailStr(detailStr)
                        .sendStr(sendStr)
                        .build());
            }
        }

        ExcelUtil<IndexApprovalVO> util = new ExcelUtil<>(IndexApprovalVO.class);
        util.exportExcel(response, resultList, "签呈数据导出");
    }

    /**
     * 接收签呈数量
     *
     * @return
     */
    @GetMapping("/receive-approval-num")
    public AjaxResult receiveApprovalNum() {
        return AjaxResult.success(iSysApprovalBusinessReceiveService.listReceiveCount(SecurityUtils.getUserId(), SecurityUtils.getPkCountry()));
    }

    /**
     * 接收签呈列表
     *
     * @param param 查询入参
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_RECEIVE, method = EOperationMethod.SELECT)
    @GetMapping("/receive-approval-list")
    public TableDataInfo receiveApprovalList(ReceiveApprovalQueryParam param) {
        param.setCreationTime(DateUtils.handTimeStartAndEnd(param.getCreationTime()));
        param.setSendTime(DateUtils.handTimeStartAndEnd(param.getSendTime()));

        List<ReceiveApprovalVO> resultList = new ArrayList<>();

        startPage();
        List<SysApprovalBusinessReceiveExt> list = iSysApprovalBusinessReceiveService.listReceive(param, SecurityUtils.getUserId(), SecurityUtils.getPkCountry());
        if (CollectionUtil.isNotEmpty(list)) {
            resultList = BeanUtil.copyToList(list, ReceiveApprovalVO.class);
        }
        TableDataInfo tableDataInfo = getDataTable(list);
        tableDataInfo.setRows(resultList);
        return tableDataInfo;
    }


    /**
     * 接收签呈导出
     *
     * @param param 查询入参
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_RECEIVE, method = EOperationMethod.EXPORT)
    @PostMapping("/receive-approval-export")
    public void receiveApprovalExport(HttpServletResponse response, ReceiveApprovalQueryParam param) {
        param.setSendTime(DateUtils.handTimeStartAndEnd(param.getSendTime()));

        List<ReceiveApprovalVO> resultList = new ArrayList<>();

        List<SysApprovalBusinessReceiveExt> list = iSysApprovalBusinessReceiveService.listReceive(param, SecurityUtils.getUserId(), SecurityUtils.getPkCountry());
        if (CollectionUtil.isNotEmpty(list)) {
            // 获取需要翻译的枚举翻译
            Map<String, String> transactionMap = iTransactionCommonService.exportEnumTransaction(EApprovalBusiness.values(), EReadState.values());

            resultList = BeanUtil.copyToList(list, ReceiveApprovalVO.class);
            for (ReceiveApprovalVO receiveApprovalVO : resultList) {
                receiveApprovalVO.setApprovalBusinessVal(transactionMap.get(EnumsPrefixConstants.APPROVAL_BUSINESS + receiveApprovalVO.getApprovalBusiness()));
                receiveApprovalVO.setReceiveStatusVal(transactionMap.get(EnumsPrefixConstants.READ_STATE + receiveApprovalVO.getReceiveStatus()));
            }
        }

        ExcelUtil<ReceiveApprovalVO> util = new ExcelUtil<>(ReceiveApprovalVO.class);
        util.exportExcel(response, resultList, "接收签呈导出");
    }

    /**
     * 接收签呈
     *
     * @param param 接收签呈入参
     * @return
     */
    @Log(module = EOperationModule.HOME_PAGE, business = EOperationBusiness.APPROVAL_RECEIVE, method = EOperationMethod.UPDATE_STATUS)
    @PutMapping("/receive-approval")
    public AjaxResult receiveApproval(@RequestBody ReceiveApprovalParam param) {
        if (CollectionUtil.isEmpty(param.getPkIdList())) {
            // 缺少参数
            return AjaxResult.error(TransactionUtils.getContent(CommonMsgConstants.MISSING_PARAM));
        }

        UpdateWrapper<SysApprovalBusinessReceive> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("PK_RECEIVE", SecurityUtils.getUserId());
        updateWrapper.in("PK_APPROVAL_BUSINESS", param.getPkIdList());
        updateWrapper.set("RECEIVE_STATUS", EReadState.HAVE_READ.getValue());
        updateWrapper.set("RECEIVE_TIME", new Date());
        return toAjax(iSysApprovalBusinessReceiveService.update(updateWrapper));
    }

}
