package com.ifish.serviceImpl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.ifish.dao.BrowseRoomDao;
import com.ifish.dao.CameraDao;
import com.ifish.dao.CameraUserDao;
import com.ifish.dao.GoldGetRecordDao;
import com.ifish.dao.LiveBannerDao;
import com.ifish.dao.LiveMessageDao;
import com.ifish.dao.LiveRoomDao;
import com.ifish.dao.LiveRoomZanDao;
import com.ifish.dao.UserAssetDao;
import com.ifish.dao.UserDao;
import com.ifish.dto.JsonResult;
import com.ifish.dto.LiveRoomInfoDto;
import com.ifish.dto.PageingDto;
import com.ifish.entity.BrowseRoom;
import com.ifish.entity.BrowseRoomId;
import com.ifish.entity.CameraUser;
import com.ifish.entity.CameraUserId;
import com.ifish.entity.Grade;
import com.ifish.entity.LiveBanner;
import com.ifish.entity.LiveMessage;
import com.ifish.entity.LiveRoom;
import com.ifish.entity.LiveRoomZan;
import com.ifish.entity.LiveRoomZanId;
import com.ifish.entity.User;
import com.ifish.entity.UserAsset;
import com.ifish.enums.BooleanEnum;
import com.ifish.enums.ResultEnum;
import com.ifish.enums.RoomStatusEnum;
import com.ifish.exception.IfishException;
import com.ifish.hibernate.Pagination;
import com.ifish.netease.NeteaseIM;
import com.ifish.service.AsyncTaskService;
import com.ifish.service.CacheService;
import com.ifish.service.LiveRoomService;
import com.ifish.util.IfishUtil;
import com.ifish.util.ResultUtil;
import com.ifish.validator.LiveRoomParam;
import com.ifish.validator.PageParam;

@Service
@Transactional
public class LiveRoomServiceImpl implements LiveRoomService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private CameraDao cameraDao;
    @Autowired
    private NeteaseIM neteaseIM;
    @Autowired
    private LiveRoomDao liveRoomDao;
    @Autowired
    private UserAssetDao userAssetDao;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private CameraUserDao cameraUserDao;
    @Autowired
    private LiveBannerDao liveBannerDao;
    @Autowired
    private BrowseRoomDao browseRoomDao;
    @Autowired
    private LiveMessageDao liveMessageDao;
    @Autowired
    private LiveRoomZanDao liveRoomZanDao;
    @Autowired
    private GoldGetRecordDao goldGetRecordDao;
    @Autowired
    private AsyncTaskService asyncTaskService;

    @Override
    public JSONObject addLiveRoom(LiveRoomParam liveRoomParam) {
        //用户ID
        Integer userId = liveRoomParam.getUserId();
        User user = userDao.get(userId);
        if (user == null) {
            throw new IfishException(ResultEnum.error402);
        }
        //用户是否绑定摄像头
        String cameraId = liveRoomParam.getCameraId();
        CameraUserId cameraUserId = new CameraUserId(userId, cameraId);
        CameraUser cameraUser = this.cameraUserDao.get(cameraUserId);
        if (cameraUser == null) {
            throw new IfishException(ResultEnum.error402);
        }
        //原来不是开启状态
        if (!BooleanEnum.YES.getKey().equals(cameraUser.getIsLive())) {
            //开启直播
            cameraUser.setIsLive(BooleanEnum.YES.getKey());
        }
        //新增直播间
        LiveRoom liveRoom = new LiveRoom();
        liveRoom.setUserId(userId);
        liveRoom.setRoomName(liveRoomParam.getRoomName());
        liveRoom.setRoomDesc(liveRoomParam.getRoomDesc());
        liveRoom.setRoomStatus(liveRoomParam.getRoomStatus());
        liveRoom.setCreateTime(new Date());
        //首次开启分享则发送云信消息给所有用户
        /*if(!BooleanEnum.YES.getKey().equals(liveRoom.getFirstShare()) && RoomStatusEnum.status1.getKey().equals(liveRoom.getRoomStatus())){
			liveRoom.setFirstShare(BooleanEnum.YES.getKey());
			asyncTaskService.sendMsgToAll(userId);
		}
		else{*/
        liveRoom.setFirstShare(BooleanEnum.NO.getKey());
        //}
        //人气值
        liveRoom.setPopularityValue(0);
        //摄像头ID
        liveRoomDao.save(liveRoom);
        Integer roomId = liveRoom.getRoomId();
        JSONObject json = new JSONObject();
        json.put("cameraId", cameraId);
        json.put("isLive", cameraUser.getIsLive());
        json.put("roomId", roomId);
        return json;
    }

    @Override
    public JsonResult<?> updateLiveRoom(Integer roomId, LiveRoomParam liveRoomParam) {
        //查找直播间信息
        LiveRoom curLiveRoom = this.liveRoomDao.get(roomId);
        if (curLiveRoom == null) {
            throw new IfishException(ResultEnum.error402);
        }
        //用户ID
        Integer userId = liveRoomParam.getUserId();
        //摄像头
        String cameraId = liveRoomParam.getCameraId();
        //用户是否绑定摄像头
        CameraUserId cameraUserId = new CameraUserId(userId, cameraId);
        CameraUser cameraUser = this.cameraUserDao.get(cameraUserId);
        if (cameraUser == null) {
            throw new IfishException(ResultEnum.error402);
        }
        //返回摄像头信息
        List<JSONObject> list = new ArrayList<JSONObject>();
        //原来不是开启状态
        if (!BooleanEnum.YES.getKey().equals(cameraUser.getIsLive())) {
            //开启直播
            cameraUser.setIsLive(BooleanEnum.YES.getKey());
            //关闭其他摄像头直播
            List<CameraUser> cameraUserList = this.cameraUserDao.findByProperty(Restrictions.eq("cameraUserId.userId", userId), Restrictions.ne("cameraUserId.cameraId", cameraId));
            for (CameraUser curCameraUser : cameraUserList) {
                curCameraUser.setIsLive(BooleanEnum.NO.getKey());
                JSONObject json = new JSONObject();
                json.put("cameraId", curCameraUser.getCameraUserId().getCameraId());
                json.put("isLive", curCameraUser.getIsLive());
                list.add(json);
            }
        }
        //返回摄像头直播状态
        JSONObject json = new JSONObject();
        json.put("cameraId", cameraId);
        json.put("isLive", cameraUser.getIsLive());
        list.add(json);
        //更新直播间信息
        curLiveRoom.setRoomName(liveRoomParam.getRoomName());
        curLiveRoom.setRoomDesc(liveRoomParam.getRoomDesc());
        curLiveRoom.setRoomStatus(liveRoomParam.getRoomStatus());
        //首次开启分享则发送云信消息给所有用户
        /*if(!BooleanEnum.YES.getKey().equals(curLiveRoom.getFirstShare()) && RoomStatusEnum.status1.getKey().equals(liveRoomParam.getRoomStatus())){
			curLiveRoom.setFirstShare(BooleanEnum.YES.getKey());
			asyncTaskService.sendMsgToAll(userId);
		}*/
        return ResultUtil.success(list);
    }

    @Override
    public Object popularityValue(Integer roomId, Integer userId) {
        if (roomId != null && userId != null) {
            //浏览直播间记录
            BrowseRoomId browseRoomId = new BrowseRoomId(roomId, userId);
            BrowseRoom browseRoom = this.browseRoomDao.get(browseRoomId);
            Date date = new Date();
            //新增浏览记录
            if (browseRoom != null) {
                browseRoom.setUpdateTime(date);
                this.browseRoomDao.update(browseRoom);
            } else {
                //更新浏览记录
                browseRoom = new BrowseRoom();
                browseRoom.setBrowseRoomId(browseRoomId);
                browseRoom.setUpdateTime(date);
                browseRoom.setCreateTime(date);
                this.browseRoomDao.save(browseRoom);
            }
            //查找直播间信息
            LiveRoom curLiveRoom = this.liveRoomDao.get(roomId);
            if (curLiveRoom != null) {
                Integer popularityValue = curLiveRoom.getPopularityValue();
                //人气值加一
                popularityValue++;
                curLiveRoom.setPopularityValue(popularityValue);
                this.liveRoomDao.update(curLiveRoom);
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("roomId", roomId);
                map.put("popularityValue", popularityValue);
                return IfishUtil.toJson(ResultEnum.success.getKey(), popularityValue);
            }
        }
        return IfishUtil.toJson(ResultEnum.fail101.getKey(), "");
    }

    @Override
    public Object getLiveRoomInfo(Integer userId) {
        if (userId != null) {
            //查找直播间信息
            LiveRoom curLiveRoom = this.liveRoomDao.findUniqueByProperty(Restrictions.eq("userId", userId));
            if (curLiveRoom != null) {
                Map<String, Object> map = new HashMap<String, Object>();
                Integer roomId = curLiveRoom.getRoomId();
                map.put("roomId", roomId);
                map.put("userId", curLiveRoom.getUserId());
                map.put("roomName", curLiveRoom.getRoomName());
                map.put("roomDesc", curLiveRoom.getRoomDesc());
                map.put("popularityValue", curLiveRoom.getPopularityValue());
                map.put("roomStatus", curLiveRoom.getRoomStatus());
                return IfishUtil.toJson(ResultEnum.success.getKey(), map);
            }
        }
        return IfishUtil.toJson(ResultEnum.success.getKey(), "");
    }

    @Override
    public Object getLiveRoomsByPage(Integer firstResult, Integer pageSize, Integer userId, String orders) {
        if (firstResult != null && pageSize != null && userId != null) {
            Map<String, Object> returnMap = new HashMap<String, Object>();
            LinkedHashMap<Integer, LiveRoomInfoDto> map = new LinkedHashMap<Integer, LiveRoomInfoDto>();
            if (firstResult == 0) {
                User user = this.userDao.get(userId);
                if (user != null) {
                    //经度
                    Double longitude = user.getLongitude();
                    //纬度
                    Double latitude = user.getLatitude();
                    //距离用户最近的前5条记录
                    List<LiveRoomInfoDto> distanceList = this.liveRoomDao.findByDistance(longitude, latitude);
                    for (LiveRoomInfoDto liveRoomInfo : distanceList) {
                        Integer roomId = liveRoomInfo.getRoomId();
                        map.put(roomId, liveRoomInfo);
                    }
                    //获取用户最近浏览的5条记录
                    List<LiveRoomInfoDto> browseList = this.liveRoomDao.findByBrowse(userId);
                    for (LiveRoomInfoDto liveRoomInfo : browseList) {
                        Integer roomId = liveRoomInfo.getRoomId();
                        map.put(roomId, liveRoomInfo);
                    }
                    //获取人气值最高的5条记录
                    List<LiveRoomInfoDto> popularityList = this.liveRoomDao.findByPopularityValue();
                    for (LiveRoomInfoDto liveRoomInfo : popularityList) {
                        Integer roomId = liveRoomInfo.getRoomId();
                        map.put(roomId, liveRoomInfo);
                    }
                    //去重条件
                    orders = StringUtils.join(map.keySet().toArray(), ",");
                    //根据开播时间倒序排列
                    Pagination<LiveRoomInfoDto> page = this.liveRoomDao.findByTime(firstResult, pageSize, orders);
                    List<LiveRoomInfoDto> timeList = page.getList();
                    for (LiveRoomInfoDto liveRoomInfo : timeList) {
                        Integer roomId = liveRoomInfo.getRoomId();
                        map.put(roomId, liveRoomInfo);
                    }
                    List<LiveRoomInfoDto> list = new ArrayList<LiveRoomInfoDto>();
                    Long curTime = new Date().getTime();
                    //计算活跃值
                    for (LiveRoomInfoDto liveRoomInfo : map.values()) {
                        Long loginTime = liveRoomInfo.getLoginTime().getTime();
                        //最近登录天数
                        Integer days = (int) ((curTime - loginTime) / (1000 * 60 * 60 * 24));
                        //小于一周
                        if (days <= 7) {
                            liveRoomInfo.setLiveness("优");
                        } //一周至半个月
                        else if (days > 7 && days <= 15) {
                            liveRoomInfo.setLiveness("良");
                        } //半个月至一个月
                        else if (days > 15 && days <= 30) {
                            liveRoomInfo.setLiveness("中");
                        } else {
                            liveRoomInfo.setLiveness("差");
                        }
                        list.add(liveRoomInfo);
                    }
                    returnMap.put("orders", orders);
                    returnMap.put("total", page.getTotalCount());
                    returnMap.put("liveRoomInfo", list);
                    return IfishUtil.toJson(ResultEnum.success.getKey(), returnMap);
                }
            } else {
                //根据开播时间倒序排列
                Pagination<LiveRoomInfoDto> page = this.liveRoomDao.findByTime(firstResult, pageSize, orders);
                List<LiveRoomInfoDto> timeList = page.getList();
                Long curTime = new Date().getTime();
                //计算活跃值
                for (LiveRoomInfoDto liveRoomInfo : timeList) {
                    Long loginTime = liveRoomInfo.getLoginTime().getTime();
                    //最近登录天数
                    Integer days = (int) ((curTime - loginTime) / (1000 * 60 * 60 * 24));
                    //小于一周
                    if (days <= 7) {
                        liveRoomInfo.setLiveness("优");
                    } //一周至半个月
                    else if (days > 7 && days <= 15) {
                        liveRoomInfo.setLiveness("良");
                    } //半个月至一个月
                    else if (days > 15 && days <= 30) {
                        liveRoomInfo.setLiveness("中");
                    } else {
                        liveRoomInfo.setLiveness("差");
                    }
                }
                returnMap.put("orders", orders);
                returnMap.put("total", page.getTotalCount());
                returnMap.put("liveRoomInfo", timeList);
                return IfishUtil.toJson(ResultEnum.success.getKey(), returnMap);
            }
        }
        return IfishUtil.toJson(ResultEnum.fail101.getKey(), "");
    }

    @Override
    public List<LiveBanner> getLiveBanners() {
        //app展示的banner图
        List<LiveBanner> list = this.liveBannerDao.findByProperty(Order.desc("bannerId"), Restrictions.eq("appShow", BooleanEnum.YES.getKey()));
        return list;
    }

    @Override
    public Object leaveMessage(LiveMessage liveMessage) {
        Integer roomId = liveMessage.getRoomId();
        Integer userId = liveMessage.getUserId();
        String messageContent = liveMessage.getMessageContent();
        if (roomId != null && userId != null && messageContent != null && messageContent.length() > 0) {
            LiveRoom liveRoom = this.liveRoomDao.get(roomId);
            User user = this.userDao.get(userId);
            if (liveRoom != null && user != null) {
                liveMessage.setCreateTime(new Date());
                this.liveMessageDao.save(liveMessage);
                liveMessage.setUserName(user.getNickName());
                liveMessage.setUserImg(user.getUserImg());
                Integer asUserId = liveMessage.getAsUserId();
                if (asUserId != null) {
                    User asUser = this.userDao.get(asUserId);
                    if (asUser != null) {
                        liveMessage.setAsUserName(asUser.getNickName());
                        if (!asUserId.equals(userId)) {
                            //发送云信消息给所@的用户
                            neteaseIM.sendMsg(userId.toString(), asUserId.toString(), "来自爱鱼看看的回复:" + messageContent, "");
                        }
                    } else {
                        Integer roomUserId = liveRoom.getUserId();
                        if (!roomUserId.equals(userId)) {
                            //发送云信消息给房主
                            neteaseIM.sendMsg(userId.toString(), roomUserId.toString(), "来自爱鱼看看的留言:" + messageContent, "");
                        }
                    }
                }
                return IfishUtil.toJson(ResultEnum.success.getKey(), liveMessage);
            }
        }
        return IfishUtil.toJson(ResultEnum.fail101.getKey(), "");
    }

    @Override
    public Object getLiveMessageByPage(Integer firstResult, Integer pageSize, Integer roomId) {
        if (firstResult == null) {
            firstResult = 0;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        //根据直播间ID分页获取留言信息
        Pagination<LiveMessage> page = this.liveMessageDao.findByCriteria(firstResult, pageSize, Order.desc("messageId"), Restrictions.eq("roomId", roomId));
        List<LiveMessage> list = page.getList();
        for (LiveMessage liveMessage : list) {
            User user = this.userDao.get(liveMessage.getUserId());
            if (user != null) {
                liveMessage.setUserName(user.getNickName());
                liveMessage.setUserImg(user.getUserImg());
            }
            if (liveMessage.getAsUserId() != null) {
                User tmpUser = this.userDao.get(liveMessage.getAsUserId());
                if (tmpUser != null) {
                    liveMessage.setAsUserName(tmpUser.getNickName());
                } else {
                    liveMessage.setAsUserName("");
                }
            } else {
                liveMessage.setAsUserName("");
            }
        }
        firstResult += list.size();
        //分页数据封装
        PageingDto<LiveMessage> pageingData = new PageingDto<LiveMessage>(ResultEnum.success.getKey(), firstResult, page.getTotalCount(), list);
        return pageingData;
    }

    /**
     * 按时间倒序分页获取直播间信息
     */
    @Override
    public PageingDto<?> getLiveRoomsByTime(PageParam pageParam) {
        Integer firstResult = pageParam.getFirstResult();
        //按时间倒序
        Pagination<LiveRoomInfoDto> page = this.liveRoomDao.findByTime(firstResult, pageParam.getPageSize(), null);
        List<LiveRoomInfoDto> list = page.getList();
        firstResult += list.size();
        //分页数据封装
        return new PageingDto<LiveRoomInfoDto>(ResultEnum.success.getKey(), firstResult, page.getTotalCount(), getLiveRoomInfoDto(pageParam.getUserId(), list));
    }

    /**
     * 按人气值倒序分页获取直播间信息
     */
    @Override
    public PageingDto<?> getLiveRoomsByPopularityValue(PageParam pageParam) {
        Integer firstResult = pageParam.getFirstResult();
        //按时间倒序
        Pagination<LiveRoomInfoDto> page = this.liveRoomDao.findByPopularityValue(firstResult, pageParam.getPageSize());
        List<LiveRoomInfoDto> list = page.getList();
        firstResult += list.size();
        //分页数据封装
        return new PageingDto<LiveRoomInfoDto>(ResultEnum.success.getKey(), firstResult, page.getTotalCount(), getLiveRoomInfoDto(pageParam.getUserId(), list));
    }

    @Override
    public PageingDto<?> getLiveRoomsByTuijian(PageParam pageParam) {
        Integer firstResult = pageParam.getFirstResult();
        //按时间倒序
        Pagination<LiveRoomInfoDto> page = this.liveRoomDao.getLiveRoomsByTuijian(firstResult, pageParam.getPageSize());
        List<LiveRoomInfoDto> list = page.getList();
        firstResult += list.size();
        //分页数据封装
        return new PageingDto<LiveRoomInfoDto>(ResultEnum.success.getKey(), firstResult, page.getTotalCount(), getLiveRoomInfoDto(pageParam.getUserId(), list));
    }

    /**
     * 封装数据
     *
     * @param userId
     * @param list
     * @return
     */
    public List<LiveRoomInfoDto> getLiveRoomInfoDto(Integer userId, List<LiveRoomInfoDto> list) {
        Long curTime = new Date().getTime();
        for (LiveRoomInfoDto liveRoomInfo : list) {
            Integer roomId = liveRoomInfo.getRoomId();
            Integer roomUserId = liveRoomInfo.getUserId();
            //是否点赞
            LiveRoomZanId id = new LiveRoomZanId(roomId, userId);
            LiveRoomZan zan = liveRoomZanDao.get(id);
            if (zan == null) {
                liveRoomInfo.setIsZan(BooleanEnum.NO.getKey());
            } else {
                liveRoomInfo.setIsZan(BooleanEnum.YES.getKey());
            }
            //点赞数量
            liveRoomInfo.setZanNum(liveRoomZanDao.getZanNum(roomId));
            //评论数
            liveRoomInfo.setPinglunNum(liveMessageDao.getLiveMessageCount(roomId));
            //打赏金币数量
            BigDecimal goldValue = goldGetRecordDao.getQuestionPayTourGoldValue(roomUserId);
            if (goldValue != null) {
                liveRoomInfo.setTotalGoldValue(goldValue);
            } else {
                liveRoomInfo.setTotalGoldValue(new BigDecimal(0));
            }
            //等级
            UserAsset userAsset = userAssetDao.get(roomUserId);
            liveRoomInfo.setGradeNum(0);
            if (userAsset != null) {
                //经验值
                Integer gradeValue = userAsset.getGradeValue();
                //等级
                for (Grade grade : cacheService.getGradeList()) {
                    if (gradeValue >= grade.getMinValue() && gradeValue < grade.getMaxValue()) {
                        liveRoomInfo.setGradeNum(grade.getGradeNum());
                        break;
                    }
                }
            }
            //最近登录天数
            Long loginTime = liveRoomInfo.getLoginTime().getTime();
            Integer days = (int) ((curTime - loginTime) / (1000 * 60 * 60 * 24));
            //小于一周
            if (days <= 7) {
                liveRoomInfo.setLiveness("优");
            } //一周至半个月
            else if (days > 7 && days <= 15) {
                liveRoomInfo.setLiveness("良");
            } //半个月至一个月
            else if (days > 15 && days <= 30) {
                liveRoomInfo.setLiveness("中");
            } else {
                liveRoomInfo.setLiveness("差");
            }
        }
        return list;
    }

    /**
     * 点赞/取消点赞
     */
    @Override
    public JsonResult<?> liveRoomsZan(Integer roomId, Integer userId) {
        //点赞数量
        Integer zanNum = liveRoomZanDao.getZanNum(roomId);
        //是否点过赞
        LiveRoomZanId id = new LiveRoomZanId(roomId, userId);
        LiveRoomZan zan = liveRoomZanDao.get(id);
        JSONObject json = new JSONObject();
        if (zan == null) {
            LiveRoom liveRoom = liveRoomDao.get(roomId);
            if (liveRoom == null) {
                throw new IfishException(ResultEnum.error402);
            }
            User user = userDao.get(userId);
            if (user == null) {
                throw new IfishException(ResultEnum.error402);
            }
            //点赞
            zan = new LiveRoomZan(id);
            liveRoomZanDao.save(zan);
            json.put("isZan", BooleanEnum.YES.getKey());
            zanNum++;
        } else {
            //取消点赞
            liveRoomZanDao.delete(zan);
            json.put("isZan", BooleanEnum.NO.getKey());
            zanNum--;
        }
        json.put("zanNum", zanNum);
        return ResultUtil.success(json);
    }

}
