package com.nantian.cloud.jljc.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nantian.cloud.jljc.entity.EnterpriseInfo;
import com.nantian.cloud.jljc.entity.TNotice;
import com.nantian.cloud.jljc.entity.TNoticeLog;
import com.nantian.cloud.jljc.service.EnterpriseInfoService;
import com.nantian.cloud.jljc.service.FeignUpmsService;
import com.nantian.cloud.jljc.service.TNoticeLogService;
import com.nantian.cloud.jljc.service.TNoticeService;
import com.nantian.cloud.jljc.vo.TreeMultiVo;
import com.nantian.sc.cloud.admin.api.dto.DeptTree;
import com.nantian.sc.cloud.admin.api.entity.SysDept;
import com.nantian.sc.cloud.admin.api.entity.SysDeptRelation;
import com.nantian.sc.cloud.admin.api.feign.RemoteDataScopeService;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.minio.service.MinioTemplate;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.nantian.cloud.jljc.vo.util.TreeVoUtil.findTreeMultiByRoot;

/**
 * 通知表
 *
 * @date 2020-09-23
 */
@Slf4j
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/tNotice")
@Api(value = "tNotice", tags = "通知表")
public class TNoticeController {
    @Autowired
    private TNoticeService tNoticeService;
    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private TNoticeLogService tNoticeLogService;
    @Autowired
    private EnterpriseInfoService enterpriseInfoService;
    @Autowired
    private FeignUpmsService upmsService;


    /**
     * 分页获取通知管理界面的通知列表(政府端)
     */
    @GetMapping("/pageManager")
    @SysLog("分页获取通知管理界面的通知列表(政府端)")
    @ApiOperation(value = "分页获取通知管理界面的通知列表(政府端)", notes = "分页获取通知管理界面的通知列表(政府端)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "tNotice", value = "通知表对象", required = false, dataType = "json", paramType = "path")
    })
    public R pageManager(Page page, TNotice tNotice) {
        tNotice.setDelFlag("1"); //筛选未删除项
        return R.ok(tNoticeService.pageManager(page, tNotice));
    }

    /**
     * 分页获取通知表(政府端)
     */
    @GetMapping("/pageGov")
    @SysLog("分页获取通知表(政府端)")
    @ApiOperation(value = "分页获取通知表(政府端)", notes = "分页获取通知表(政府端)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "tNotice", value = "通知表对象", required = false, dataType = "json", paramType = "path")
    })
    public R pageGov(Page page, TNotice tNotice) {
        ScUser u = SecurityUtils.getUser();
        return R.ok(tNoticeService.pageGov(page, tNotice, u.getId(), u.getDeptId()));
    }

    /**
     * 分页获取通知表(企业端)
     */
    @GetMapping("/pageCmp")
    @SysLog("分页获取通知表(企业端)")
    @ApiOperation(value = "分页获取通知表(企业端)", notes = "分页获取通知表(企业端)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "tNotice", value = "通知表对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "epc", value = "企业社会信用编码", required = true, dataType = "int", paramType = "path")
    })
    public R pageCmp(Page page, TNotice tNotice, String epc) {
        if (epc == null || "".equals(epc)) {
            return R.failed("查看通知信息失败，企业信用编码不能为空！");
        }
        tNotice.setDelFlag("1"); //筛选未删除项
        return R.ok(tNoticeService.pageCmp(page, tNotice, epc));
    }

    /**
     * 根据id获取通知表(政府端)
     */
    @GetMapping("/getByIdGov")
    @SysLog("根据id获取通知表(政府端)")
    @ApiOperation(value = "根据id获取通知表(政府端)", notes = "根据id获取通知表(政府端)")
    @ApiImplicitParam(name = "id", value = "通知表id", required = true, dataType = "int", paramType = "path")
    public R getByIdGov(Integer id) {
        if (id == null) {
            return R.failed("查看通知信息失败，通知表id不能为空！");
        }
        ScUser u = SecurityUtils.getUser();
        //返回政府端通知详情以及是否已读消息状态
        return R.ok(tNoticeService.getByIdGov(id, u.getId(), u.getDeptId()));
    }

    /**
     * 根据id获取通知表(企业端)
     */
    @GetMapping("/getByIdCmp")
    @SysLog("根据id获取通知表(企业端)")
    @ApiOperation(value = "根据id获取通知表(企业端)", notes = "根据id获取通知表(企业端)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "通知表id", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "epc", value = "企业社会信用编码", required = true, dataType = "int", paramType = "path")
    })
    public R getByIdCmp(Integer id, String epc) {
        if (epc == null || "".equals(epc)) {
            return R.failed("查看通知信息失败，企业信用编码不能为空！");
        }
        if (id == null) {
            return R.failed("查看通知信息失败，通知表id不能为空！");
        }
        //返回企业端通知详情以及是否已读消息状态
        return R.ok(tNoticeService.getByIdCmp(id, epc));
    }

    /**
     * 统计未读消息条数(政府端)
     */
    @GetMapping("/noCountGov")
    @SysLog("统计未读消息条数(政府端)")
    @ApiOperation(value = "统计未读消息条数(政府端)", notes = "统计未读消息条数(政府端)")
    public R noCountGov() {
        ScUser u = SecurityUtils.getUser();
        //返回政府端未读条数，通过用户id和部门id，确定唯一一条政府的通知日志
        return R.ok(tNoticeService.noCountGov(u.getId(), u.getDeptId()));
    }

    /**
     * 统计未读消息条数(企业端)
     */
    @GetMapping("/noCount")
    @SysLog("统计未读消息条数(企业端)")
    @ApiOperation(value = "统计未读消息条数(企业端)", notes = "统计未读消息条数(企业端)")
    @ApiImplicitParam(name = "epc", value = "企业社会信用编码", required = true, dataType = "int", paramType = "path")
    public R noCount(String epc) {
        if (epc == null || "".equals(epc)) {
            return R.failed("查看通知信息失败，企业信用编码不能为空！");
        }
        return R.ok(tNoticeService.noCount(epc)); //返回企业端未读条数
    }

    /**
     * 更新通知信息(超期修改、报表审核结果)
     */
    @PostMapping("/reportNotice")
    @SysLog("更新通知信息(超期修改、报表审核结果)")
    @ApiOperation(value = "更新通知信息(超期修改、报表审核结果)", notes = "更新通知信息(超期修改、报表审核结果)")
    @ApiImplicitParam(name = "tNotice", value = "通知表信息", required = false, dataType = "json", paramType = "path")
    public R reportNotice(@RequestBody TNotice tNotice){
        ScUser u = SecurityUtils.getUser();
        tNotice.setUserid(u.getId());
        tNotice.setUpdateTime(new Date());
        tNotice.setDeptId(u.getDeptId());
        tNotice.setDelFlag("1");
        return R.ok(tNoticeService.saveOrUpdate(tNotice));
    }

    /**
     * 保存/修改通知表信息(政府端)
     */
    @PostMapping("/saveOrUp")
    @SysLog("保存/修改通知表信息(政府端)")
    @ApiOperation(value = "保存/修改通知表信息(政府端)", notes = "保存/修改通知表信息(政府端)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tNotice", value = "通知表信息", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "noticeFile", value = "文件流（通知表附件）", required = false, dataType = "File", paramType = "path"),
            @ApiImplicitParam(name = "overDateStr", value = "超期时间字符串", required = false, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "deptIDAraay", value = "通知的政府部门字符集", required = false, dataType = "string", paramType = "path")
    })
    public R saveOrUp(TNotice tNotice, MultipartFile noticeFile, String overDateStr, String deptIDAraay) throws Exception {
        log.error("保存/修改通知表信息：{}，##文件：{}，##超期时间字符串{}，##通知的政府部门字符集{}", tNotice, noticeFile, overDateStr, deptIDAraay);

        if ( StringUtils.isEmpty(tNotice.getZfDeptStr()) && StringUtils.isEmpty(tNotice.getEpcStr())) {
            return R.failed("请选择接收通知的单位！");
        }

        ScUser u = SecurityUtils.getUser();
        tNotice.setUserid(u.getId());
        tNotice.setUpdateTime(new Date());
        tNotice.setDeptId(u.getDeptId());
        tNotice.setDelFlag("1");
        tNotice.setUserDept(u.getUserDept());

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        if (overDateStr != null && !"".equals(overDateStr)) {
            tNotice.setOverDate(new Date(overDateStr)); //Thu Sep 10 2020 00:00:00 GMT+0800 (中国标准时间)
        }

        if (noticeFile != null && noticeFile.getSize() > 0) {
            tNotice.setFile(getFileUrl(noticeFile));
        }

        if (StringUtils.isNotEmpty(tNotice.getEpcStr()) && "undefined".equals(tNotice.getEpcStr())) {
            //发送通知至企业端，若选择企业为undefined时，就默认下发通知至所有企业
            EnterpriseInfo enterpriseInfo = new EnterpriseInfo();
            enterpriseInfo.setDelFlag("1"); //查询未删除项
            List<EnterpriseInfo> enterpriseInfoList = enterpriseInfoService.list(Wrappers.query(enterpriseInfo));
            StringBuilder builder = new StringBuilder();
            if (enterpriseInfoList.size() > 0) {
                for (EnterpriseInfo info : enterpriseInfoList) {
                    builder.append(info.getEnterpriseCode() + ",");
                }
            }
            //去掉最后一个字符
            String epcStr = builder.deleteCharAt(builder.length() - 1).toString();
            tNotice.setEpcStr(epcStr);
        }

        /*if (deptIDAraay == null || "".equals(deptIDAraay)) {
            //发送通知的时候，若没有选择政府，就默认只有当前部门的政府可以收到信息
            R<List<SysDeptRelation>> descendantList = upmsService.getDescendantList(u.getDeptId());
            if (descendantList.getCode() == 0 && descendantList.getData().size() > 0) {
                //服务调用成功，并且返回数据不为空
                List<Integer> deptIdList = descendantList
                        .getData().stream().map(SysDeptRelation::getDescendant)
                        .collect(Collectors.toList());
                String deptStr = StringUtils.join(deptIdList, ",");
                tNotice.setZfDeptStr(deptStr);
            } else {
                tNotice.setZfDeptStr(u.getDeptId().toString());
            }
        } else {
            *//*if (deptIDAraay.contains(u.getDeptId().toString())) {
                tNotice.setZfDeptStr(deptIDAraay);
            }else{
                //发送通知的部门，默认本部门需要接收
                tNotice.setZfDeptStr(deptIDAraay+","+u.getDeptId());
            }*//*
            tNotice.setZfDeptStr(deptIDAraay);
        }*/

        return R.ok(tNoticeService.saveOrUpdate(tNotice));
    }

    /**
     * 获取通知部门本级及下级树形下拉框
     */
    @GetMapping("/getDeptTree")
    @SysLog("获取通知部门本级及下级树形下拉框")
    @ApiOperation(value = "获取通知部门本级及下级树形下拉框", notes = "获取通知部门本级及下级树形下拉框")
    public R<List<TreeMultiVo>> getDeptTree() {
        R<List<SysDept>> treeBySelect = upmsService.getList();
        if (treeBySelect.getCode() == 0 && treeBySelect.getData().size() > 0) {
            List<TreeMultiVo> treeList = treeBySelect.getData().stream()
                    .filter(dept -> !dept.getDeptId().equals(dept.getParentId()))
                    .sorted(Comparator.comparingInt(SysDept::getSort))
                    .map(dept -> {
                        TreeMultiVo deptNode = new TreeMultiVo();
                        deptNode.setId(dept.getDeptId());
                        deptNode.setParentId(dept.getParentId());
                        deptNode.setTitle(dept.getName());
                        return deptNode;
                    }).collect(Collectors.toList());
            Integer deptId = SecurityUtils.getUser().getDeptId();
            return R.ok(findTreeMultiByRoot(treeList, deptId));
        } else {
            return  R.ok();
        }
    }


    public String getFileUrl(MultipartFile file) throws Exception {
        String uuid = UUID.randomUUID().toString();
        InputStream inputStream = file.getInputStream(); //得到文件流
        String fileName = file.getOriginalFilename();    //文件名（含后缀）
        minioTemplate.putObject("jljc", uuid, inputStream, inputStream.available(), "application/octet-stream");
        return fileName + "<" + uuid;
    }

    /**
     * 删除通知表(政府端)
     */
    @DeleteMapping("/delete")
    @SysLog("删除通知表(政府端)")
    @ApiOperation(value = "删除通知表(政府端)", notes = "删除通知表(政府端)")
    @ApiImplicitParam(name = "tNoticeId", value = "id", required = true, dataType = "int", paramType = "path")
    public R removeById(Integer id) {
        TNotice tNotice = tNoticeService.getById(id);
        if (tNotice == null) {
            return R.failed("通知表不存在，删除失败");
        }
        ScUser u = SecurityUtils.getUser();
        tNotice.setDelFlag("4");
        tNotice.setUpdateTime(new Date());
        tNotice.setUserid(u.getId());
        return R.ok(tNoticeService.updateById(tNotice));
    }

}
