package com.yeejoin.precontrol.controller;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import com.yeejoin.precontrol.common.entity.publics.BaseEntity;
import com.yeejoin.precontrol.common.publish.MessageEventPublish;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.precontrol.common.dto.CommonPageableDto;
import com.yeejoin.precontrol.common.entity.BadManagementPerson;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.entity.PersonMessage;
import com.yeejoin.precontrol.common.entity.Project;
import com.yeejoin.precontrol.common.enums.MessageSalaryTypeEnum;
import com.yeejoin.precontrol.common.enums.MessageSubTypeEnum;
import com.yeejoin.precontrol.common.enums.MessageTypeEnum;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.IBadManagementPersonService;
import com.yeejoin.precontrol.common.service.IBadManagementService;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IPersonMessageService;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.service.IProjectService;
import com.yeejoin.precontrol.common.service.ITaskService;
import com.yeejoin.precontrol.common.utils.DateUtils;
import com.yeejoin.precontrol.common.utils.StringUtil;
import com.yeejoin.precontrol.common.vo.PersonMessageOneVo;
import com.yeejoin.precontrol.common.vo.PersonVo;
import com.yeejoin.precontrol.common.vo.SingTaskBadManagementVo;
import com.yeejoin.precontrol.controller.publics.BaseController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * @author duanwei
 * @date 2020-06-30
 */
@RestController
@Api(tags = "我的消息Api")
@RequestMapping(value = "/person-message", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class PersonMessageController extends BaseController {
    /**
     * 人员消息服务
     */
    @Autowired
    IPersonMessageService iPersonMessageService;
    /**
     * 人员关系表服务
     */
    @Autowired
    IPersonAscriptionService iPersonAscriptionService;

    @Autowired
    IPersonService iPersonService;

    @Autowired
    ICompanyService iCompanyService;

    @Autowired
    ITaskService iTaskService;

    @Autowired
    IBadManagementService iBadManagementService;

    /**
     * 文件服务器地址
     */
    @Value("${fileserver.domain}")
    String fileServerUrl;

    @Autowired
    IBadManagementPersonService iBadManagementPersonService;

    @Autowired
    IProjectService iProjectService;

    @Autowired
    MessageEventPublish messageEventPublish;

    /**
     * 新增
     *
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "新增", notes = "新增")
    public boolean savePersonMessage(HttpServletRequest request, @RequestBody PersonMessage personMessage) {
        return iPersonMessageService.save(personMessage);
    }

    /**
     * 根据id删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
    public boolean deleteById(HttpServletRequest request, @PathVariable Long id) {
        return iPersonMessageService.removeById(id);
    }

    /**
     * 修改
     *
     * @return
     */
    @RequestMapping(value = "/updateById", method = RequestMethod.PUT)
    @ApiOperation(httpMethod = "PUT", value = "修改", notes = "修改")
    public boolean updateByIdPersonMessage(HttpServletRequest request, @RequestBody PersonMessage personMessage) {
        return iPersonMessageService.updateById(personMessage);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
    public PersonMessage selectById(HttpServletRequest request, @PathVariable Long id) {
        PersonMessage personMessage = iPersonMessageService.getById(id);
        personMessage.setTypeName(MessageTypeEnum.getNameByType(personMessage.getType()));
        return personMessage;
    }

    /**
     * 列表分页查询
     *
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
    public Object listPage(String pageNum, String pageSize, PersonMessage personMessage) {
        Person person = getPerson();
        Page<PersonMessage> pageBean;
        LambdaQueryWrapper<PersonMessage> personMessageQueryWrapper = new LambdaQueryWrapper<>();
        if (personMessage.getType() != null) {
            personMessageQueryWrapper.eq(PersonMessage::getType, personMessage.getType());
        }
        if (personMessage.getContent() != null) {
            personMessageQueryWrapper.like(PersonMessage::getContent, personMessage.getContent());
        }
        IPage<PersonMessage> page;
        if (StringUtils.isBlank(pageNum) || StringUtils.isBlank(pageSize)) {
            pageBean = new Page<>(0, Long.MAX_VALUE);
        } else {
            pageBean = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        }
        personMessageQueryWrapper.eq(PersonMessage::getPersonId, person.getId())
                .orderByDesc(PersonMessage::getCreateDate);
        page = iPersonMessageService.page(pageBean, personMessageQueryWrapper);
        List<PersonMessage> list = page.getRecords();
        list.stream().forEach(data -> {
            if (data.getType() == MessageTypeEnum.SALARY.getType()) {
                data.setTypeName(MessageSalaryTypeEnum.getNameByType(data.getSubType().intValue()));
            } else {
                data.setTypeName(MessageTypeEnum.getNameByType(data.getType()));
            }
            if (data.getProjectId() != null) {
                Project project = iProjectService.getById(data.getProjectId());
                data.setProjectName(project.getName());
            }
        });
        return page;
    }

    /**
     * 技术库分享
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/share", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "技术库分享", notes = "技术库分享")
    public Object share(@RequestBody Map<String, Object> map) {
        List<Map<String, Object>> content = (List<Map<String, Object>>) map.get("content");
        List<Map<String, Object>> target = (List<Map<String, Object>>) map.get("target");
        if (content == null || target == null) {
            throw new BaseException("分享失败，内容或者目标对象未空");
        }
        Set<Long> personIds = new HashSet<Long>();
        for (Map<String, Object> targetOne : target) {
            String type = (String) targetOne.get("type");
            // 如果是人 就添加单人
            if ("user".equals(type)) {
                personIds.add(Long.valueOf((String) targetOne.get("id")));
            }
            // 如果是公司 就添加公司下所有人
            else if ("group".equals(type)) {
                Long companyId = Long.valueOf((String) targetOne.get("id"));
                List<PersonAscription> personAscriptionList = iPersonAscriptionService
                        .list(new LambdaQueryWrapper<PersonAscription>().eq(PersonAscription::getCompanyId, companyId));
                Set<Long> cPersonIds = personAscriptionList.stream().map(p -> p.getPersonId())
                        .collect(Collectors.toSet());
                personIds.addAll(cPersonIds);
            }
        }

        List<PersonMessage> messageList = new ArrayList<PersonMessage>();
        for (Map<String, Object> contentOne : content) {
            Long objectId = Long.valueOf((String) contentOne.get("sequenceNbr"));
            String title = null;
            if (contentOne.get("docTitle") != null) {
//				Map<String, Object> docBaseInfo = (Map<String, Object>) contentOne.get("docBaseInfo");
                title = (String) contentOne.get("docTitle");
            }
            // 消息通知--知识分享
            for (Long personId : personIds) {
                PersonMessage message = new PersonMessage();
                message.setContent(title);
                message.setPersonId(personId);
                message.setTaskId(objectId);
                message.setType(MessageTypeEnum.KNOWLEDGE_SHARE.getType());
                message.setSubType(Long.valueOf(MessageSubTypeEnum.KNOWLEDGE_SHARE_MSG.getType()));
                message.setReadStatus(0);

                messageList.add(message);
            }
        }

        return iPersonMessageService.saveBatch(messageList);
    }

    /**
     * 标记已读
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/read", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "标记已读", notes = "标记已读")
    public Object read(@RequestBody Long id) {
        PersonMessage personMessage = new PersonMessage();
        personMessage.setId(id);
        personMessage.setReadStatus(1);
        return iPersonMessageService.updateById(personMessage);
    }

    /**
     * 未读信息数量
     *
     * @return
     */
    @RequestMapping(value = "/unReadCount", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = " 未读信息数量", notes = "未读信息数量")
    public Object unReadCount() {
        Person peron = getPerson();
        return iPersonMessageService.count(new LambdaQueryWrapper<PersonMessage>()
                .eq(PersonMessage::getPersonId, peron.getId()).eq(PersonMessage::getReadStatus, 0));
    }

    /**
     * 红码人员
     *
     * @return
     */
    @RequestMapping(value = "/redColorPerson", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "红码人员", notes = "红码人员")
    public Object listPage(@ApiParam(value = "分页条件 isAll=0 具体分页必传") CommonPageableDto pageable, Long companyId) {
        return iPersonService.redPerson(pageable,companyId).getRecords();
    }

    /**
     * 群体违章
     *
     * @return
     */
    @RequestMapping(value = "/badGroup", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "群体违章", notes = "群体违章")
    public Object badGroup(@ApiParam(value = "分页条件 isAll=0 具体分页必传") CommonPageableDto pageable, Long companyId) {
        LambdaQueryWrapper<PersonMessage> personMessageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        personMessageLambdaQueryWrapper.eq(PersonMessage::getObjectId, companyId);
        personMessageLambdaQueryWrapper.eq(PersonMessage::getType, MessageTypeEnum.COMPANY.getType());
        personMessageLambdaQueryWrapper.eq(PersonMessage::getSubType, MessageSubTypeEnum.MANY_PERSON.getType());
        List<PersonMessage> list = iPersonMessageService.list(personMessageLambdaQueryWrapper);
        List<SingTaskBadManagementVo> singTaskBadManagementVos = new ArrayList<>();
        if (StringUtil.isNotEmpty(list)) {
            Set<Long> taskId = list.stream().map(m -> m.getTaskId()).collect(Collectors.toSet());
            for (Long id : taskId) {
                SingTaskBadManagementVo singTaskBadManagementVo = (SingTaskBadManagementVo) iTaskService
                        .getBadManagement(id, null,null);
                singTaskBadManagementVos.add(singTaskBadManagementVo);
            }
        }
        //根据创建时间排序
        List<SingTaskBadManagementVo> sortedCollections = singTaskBadManagementVos.stream()
                .sorted(Comparator.comparing(SingTaskBadManagementVo::getCreateTime).reversed())
                .collect(Collectors.toList());
        return sortedCollections;
    }

    /**
     * 消息告警分包商信息
     *
     * @return
     */
    @RequestMapping(value = "/companyInfo", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "消息告警分包商信息", notes = "消息告警分包商信息")
    public Object companyInfo(Long id) {
        Map<String, Object> map = new HashMap<>();
        PersonMessage personMessage = iPersonMessageService.getById(id);
        Long projectId = personMessage.getProjectId();
        Project project = iProjectService.getById(projectId);
        map.put("projectName", null != projectId ? project.getName() : null);
        Long companyId = personMessage.getObjectId();
        Company company = iCompanyService.getById(companyId);
        map.put("companyName", company != null ? company.getName() : null);
        map.put("alarmTime", personMessage.getCreateDate());
        return map;
    }

    /**
     * 一周违章人员
     *
     * @return
     */
    @RequestMapping(value = "/weekBadPerson", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "一周违章人员", notes = "一周违章人员")
    public Object weekBadPerson(@ApiParam(value = "分页条件 isAll=0 具体分页必传") CommonPageableDto pageable, Long companyId)
            throws ParseException {
        LambdaQueryWrapper<BadManagementPerson> badManagementPersonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        badManagementPersonLambdaQueryWrapper.eq(BadManagementPerson::getCompanyId, companyId);
        List<String> thirtyDay = getDay(-7);
        badManagementPersonLambdaQueryWrapper.between(BadManagementPerson::getCreateDate, thirtyDay.get(0),
                thirtyDay.get(1));
        List<BadManagementPerson> list = iBadManagementPersonService.list(badManagementPersonLambdaQueryWrapper);
        List<PersonVo> personVoList = new ArrayList<>();
        if (StringUtil.isNotEmpty(list)) {
            Set<Long> userIds = list.stream().map(m -> m.getPersonId()).collect(Collectors.toSet());
            List<Person> user = iPersonService.list(new LambdaQueryWrapper<Person>().in(Person::getId, userIds));
            for (Person person : user) {
                PersonVo personVo = new PersonVo();
                BeanUtils.copyProperties(person, personVo);
                Long personId = personVo.getId();
                PersonAscription personAscription = iPersonAscriptionService
                        .getOne(new LambdaQueryWrapper<PersonAscription>().eq(PersonAscription::getPersonId, personId));
                if (personAscription != null) {
                    Company company = iCompanyService.getById(personAscription.getCompanyId());
                    if (company != null) {
                        personVo.setCompanyName(company.getName());
                    }
                }
                personVo.setHeadPhoto(person.getHeadPhoto());
                personVoList.add(personVo);
            }
        }
        return personVoList;
    }

    /**
     * 个人违章
     *
     * @return
     */
    @RequestMapping(value = "/badPerson", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "个人违章", notes = "个人违章")
    public Object badPerson(Long id) throws ParseException {
        PersonMessage personMessage = iPersonMessageService.getById(id);
        Long badPersonId = personMessage.getObjectId();

        PersonMessageOneVo personMessageOneVo = new PersonMessageOneVo();
        List<BadManagementPerson> list = iBadManagementPersonService
                .list(new LambdaQueryWrapper<BadManagementPerson>().eq(BadManagementPerson::getPersonId, badPersonId)
                        .orderByDesc(BadManagementPerson::getCreateDate));
        List<SingTaskBadManagementVo> singTaskBadManagementVos = new ArrayList<>();
        if (StringUtil.isNotEmpty(list)) {
            for (BadManagementPerson badManagementPerson : list) {
                Long taskId = badManagementPerson.getTaskId();
                SingTaskBadManagementVo singTaskBadManagementVo = (SingTaskBadManagementVo) iTaskService
                        .getBadManagement(taskId, null,null);
                singTaskBadManagementVos.add(singTaskBadManagementVo);
            }
        }
        //按照创建时间进行倒序
        List<SingTaskBadManagementVo> collect = singTaskBadManagementVos.stream().sorted(Comparator.comparing(SingTaskBadManagementVo::getCreateTime).reversed()).collect(Collectors.toList());

        personMessageOneVo.setAlarmTime(personMessage.getCreateDate());
        personMessageOneVo.setSingTaskBadManagementVoList(collect);
        Person person = iPersonService.getById(badPersonId);
        if (person != null) {
            String name = person.getName();
            personMessageOneVo.setName(name);
        }
        personMessageOneVo.setNum(list.size());
        PersonAscription personAscription = iPersonAscriptionService
                .getOne(new LambdaQueryWrapper<PersonAscription>().eq(PersonAscription::getPersonId, badPersonId));
        Company company = iCompanyService.getById(personAscription.getCompanyId());
        personMessageOneVo.setCompanyName(company != null ? company.getName() : null);
        return personMessageOneVo;
    }

    private List<String> getDay(int i) throws ParseException {
        Calendar calendar = new GregorianCalendar();
        LinkedList<String> day = new LinkedList<>();
        Date e = new Date();
        calendar.setTime(e);
        calendar.add(Calendar.DAY_OF_MONTH, i);
        Date s = calendar.getTime();
        String start = DateUtils.dateFormat(s, "yyyy-MM-dd 00:00:00");
        String end = DateUtils.dateFormat(e, "yyyy-MM-dd 23:59:59");
        day.add(start);
        day.add(end);
        return day;
    }

    @ApiOperation(value = "消息下拉枚举",notes = "消息下拉枚举")
    @GetMapping("/option/list")
    public List optionList(){
        return MessageTypeEnum.appOptionList();
    }

    @ApiOperation(value = "消息分页查询",notes = "消息分页查询")
    @GetMapping("/page/list")
    public Page messagePageList(@RequestParam Integer pageNumber,
                                @RequestParam Integer pageSize,
                                @RequestParam(required = false) Integer type){
        Long personId = getUserInfo().getSequenceNbr();
        return iPersonMessageService.messagePageList(pageNumber,pageSize,personId,type);
    }

}
