package com.yihu.jw.message.service;

import com.yihu.jw.entity.base.message.BaseMessageDO;
import com.yihu.jw.message.dao.MessageDao;
import com.yihu.jw.util.date.DateUtil;
import com.yihu.mysql.query.BaseJpaService;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author liuwenbin on 2018/11/28.
 */
@Service
public class MessageService extends BaseJpaService<BaseMessageDO, MessageDao> {

    @Autowired
    private MessageDao messageDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;


    /**
     * 消息列表
     * @param platform
     * @param code
     * @param page
     * @param pageSize
     * @return
     */
    public List<Map<String,Object>> messageList(Integer platform,String code,Integer page,Integer pageSize){

        if(page==null){
            page = 0;
        }else if(page > 0)
        {
            page = page -1;
        }

        if (pageSize <= 0) {
            pageSize = 10;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        // 分页信息
        List<BaseMessageDO> applyList = messageDao.messageList(platform,code,"00%");
        Integer applyReadCount = messageDao.countMessage(platform,code,"00%");
        List<BaseMessageDO> systemList = messageDao.messageList(platform,code,"01%");
        Integer systemReadCount = messageDao.countMessage(platform,code,"01%");

        List<Map<String,Object>> resultList = new LinkedList<>();
        Map<String,Object> applyMap = new HashedMap();
        applyMap.put("name","应用消息");
        applyMap.put("count",applyReadCount);
        applyMap.put("message",applyList.size()>0?applyList.get(0).getMsgContent():null);
        applyMap.put("createTime", applyList.size()>0?DateUtil.dateToStr(applyList.get(0).getCreateTime(),"yyyy-MM-dd HH:mm:ss"):null);
        applyMap.put("type","01");
        resultList.add(applyMap);

        Map<String,Object> systemMap = new HashedMap();
        systemMap.put("name","系统消息");
        systemMap.put("count",systemReadCount);
        systemMap.put("message",systemList.size()>0?systemList.get(0).getMsgContent():null);
        systemMap.put("createTime", systemList.size()>0?DateUtil.dateToStr(systemList.get(0).getCreateTime(),"yyyy-MM-dd HH:mm:ss"):null);
        applyMap.put("type","02");
        resultList.add(systemMap);
        Integer unReadPageSize = pageSize;
        if(page==0){
            unReadPageSize=unReadPageSize-2;
        }

        //1、未读消息(置顶)
        List<Map<String, Object>> unReadResult = messageListSql(platform,code,0,page,unReadPageSize);
        for(Map<String, Object> one:unReadResult){
            Map<String,Object> unReadMap = new HashedMap();
            unReadMap.put("patientCode",one.get("sender"));
            unReadMap.put("name",one.get("sender_name"));
            unReadMap.put("count",one.get("num"));
            unReadMap.put("message",one.get("msg_content"));//create_time
            unReadMap.put("createTime", DateUtil.dateToStr((Date)one.get("create_time"),"yyyy-MM-dd HH:mm:ss"));
            unReadMap.put("senderPhoto", one.get("sender_photo"));
            unReadMap.put("senderSex", one.get("sex"));
            applyMap.put("type","03");
            resultList.add(unReadMap);
        }
        if(unReadResult.size()<unReadPageSize){
            page = messageCountSql(platform,code,1,page,pageSize);
            //2、已读消息
            List<Map<String, Object>> readResult = messageListSql(platform,code,1,page,unReadPageSize);
            for(Map<String, Object> one:readResult){
                Map<String,Object> readMap = new HashedMap();
                readMap.put("patientCode",one.get("sender"));
                readMap.put("name",one.get("sender_name"));
                readMap.put("count",one.get("num"));
                readMap.put("message",one.get("msg_content"));
                readMap.put("createTime", DateUtil.dateToStr((Date)one.get("create_time"),"yyyy-MM-dd HH:mm:ss"));
                readMap.put("senderPhoto", one.get("sender_photo"));
                readMap.put("senderSex", one.get("sex"));
                applyMap.put("type","03");
                resultList.add(readMap);
            }
        }

        return resultList;
    }


    public BaseMessageDO create(BaseMessageDO messageDO){

        return messageDao.save(messageDO);
    }


    public List<Map<String, Object>> applyMessageList(String patient, String msgTypeCode){
        String sql = "select m.* from base_message m join patient_apply_for_log l on m.relation_data=l.id where  m.read_state=0 and m.msg_type_code='"+msgTypeCode+"' and m.receiver='"+patient+"'";
        return jdbcTemplate.queryForList(sql);
//        return messageDao.applyMessageList(patient,failureTime,msgTypeCode);
    }




    private List<Map<String, Object>> messageListSql(Integer platform,String code,Integer readState,Integer page,Integer pageSize){
        String sql =" SELECT " +
                " a.*, b.msg_content ,b.sender_photo ,p.sex " +
                " FROM " +
                " ( " +
                "  SELECT " +
                "   m.sender, " +
                "   m.sender_name, " +
                "   count(*) as num, " +
                "   max(m.create_time) AS create_time " +
                "  FROM " +
                "   base_message m " +
                "  WHERE " +
                "   m.platform = '"+platform+"' " +
                "  AND m.receiver = '"+code+"' " +
                "  AND m.del = 1 " +
                "  AND m.read_state = "+readState+" " +
                "  AND m.msg_type_code like '03%'"+
                "  GROUP BY " +
                "   m.sender, " +
                "   m.sender_name " +
                "  LIMIT "+page+", " +
                "  "+pageSize+" " +
                " ) a " +
                " LEFT JOIN base_message b ON a.sender = b.sender " +
                " AND a.create_time = b.create_time " +
                " AND b.platform = '"+platform+"' " +
                " AND b.receiver = '"+code+"' " +
                " AND b.del = 1 " +
                " AND b.read_state = "+readState+
                " AND b.msg_type_code like '03%'"+
                " LEFT JOIN base_patient p ON a.sender = p.id ";
        return jdbcTemplate.queryForList(sql);
    }

    private Integer messageCountSql(Integer platform,String code,Integer readState,Integer page,Integer originalPageSize){
        String sql ="  SELECT count(*) as num " +
                "  FROM " +
                "   base_message m " +
                "  WHERE " +
                "   m.platform = '"+platform+"' " +
                "  AND m.receiver = '"+code+"' " +
                "  AND m.del = 1 " +
                "  AND m.read_state = "+readState+" " +
                "  AND m.msg_type_code like '03%'"+
                "  GROUP BY " +
                "   m.sender, " +
                "   m.sender_name " ;
        List<Map<String, Object>> list  = jdbcTemplate.queryForList(sql);
        Integer count = list.size();
        if(count<=(originalPageSize-2)){
            return page;
        }else{
            Integer s = (count-(originalPageSize-2))/originalPageSize;
            Integer y = (count-(originalPageSize-2))%originalPageSize;
            if(y>0){
                return page-(s+2);
            }else{
                return page-(s+1);
            }
        }
    }

    public BaseMessageDO findById(Integer id){
        return messageDao.findById(id);
    }

    public void updateStatusById(Integer readState,Integer id) throws Exception{

        int i = messageDao.updateStatusById(readState,id);
        if(i<0){
            throw new Exception("update data failur !");
        }
    }

    public List<BaseMessageDO> getAllByPatient(String receiver,String sender,String msgTypeCode,Integer platform,Pageable pageRequest){

        return messageDao.getAllByPatient(receiver,sender,msgTypeCode,platform,pageRequest);
    }

    public List<BaseMessageDO> getAllByPatient(String receiver,String msgTypeCode,Integer platform,Pageable pageRequest){

        return messageDao.getAllByPatient(receiver,msgTypeCode,platform,pageRequest);
    }

}
