package cn.com.ty.lift.quan.news.service.impl;

import cn.com.ty.lift.quan.news.dao.entity.MapInfo;
import cn.com.ty.lift.quan.news.dao.entity.QuanNews;
import cn.com.ty.lift.quan.news.dao.entity.model.QuanNewsReq;
import cn.com.ty.lift.quan.news.dao.mapper.QuanNewsMapper;
import cn.com.ty.lift.quan.news.service.QuanNewsService;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 电梯圈新闻公告 服务实现类
 * </p>
 *
 * @author wang-hai-cheng
 * @since 2019-12-02
 */
@Service
@AllArgsConstructor
public class QuanNewsServiceImpl extends ServiceImpl<QuanNewsMapper, QuanNews> implements QuanNewsService {

    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 查询置顶新闻+普通新闻列表
     *
     * @since 2019/12/3 10:30
     */
    public RestResponse appNews(QuanNewsReq request) {
        Page<QuanNews> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<QuanNews> news = this.page(page, Wrappers.<QuanNews>query()
                .like(null != request.getTitle() && !request.getTitle().isEmpty(), "title", request.getTitle())
                .eq("is_top", false)
                .orderByDesc("release_date"));
        //全部新闻的浏览量列表
        Map<Object, Object> lookTimes = redisTemplate.boundHashOps("system-quanNews-look-time").entries();
        //全部新闻的点赞用户列表
        Map<Object, Object> likeUsers = redisTemplate.opsForHash().entries("system-quanNews-like-users");
        HashMap<String, Object> result = new HashMap<>();
        newsAddLookAndLike(news.getRecords(), lookTimes, likeUsers);
        result.put("news", news);
        if (request.getHaveTops() == 1) {
            List<QuanNews> topNews = this.list(Wrappers.<QuanNews>query()
                    .eq("is_top", true)
                    .orderByAsc("top_serial"));
            //把点赞的用户数量和浏览量整入新闻字段中
            newsAddLookAndLike(topNews, lookTimes, likeUsers);
            result.put("topNews", topNews);
        }
        return RestResponse.success(result);
    }

    public RestResponse news(QuanNewsReq request) {
        Page<QuanNews> page = new Page<>(request.getPageNum(), request.getPageSize());
        IPage<QuanNews> news = this.page(page, Wrappers.<QuanNews>query()
                .orderByDesc("is_top")
                .orderByAsc("top_serial")
                .orderByDesc("release_date"));
        //全部新闻的浏览量列表
        Map<Object, Object> lookTimes = redisTemplate.boundHashOps("system-quanNews-look-time").entries();
        //全部新闻的点赞用户列表
        Map<Object, Object> likeUsers = redisTemplate.opsForHash().entries("system-quanNews-like-users");
        newsAddLookAndLike(news.getRecords(), lookTimes, likeUsers);
        return RestResponse.success(news);
    }

    //把点赞的用户数量和浏览量整入新闻字段中
    void newsAddLookAndLike(List<QuanNews> records, Map<Object, Object> lookTimes, Map<Object, Object> likeUsers) {
        for (QuanNews quanNews : records) {
            Long id = quanNews.getId();
            //如果没有浏览量
            if (lookTimes.isEmpty()) {
                quanNews.setLookNum(0L);
            } else {
                //遍历lookTimes，查看对应id的新闻浏览量
                for (Map.Entry<Object, Object> entry : lookTimes.entrySet()) {
                    Object key = entry.getKey();
                    Long value = Long.valueOf((Integer) entry.getValue());
                    if (key.equals(id.toString())) {
                        quanNews.setLookNum(value);
                        break;
                    }
                    quanNews.setLookNum(0L);
                }
            }
            //如果没有用户喜爱
            if (likeUsers.isEmpty()) {
                quanNews.setLikeNum(0L);
            } else {
                //遍历likeUsers，查看对应id的新闻的点赞量
                for (Map.Entry<Object, Object> entry : likeUsers.entrySet()) {
                    String k = entry.getKey().toString();
                    ArrayList v = (ArrayList) entry.getValue();
                    if (k.equals(id.toString())) {
                        quanNews.setLikeNum((long) v.size());
                        break;
                    }
                    quanNews.setLikeNum(0L);
                }
            }
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    public RestResponse like(QuanNewsReq request) {
        String userId = request.getUserId().toString();
        String id = request.getId().toString();
        ArrayList users = (ArrayList) redisTemplate.opsForHash().get("system-quanNews-like-users", id);
        if (null == users) {
            users = new ArrayList<>();
        } else {
            //遍历userId列表
            for (Object user : users) {
                if (user.equals(userId)) {
                    //如果列表内有这个uid就删除喜欢,并return
                    users.remove(user);
                    redisTemplate.opsForHash().put("system-quanNews-like-users", id, users);
                    return RestResponse.success(null, "取消点赞成功");
                }
            }
        }
        //如果没有列表或列表内没有这个uid就标记喜欢
        users.add(userId);
        redisTemplate.opsForHash().put("system-quanNews-like-users", id, users);
        return RestResponse.success(null, "点赞成功");
    }

    //获取一条新闻
    @SuppressWarnings("rawtypes")
    public RestResponse getNews(QuanNewsReq quanNewsReq) {
        QuanNews byId = this.getById(quanNewsReq);
        if (null == byId) {
            return RestResponse.success();
        }
        String id = byId.getId().toString();
        Long lookNum = redisTemplate
                .boundHashOps("system-quanNews-look-time").increment(id, 1);
        ArrayList users = (ArrayList) redisTemplate
                .opsForHash().get("system-quanNews-like-users", id);
        Long userId = quanNewsReq.getUserId();
        boolean isLike = false;
        if (null != userId) {
            isLike = users != null && users.contains(userId.toString());
        }
        byId.setLookNum(lookNum);
        byId.setLikeNum(users != null ? users.size() : 0L);
        byId.setIsLike(isLike);
        return RestResponse.success(byId, "成功");
    }

    public RestResponse areas() {
        List<String> areas = this.getBaseMapper().areas();
        if (areas.isEmpty()) {
            return RestResponse.success();
        }
        return RestResponse.success(areas);
    }

    //传入经纬度，返回城市名称，基于百度地图，文档http://lbsyun.baidu.com/index.php?title=uri/api/web#service-page-anchor2
    public RestResponse location(String point) throws IOException {
        ObjectMapper jackson = new ObjectMapper();
        jackson.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        String body = new RestTemplate()
                .getForEntity("http://api.map.baidu.com/geocoder?location=" + point + "&output=json", String.class)
                .getBody();
        MapInfo mapInfo = jackson.readValue(body, MapInfo.class);
        if (mapInfo.getCity() != null) {
            return RestResponse.success(mapInfo.getCity().replace("市", ""));
        }
        return RestResponse.fail();
    }
}