package com.testor.module.notice.controller;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.rule.service.SysRuleService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.module.isRead.model.domain.TSysIsRead;
import com.testor.module.isRead.service.TSysIsReadService;
import com.testor.module.news.model.domain.SysNews;
import com.testor.module.notice.model.domain.DetailNotice;
import com.testor.module.notice.model.domain.TSysNotice;
import com.testor.module.notice.model.domain.TSysNoticeTop;
import com.testor.module.notice.model.dto.TSysNoticeDelParam;
import com.testor.module.notice.model.dto.TSysNoticeParam;
import com.testor.module.notice.service.TSysNoticeService;
import com.testor.module.notice.service.TSysNoticeTopService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.supers.SuperController;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * noticeController
 *
 * @author tong-framework
 * @date 2022-04-27 18:10:12
 */
@RestController
@RequestMapping("/notice")
@Api(value = "TSysNotice", tags = "公告管理模块")
@Slf4j
public class TSysNoticeController extends SuperController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private TSysNoticeService tSysNoticeService;
    @Autowired
    private SysRuleService sysRuleService;
    @Autowired
    private TSysIsReadService tSysIsReadService;
    @Autowired
    private TSysNoticeTopService tSysNoticeTopService;

    @ApiOperation(value = "获取首页 新闻和公告 ", notes = "Get TSysNotice By Id")
    @GetMapping(value = "/getNewsAndNotice")
    public BaseResponse<BaseResponseList<TSysNotice>> getNewsAndNotice(TSysNoticeParam param) {
        String orgId = param.getOrgId();
        if (StringHelper.isEmpty(orgId)) {
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        //获取顶置信息
        TSysNotice tSysNotice = userTopNotice();
        IPage<TSysNotice> read = tSysNoticeService.getNewsAndNotice(param, orgId);
        BaseResponse<BaseResponseList<TSysNotice>> baseResponse = new BaseResponse<>();
        BaseResponseList<TSysNotice> baseResponseList = new BaseResponseList<>();
        List<TSysNotice> records = read.getRecords();
        //如果顶置信息不为空添加到第一列
        if (tSysNotice.getId() != null) {
            records.add(0, tSysNotice);
            baseResponseList.setData(records);
        } else {
            baseResponseList.setData(records);
        }
        baseResponseList.setTotal(read.getTotal());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    /* Generated Method*/
    @ApiOperation(value = "新增公告", notes = "必传标题  内容   接收对象")
    @PostMapping(value = "/add")
    public BaseResponse<TSysNotice> addEntity(@RequestBody TSysNotice addRequest) throws Exception {
        return tSysNoticeService.addEntity(addRequest);
    }

    /* Generated Method*/
    @ApiOperation(value = "置顶公告", notes = "必传标题  内容   接收对象")
    @PostMapping(value = "/top")
    public BaseResponse<TSysNotice> top(@RequestBody TSysNotice addRequest) throws Exception {
        addRequest.setUserOrgId(ContextUtils.getLoginUser().getOrgId());
        return tSysNoticeTopService.top(addRequest);
    }

    /* Generated Method*/
    @ApiOperation(value = "取消置顶", notes = "必传标题  内容   接收对象")
    @PostMapping(value = "/cancelTop")
    public BaseResponse<TSysNotice> cancelTop(@RequestBody TSysNotice addRequest) throws Exception {
        return tSysNoticeTopService.cancelTop(addRequest);
    }

    //	@ApiOperation(value = "根据id获取公告 ", notes = "Get TSysNotice By Id")
//	@GetMapping(value = "/get")
    public BaseResponse getById(String id) {
        return tSysNoticeService.getByIds(id);
    }

    @ApiOperation(value = "修改公告 ", notes = "需要传公告id  如果保存草稿 processStatus 等于 4")
    @PutMapping(value = "/update")
    public BaseResponse updateEntity(@RequestBody DetailNotice updateRequest) throws Exception {
        return tSysNoticeService.updateEntity(updateRequest);
    }

    @ApiOperation(value = "删除公告 ", notes = "需要传公告id")
    @PostMapping(value = "/delete")
    public BaseResponse deleteEntity(@RequestBody TSysNoticeDelParam deleteRequest) throws Exception {

        return tSysNoticeService.deleteNotice(deleteRequest);
    }

    @ApiOperation(value = "物理删除公告模块", notes = "需要传公告id")
    @GetMapping("/drop")
    public BaseResponse dropNotice(String id) throws Exception {
        BaseResponse<TSysNotice> response = new BaseResponse<>();
        LambdaQueryWrapper<TSysNotice> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TSysNotice::getId, id);
        TSysNotice one = tSysNoticeService.getOne(queryWrapper);
        if (one == null) {
            throw new BusinessException("数据不存在");
        }
        boolean b = tSysNoticeService.removeById(id);
        return response;
    }

    @ApiOperation(value = "获取公告详情 ", notes = "需要传公告 id")
    @GetMapping(value = "/detail")
    public BaseResponse detail(TSysNotice tSysNotice) throws Exception {
        return tSysNoticeService.detail(tSysNotice);
    }

    @ApiOperation(value = "获取公告详情 修改已读未读状态 ", notes = "需要传公告 id 在台账页面调佣")
    @GetMapping(value = "/getIsRead")
    public BaseResponse getIsRead(TSysNotice tSysNotice) throws Exception {
        return tSysNoticeService.getIsRead(tSysNotice);
    }

    //	@GetMapping(value = "/getStatus")
    public BaseResponse getStatus() {
        Map<String, String> map = new HashMap<>();
        map.put("3", "待审核");
        map.put("4", "草稿");
        map.put("5", "审核通过");
        map.put("6", "撤销发布");
        map.put("7", "驳回");
        BaseResponse<Object> response = new BaseResponse<>();
        response.setData(map);
        return response;
    }

    //	@ApiOperation(value = "批量删除notice", notes = "delete TSysNotice by batch Id")
//	@PutMapping(value = "/batch_delete")
    public BaseResponse<BizGeneralResponse> deleteEntityBatch(
            @RequestBody TSysNoticeDelParam deleteRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(deleteRequest) && (!deleteRequest.getIds().isEmpty())) {
            /* 批量删除 */
            List<TSysNotice> tSysNoticeList = new ArrayList<>();
            for (String id : deleteRequest.getIds()) {
                TSysNotice data = new TSysNotice();
                data.setId(id);
                data.setStatus(BizConstants.STATUS_DELETE);
                tSysNoticeList.add(data);
            }
            boolean result = tSysNoticeService.updateBatchById(tSysNoticeList);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @ApiOperation(value = "获取公告我的发布和草稿", notes = "获取草稿箱时传processStatus=4 ， 获取我的发布不需要传参数")
    @GetMapping(value = "/list")
    public BaseResponse<BaseResponseList<TSysNotice>> listEntity(TSysNoticeParam param, String startTime, String endTime) {

        return tSysNoticeService.listEntity(param, startTime, endTime);
    }

    @ApiOperation(value = "获取接收公告列表", notes = "时间查询条件 startTime 开始时间  endTime 结束时间 ")
    @GetMapping(value = "/datas")
    public BaseResponse<BaseResponseList<TSysNotice>> listAllEntity(TSysNoticeParam param, String startTime, String endTime, String levels) {
        BaseResponse<BaseResponseList<TSysNotice>> baseResponse = new BaseResponse<>();
        BaseResponseList<TSysNotice> baseResponseList = new BaseResponseList<>();
        String loginUserId = ContextUtils.getLoginUserId();
        String orgId = ContextUtils.getLoginUser().getOrgId();
        if ("1".equals(param.getIsRead())) {
            //获取已读数据
            String[] split = levels.split(",");
            List<String> list = Arrays.asList(split);
            IPage<TSysNotice> read = tSysNoticeService.getRead(param, startTime + " 00:00:00", endTime + " 23:59:59", list, loginUserId, orgId);
            read.getRecords().stream().forEach(item -> {
                item.setIsRead("1");
            });

            List<TSysNotice> records = read.getRecords();
            //获取顶置信息
            TSysNotice tSysNotice = userTopNotice();
            //如果顶置信息不为空添加到第一列
            if (tSysNotice.getId() != null) {
                records.add(0, tSysNotice);
                read.setTotal(read.getTotal() + 1);
                baseResponseList.setData(records);
            } else {
                baseResponseList.setData(read.getRecords());
            }
            baseResponseList.setTotal(read.getTotal());
            baseResponse.setData(baseResponseList);
            return baseResponse;
        }
        if ("0".equals(param.getIsRead())) {
            // 获取未读数据
            String[] split = levels.split(",");
            List<String> list = Arrays.asList(split);
            IPage<TSysNotice> unRead = tSysNoticeService.getUnRead(param, startTime + " 00:00:00", endTime + " 23:59:59", list, loginUserId, orgId);
            List<TSysNotice> records = unRead.getRecords();
            //获取顶置信息
            TSysNotice tSysNotice = userTopNotice();
            //如果顶置信息不为空添加到第一列
            if (tSysNotice.getId() != null) {
                records.add(0, tSysNotice);
                baseResponseList.setData(records);
                unRead.setTotal(unRead.getTotal() + 1);
            } else {
                baseResponseList.setData(records);
            }
            baseResponseList.setTotal(unRead.getTotal());
            baseResponse.setData(baseResponseList);
            return baseResponse;
        }
        Long page =
                StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit =
                StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<TSysNotice> resultPage = new Page<>(page, limit);
        QueryWrapper<TSysNotice> queryWrapper = this.createQuery(param, startTime, endTime, levels);
        Page<TSysNotice> resultList = tSysNoticeService.page(resultPage, queryWrapper);

        List<TSysNotice> records = resultList.getRecords();
        if (records.size() == 0) {
            Integer size = records.size();
            //获取顶置信息
            TSysNotice tSysNotice = userTopNotice();
            //如果顶置信息不为空添加到第一列
            if (tSysNotice.getId() != null) {
                records = new ArrayList<>();
                records.add(tSysNotice);
                baseResponseList.setData(records);
                size = size + 1;
            } else {
                baseResponseList.setData(records);
            }
            baseResponseList.setTotal(records.size());
            baseResponse.setData(baseResponseList);
            return baseResponse;
        }


        QueryWrapper<TSysIsRead> wrapper = new QueryWrapper<>();
        List<String> idList = new ArrayList<>();
        records.stream().forEach(item -> {
            String id = item.getId();
            idList.add(id);
        });
        wrapper.in(TSysIsRead.ARTICLE_ID, idList).eq(TSysIsRead.USER_ID, loginUserId);
        List<TSysIsRead> list = tSysIsReadService.list(wrapper);

        records.stream().forEach(p -> {
            p.setIsRead("0");
            list.stream().forEach(r -> {
                if ((p.getId().equals(r.getArticleId())) && (r.getUserId().equals(loginUserId))) {
                    p.setIsRead(r.getIsRead());
                }
            });
        });

        if ("0".equals(param.getIsRead())) {
            records = records.stream().filter(item -> item.getIsRead().equals("0")).collect(Collectors.toList());
        } else if ("1".equals(param.getIsRead())) {
            records = records.stream().filter(item -> item.getIsRead().equals("1")).collect(Collectors.toList());
        }
//        records = records.stream().sorted(Comparator.comparing(p -> p.getIsRead())).collect(Collectors.toList());
        records = records.stream()
                .sorted(Comparator.comparing(TSysNotice::getReleaseTime).reversed()
                        .thenComparing(TSysNotice::getIsRead)
                )
                .collect(Collectors.toList());

        Integer size = records.size();
        long total = resultList.getTotal();
        TSysNotice tSysNotice = userTopNotice();
        //如果顶置信息不为空添加到第一列
        if (tSysNotice.getId() != null) {
            records.add(0, tSysNotice);
            size = size + 1;
            total = total + 1;
            baseResponseList.setData(records);
        } else {
            baseResponseList.setData(records);
        }

        if ("0".equals(param.getIsRead()) || "1".equals(param.getIsRead())) {
            baseResponseList.setTotal(size);
        } else {
            baseResponseList.setTotal(total);
        }

//        baseResponseList.setTotal(records.size());
//        baseResponseList.setData(resultList.getRecords());
        baseResponse.setData(baseResponseList);
        return baseResponse;
    }

    private TSysNotice userTopNotice() {
        //获取用户所有父级公司ID;
        String orgId = ContextUtils.getLoginUser().getOrgId();
        SysOrg orgOrg = sysOrgService.getById(orgId);
        String orgIds = orgOrg.getParentIds() + "," + orgId;
        String[] split = orgIds.split(",");
        TSysNotice tSysNotice = new TSysNotice();
        //查看当前用户的父级公司是否有顶置消息
        TSysNoticeTop top = tSysNoticeTopService.getOne(new QueryWrapper<TSysNoticeTop>().in("org_id", split).eq("status", "0"));
        if (top != null) {
            String noticeId = top.getNoticeId();
            tSysNotice = tSysNoticeService.getById(noticeId);
            tSysNotice.setTop(0);
            tSysNotice.setType("公告");
        }
        return tSysNotice;
    }

    /* Private Methods */

    /**
     * 列表查询条件及查询参数
     */
    private QueryWrapper<TSysNotice> createQuery(TSysNoticeParam queryParam, String startTime, String endTime, String levels) {
        QueryWrapper<TSysNotice> queryWrapper = new QueryWrapper<>();
//        String userId = ContextUtils.getLoginUser().getUserId();
//        SysUser sysUser = sysUserService.getById(userId);
//		if (sysUser != null) {
//			String orgId = sysUser.getOrgId();
//			queryWrapper.like("receiver_obj", orgId);
//		}
        if (levels != null) {
            String[] split = levels.split(",");
            queryWrapper.in("\"level\"", split);
        }
//        if (sysUser != null) {
//            NOTICE_RULE
//            String orgId = sysUser.getOrgId();
//            queryWrapper.lambda().apply(1 == 1, "FIND_IN_SET ('" + orgId + "',receiver_obj)");
//        }
        // Data Rule
//        if (StringUtils.isNotEmpty(queryParam.getDataRuleCode())) {
        String rule = sysRuleService.dataRuleScope("NOTICE_RULE");
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(rule)) {
            queryWrapper.apply(rule);
        }
//        }

        if (!StringUtils.isEmpty(startTime)) {
            String start = startTime + " 00:00:00";
            queryWrapper.ge("release_time", start);
        }
        if (!StringUtils.isEmpty(endTime)) {
            String end = endTime + " 23:59:59";
            queryWrapper.le("release_time", end);
        }
        queryWrapper.orderByDesc("release_time");
        if (StringHelper.isNotEmpty(queryParam.getCreateBy())) {
            queryWrapper.eq(TSysNotice.CREATE_BY, queryParam.getCreateBy());
        }
        if (StringHelper.isNotEmpty(queryParam.getReceiverObj())) {
            queryWrapper.eq(TSysNotice.RECEIVER_OBJ, queryParam.getReceiverObj());
        }
        if (StringHelper.isNotEmpty(queryParam.getReleaseUnit())) {
            queryWrapper.eq(TSysNotice.RELEASE_UNIT, queryParam.getReleaseUnit());
        }
        if (StringHelper.isNotEmpty(queryParam.getTitle())) {
            queryWrapper.like(TSysNotice.TITLE, queryParam.getTitle());
        }
        if (StringHelper.isNotEmpty(queryParam.getContent())) {
            queryWrapper.eq(TSysNotice.CONTENT, queryParam.getContent());
        }
//        if (StringHelper.isNotEmpty(queryParam.getIsRead())) {
//            queryWrapper.eq(TSysNotice.IS_READ, queryParam.getIsRead());
//        }
//        if (StringHelper.isNotEmpty(queryParam.getProcessStatus())) {
        queryWrapper.eq(TSysNotice.PROCESS_STATUS, "5");
        queryWrapper.ne(SysNews.PROCESS_STATUS, "6");
//        }
        if (StringHelper.isNotEmpty(queryParam.getProcessId())) {
            queryWrapper.eq(TSysNotice.PROCESS_ID, queryParam.getProcessId());
        }
        if (StringHelper.isNotEmpty(queryParam.getParentId())) {
            queryWrapper.eq(TSysNotice.PARENT_ID, queryParam.getParentId());
        }
        if (StringHelper.isNotEmpty(queryParam.getRejectOpinion())) {
            queryWrapper.eq(TSysNotice.REJECT_OPINION, queryParam.getRejectOpinion());
        }
        if (StringHelper.isNotEmpty(queryParam.getTenantId())) {
            queryWrapper.eq(TSysNotice.TENANT_ID, queryParam.getTenantId());
        }
        if (StringHelper.isNotEmpty(queryParam.getStatus())) {
            queryWrapper.eq(TSysNotice.STATUS, queryParam.getStatus());
        } else {
            queryWrapper.ne(TSysNotice.STATUS, 3);
            queryWrapper.ne(TSysNotice.STATUS, BizConstants.STATUS_DELETE);
        }
        if (StringHelper.isNotEmpty(queryParam.getOrderBy())) {
            if (StringHelper.isNotEmpty(queryParam.getOrderType())
                    && BizConstants.ASC.equals(queryParam.getOrderType())) {
                queryWrapper.orderByAsc(queryParam.getOrderBy());
            } else {
                queryWrapper.orderByDesc(queryParam.getOrderBy());
            }
        } else {
            queryWrapper.orderByDesc(SysNews.UPDATE_DATE);
        }
        return queryWrapper;
    }

    public String formatDateTime(LocalDateTime createDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = createDate.format(fmt);
        return format;
    }
}
