package com.tourism.webadmin.app.website.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.tourism.common.additional.config.ApplicationConfig;
import com.tourism.common.additional.utils.UrlConvertUtils;
import com.tourism.common.core.annotation.DisableDataFilter;
import com.tourism.common.core.object.MyPageData;
import com.tourism.common.core.object.ResponseResult;
import com.tourism.common.core.object.TokenData;
import com.tourism.common.core.util.MyCommonUtil;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.core.util.MyPageUtil;
import com.tourism.common.log.annotation.OperationLog;
import com.tourism.common.log.model.constant.SysOperationLogType;
import com.tourism.webadmin.app.website.dto.TourismTravelNotesWriteDto;
import com.tourism.webadmin.app.website.dto.TravelNotesByStateDto;
import com.tourism.webadmin.app.website.dto.TravelToTopDto;
import com.tourism.webadmin.app.website.vo.*;
import com.tourism.webadmin.app.website.dto.TourTravelNotesTopicListByNameDto;
import com.tourism.webadmin.back.dao.TourUserLikeTopicMapper;
import com.tourism.webadmin.back.dao.TourismProjectTravelNotesWriteMapper;
import com.tourism.webadmin.back.model.*;
import com.tourism.webadmin.back.service.*;
import com.tourism.webadmin.back.vo.TourUserVo;
import com.tourism.webadmin.back.vo.TourismProjectTravelNotesWriteVo;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

/**
 * @author 陈
 * @date 2024年1月24日 9:00:00
 */
@Tag(name = "游记话题")
@Slf4j
@RestController
@RequestMapping("/website/tourism/travelNotesTopic")
@DisableDataFilter
public class TourWebTravelNotesTopicController {


    @Autowired
    private TourUserLikeTopicService tourUserLikeTopicService;
    @Autowired
    private TourUserLikeTopicMapper tourUserLikeTopicMapper;
    @Autowired
    private TourTravelNotesTopicService tourTravelNotesTopicService;
    @Autowired
    private TourUserService tourUserService;
    @Autowired
    private TourWebFansController tourWebFansController;
    @Autowired
    private TourismProjectTravelNotesWriteService tourismProjectTravelNotesWriteService;
    @Autowired
    private TourUserLikeTravelNotesService tourUserLikeTravelNotesService;
    @Autowired
    private TourFansService tourFansService;
    @Autowired
    private TourismProjectTravelNotesWriteMapper tourismProjectTravelNotesWriteMapper;
    @Autowired
    private ApplicationConfig applicationConfig;
    @Autowired
    private TourTourismProjectSearchRecordsService tourTourismSearchRecordsService;


    /**
     * 分页条件查询游记话题，默认根据最热进行排序
     * @param tourTravelNotesTopicListByNameDto
     * @return
     */
    @GetMapping("/list")
    public ResponseResult<TourTravelNotesTopicSearchVo> listPage(@Validated TourTravelNotesTopicListByNameDto tourTravelNotesTopicListByNameDto) {

        TourTravelNotesTopicSearchVo tourTravelNotesTopicSearchVo = new TourTravelNotesTopicSearchVo();

        //根据话题名称查询本人是否收藏
        TourUserLikeTopic tourUserLikeTopic = new TourUserLikeTopic();
        tourUserLikeTopic.setTourTravelNotesTopicName(tourTravelNotesTopicListByNameDto.getTopicName());
        tourUserLikeTopic.setTourUserId(TokenData.takeFromRequest().getUserId());
        List<TourTravelNotesTopic> tourUserLikeTopicList = tourTravelNotesTopicService.lambdaQuery().eq(TourTravelNotesTopic::getName, tourTravelNotesTopicListByNameDto.getTopicName()).list();
        if(CollectionUtils.isEmpty(tourUserLikeTopicList)){
            return ResponseResult.success(null);
        }
        //根据名称查询专题
        tourTravelNotesTopicSearchVo = BeanUtil.toBean(tourUserLikeTopicList.get(0), TourTravelNotesTopicSearchVo.class);
        if(tourUserLikeTopicService.existByFilter(tourUserLikeTopic)){
            tourTravelNotesTopicSearchVo.setIsCollect(1);
        }else {
            tourTravelNotesTopicSearchVo.setIsCollect(0);
        }
        //根据话题名称查询浏览量
        Integer viewCountTopicByName = tourTravelNotesTopicService.getViewCountTopicByName(tourTravelNotesTopicListByNameDto.getTopicName(),tourTravelNotesTopicListByNameDto.getTitleName());
        tourTravelNotesTopicSearchVo.setViewCount(viewCountTopicByName);
        //根据话题名称查询讨论量
        Integer commentCountTopicByName = tourTravelNotesTopicService.getCommentCountTopicByName(tourTravelNotesTopicListByNameDto.getTopicName(),tourTravelNotesTopicListByNameDto.getTitleName());
        tourTravelNotesTopicSearchVo.setCommentCount(commentCountTopicByName);
        //根据话题名称查询帖子数量
        Integer countTravelNotesByName = tourTravelNotesTopicService.getCountTravelNotesByName(tourTravelNotesTopicListByNameDto.getTopicName(),tourTravelNotesTopicListByNameDto.getTitleName());
        tourTravelNotesTopicSearchVo.setTravelNotesCount(countTravelNotesByName);
        //根据话题名称查询游记列表

        PageMethod.startPage(tourTravelNotesTopicListByNameDto.getPageNum(), tourTravelNotesTopicListByNameDto.getPageSize(), true);
        List<TourismProjectTravelNotesWrite> travelNotesByTopicName =
                tourTravelNotesTopicService.getTravelNotesByTopicName(tourTravelNotesTopicListByNameDto.getTopicName(),tourTravelNotesTopicListByNameDto.getOrderBy());

        if(CollectionUtils.isNotEmpty(travelNotesByTopicName)) {
            List<TourTravelNotesTopicNotesSearchVo> tourTravelNotesTopicNotesSearchVoList =
                    MyModelUtil.copyCollectionTo(travelNotesByTopicName, TourTravelNotesTopicNotesSearchVo.class);

            //赋值每个游记的创作者昵称和创作者头像
            List<String> userIdList =
                    tourTravelNotesTopicNotesSearchVoList.stream().map(TourTravelNotesTopicNotesSearchVo::getCreateUserId).collect(Collectors.toList());

            List<TourUser> tourUserList = tourUserService.getInList("userId", new HashSet<>(userIdList));

            List<TourUserVo> tourUserVoList = MyModelUtil.copyCollectionTo(tourUserList, TourUserVo.class);
            // 按照 userId 分组
            Map<String, List<TourUserVo>> userIdGroupedMap = tourUserVoList.stream().collect(Collectors.groupingBy(TourUserVo::getUserId));

            tourTravelNotesTopicNotesSearchVoList.stream().forEach(item->{
                List<TourUserVo> tourUsers = userIdGroupedMap.get(item.getCreateUserId());
                item.setCreatedShowName(tourUsers.get(0).getShowName());
                item.setCreatedHeadImageUrl(tourUsers.get(0).getHeadImageUrl());
            });
            tourTravelNotesTopicSearchVo.setTourTravelNotesTopicNotesSearchVoList(tourTravelNotesTopicNotesSearchVoList);
        }
        //
        return ResponseResult.success(tourTravelNotesTopicSearchVo);
    }

    /**
     *  查询登录用户收藏的游记话题
     */
    @GetMapping("/getSpecialCollection")
    public ResponseResult<List<SpecialCollectionVo>> getSpecialCollection(){
        Long userId = TokenData.takeFromRequest().getUserId();
        List<SpecialCollectionVo> list=tourUserLikeTopicMapper.getSpecialCollection(userId);
        if(list.isEmpty()) return ResponseResult.success(new ArrayList<>());
        //话题Ids
        Set<String> collect = list.stream().map(intem->intem.getId().toString()).collect(Collectors.toSet());
        ArrayList<Long> longs = new ArrayList<>();
        for (String s : collect) {
            longs.add(Long.valueOf(s));
        }
        Map<Long, Integer> viewCountListTopicByName = tourTravelNotesTopicService.getViewCountListTopicByName(longs);
        //放入浏览量的数值
        if(!ObjectUtil.isEmpty(viewCountListTopicByName)){
            list.stream().forEach(item->{
                item.setViewCount(viewCountListTopicByName.get(Long.valueOf(item.getId())));
            });
        }else {
            list.stream().forEach(item->{
                item.setViewCount(0);
            });
        }
        return ResponseResult.success(list);
    }

    /**
     * 收藏专题
     * */
    @PostMapping("/Collection")
    public ResponseResult<Void> Collection(@RequestBody Map<String,Object> map){
        Long id = Long.valueOf(map.get("id").toString());
        TourTravelNotesTopic byId = tourTravelNotesTopicService.getById(id);
        if(byId==null){
            return ResponseResult.error("500","专题不存在");
        }
        Long userId = TokenData.takeFromRequest().getUserId();
        TourUserLikeTopic tourUserLikeTopic = new TourUserLikeTopic();
        tourUserLikeTopic.setTourUserId(userId);
        tourUserLikeTopic.setTourTravelNotesTopicId(byId.getId());
        tourUserLikeTopic.setTourTravelNotesTopicName(byId.getName());
        tourUserLikeTopicMapper.insert(tourUserLikeTopic);
        return ResponseResult.success();
    }

    /**
     * 取消搜藏
     * */
    @PostMapping("/cancelCollection")
    public ResponseResult<Void> cancelCollection(@RequestBody Map<String,Object> map){
        Long id = Long.valueOf(map.get("id").toString());
        TourTravelNotesTopic byId = tourTravelNotesTopicService.getById(id);
        if(byId==null){
            return ResponseResult.error("500","专题不存在");
        }
        Long userId = TokenData.takeFromRequest().getUserId();
        LambdaQueryWrapper<TourUserLikeTopic> query =
                Wrappers.<TourUserLikeTopic>lambdaQuery().eq(TourUserLikeTopic::getTourUserId, userId)
                        .eq(TourUserLikeTopic::getTourTravelNotesTopicId, byId.getId());
        tourUserLikeTopicMapper.delete(query);
        return ResponseResult.success();
    }

    /**
     *  他人主页
     */
    @GetMapping("/homePageDetailsDto")
    public ResponseResult<HomePageDetailsVo> homePageDetails(Long userId){
        TourUser byId = tourUserService.getById(userId);
        if(byId==null){
            return ResponseResult.error("500","用户不存在");
        }
        HomePageDetailsVo bean = BeanUtil.toBean(byId, HomePageDetailsVo.class);

        //获取用户粉丝数量
        ResponseResult<String> myFansCount = tourWebFansController.getMyFansCount(byId.getUserId().toString());
        bean.setNumberOfFollowers(myFansCount.getData());
        //获取用户关注数量
        ResponseResult<String> myConcern = tourWebFansController.getMyConcern(byId.getUserId().toString());
        bean.setNumberOfConcern(myConcern.getData());
        //获取用户获赞数量
        Set<Long> collect = this.getUserTravelNotesIds(userId);
        Long likeCount=0L;
        if(!ObjectUtil.isEmpty(collect)){
            likeCount=tourismProjectTravelNotesWriteMapper.getLikeCount(collect);
        }
        bean.setPraiseNum(likeCount);

        //获取用户和登录用户的关注状态
        Long me = TokenData.takeFromRequest().getUserId();
        //对方是否关注了我
        Long count1 = tourFansService.lambdaQuery().eq(TourFans::getAttentionId, me)
                .eq(TourFans::getCreateUserId, userId)
                .eq(TourFans::getDeleteFlag, 1).count();
        //我是否关注对方
        Long count2 = tourFansService.lambdaQuery().eq(TourFans::getAttentionId, userId)
                .eq(TourFans::getCreateUserId, me)
                .eq(TourFans::getDeleteFlag, 1).count();
        if(count1>0&&count2>0){
            //互关
            bean.setState("2");
        }else if(count1<=0&&count2<=0){
            //关注
            bean.setState("0");
        } else if(count1>0){
            //回关
            bean.setState("4");
        }else{
            //已关注
            bean.setState("1");
        }
        return ResponseResult.success(bean);
    }

    /**
     *  分页查询用户游记
     */
    @GetMapping("/getTravelNotes")
    public ResponseResult<MyPageData<TravelNotesVo>> getTravelNotes(Integer pageSize, Integer pageNum,String userId){
        if(userId==null){
            userId = TokenData.takeFromRequest().getUserId().toString();
        }
        LambdaQueryWrapper<TourismProjectTravelNotesWrite> query=
                Wrappers.<TourismProjectTravelNotesWrite>lambdaQuery()
                .eq(TourismProjectTravelNotesWrite::getCreateUserId, userId)
                .eq(TourismProjectTravelNotesWrite::getState, 3)
                .eq(TourismProjectTravelNotesWrite::getVisibleRange, 0)
                .eq(TourismProjectTravelNotesWrite::getDataState, 1)
                .orderByDesc(TourismProjectTravelNotesWrite::getIsTop,TourismProjectTravelNotesWrite::getCreateTime);

        PageMethod.startPage(pageNum==null?1:pageNum,pageSize==null?10:pageSize);
        List<TourismProjectTravelNotesWrite> list = tourismProjectTravelNotesWriteService.list(query);
        List<TravelNotesVo> bean = BeanUtil.copyToList(list, TravelNotesVo.class);
        long totalCount = 0L;
        if (list instanceof Page) {
            totalCount = ((Page<TourismProjectTravelNotesWrite>) list).getTotal();
        }
        if(ObjectUtil.isEmpty(bean)){
            return ResponseResult.success(MyPageUtil.makeResponseData(bean,totalCount));
        }
        if(CollectionUtils.isNotEmpty(bean)){
            bean.stream().forEach(item->{
                item.setImageUrl(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
            });
        }
        TourUser byId = tourUserService.getById(userId);
        bean.forEach(b->{
            b.setImage(byId.getHeadImageUrl());
            b.setName(byId.getShowName());
        });
        return ResponseResult.success(MyPageUtil.makeResponseData(bean,totalCount));
    }


    /**
     *  查看用户发布的游记ids
     */
    public Set<Long> getUserTravelNotesIds(Long userId){
        LambdaQueryWrapper<TourismProjectTravelNotesWrite> query=
                Wrappers.<TourismProjectTravelNotesWrite>lambdaQuery()
                        .eq(TourismProjectTravelNotesWrite::getCreateUserId, userId)
                        .eq(TourismProjectTravelNotesWrite::getState, 3)
                        .eq(TourismProjectTravelNotesWrite::getVisibleRange, 0)
                        .eq(TourismProjectTravelNotesWrite::getDataState, 1)
                        .orderByDesc(TourismProjectTravelNotesWrite::getIsTop,TourismProjectTravelNotesWrite::getCreateTime);
        List<TourismProjectTravelNotesWrite> list = tourismProjectTravelNotesWriteService.list(query);
        Set<Long> collect = list.stream().map(TourismProjectTravelNotesWrite::getId).collect(Collectors.toSet());
        return collect;
    }


    /**
     *  状态查询我的游记
     */
    @GetMapping("/getTravelNotesByState")
    public ResponseResult<MyPageData<TravelNotesByStateVo>> getTravelNotesByState(TravelNotesByStateDto param){
        Long userId = TokenData.takeFromRequest().getUserId();
        LambdaQueryWrapper<TourismProjectTravelNotesWrite> query = Wrappers.<TourismProjectTravelNotesWrite>lambdaQuery()
                .eq(TourismProjectTravelNotesWrite::getCreateUserId, userId)
                .eq(TourismProjectTravelNotesWrite::getState, param.getState())
                .orderByDesc(TourismProjectTravelNotesWrite::getIsTop,TourismProjectTravelNotesWrite::getCreateTime);
        PageMethod.startPage(param.getPageNum()==null?1:param.getPageNum(),
                param.getPageSize()==null?10:param.getPageSize());

        List<TourismProjectTravelNotesWrite> list = tourismProjectTravelNotesWriteService.list(query);
        long totalCount = 0L;
        if (list instanceof Page) {
            totalCount = ((Page<TourismProjectTravelNotesWrite>) list).getTotal();
        }

        List<TravelNotesByStateVo> vo = BeanUtil.copyToList(list, TravelNotesByStateVo.class);

        List<String> collect = vo.stream().map(TravelNotesByStateVo::getId).collect(Collectors.toList());

        //查询收藏的游记
        LambdaQueryWrapper<TourUserLikeTravelNotes> query1 = Wrappers.<TourUserLikeTravelNotes>lambdaQuery();
        query1.eq(TourUserLikeTravelNotes::getUserId,userId)
                .eq(TourUserLikeTravelNotes::getDataState, 1);
        List<TourUserLikeTravelNotes> list1 = tourUserLikeTravelNotesService.list(query1);

        //收藏的游记ids
        Set<String> collect1 = list1.stream().map(item->item.getTravelNotesId().toString()).collect(Collectors.toSet());
        //交集
        Collection<String> intersection = CollectionUtils.intersection(collect, collect1);
        for (TravelNotesByStateVo bean : vo) {
            if (intersection.contains(bean.getId())) {
                bean.setIsCollect("1");
            }else {
                bean.setIsCollect("0");
            }
        }
        if(CollectionUtils.isNotEmpty(vo)){
            vo.stream().forEach(item->{
                item.setImageUrl(UrlConvertUtils.urlConvert(applicationConfig.getHostIpPort(), item.getTourismUrl()));
            });
        }

        return ResponseResult.success(MyPageUtil.makeResponseData(vo,totalCount));
    }

    /**
     *  游记置顶
     */
    @PostMapping("/toTop")
    public ResponseResult<Void> toTop(@RequestBody TravelToTopDto params){
        Long userId = TokenData.takeFromRequest().getUserId();

        LambdaQueryWrapper<TourismProjectTravelNotesWrite> query = Wrappers.<TourismProjectTravelNotesWrite>lambdaQuery().eq(TourismProjectTravelNotesWrite::getId, params.getId())
                .eq(TourismProjectTravelNotesWrite::getCreateUserId, userId);
        List<TourismProjectTravelNotesWrite> list = tourismProjectTravelNotesWriteService.list(query);

        if(ObjectUtil.isEmpty(list)){
            return ResponseResult.error("500","游记不存在");
        }
        TourismProjectTravelNotesWrite write = new TourismProjectTravelNotesWrite();
        write.setIsTop(params.getIsTop());
        tourismProjectTravelNotesWriteService.update(write,query);
        return ResponseResult.success();
    }

    /**
     * 模糊搜索游记话题，默认根据最热进行排序
     * @param tourismTravelNotesWriteDto 入参（titleName：标题名称。模糊查询）
     * @return 结果
     */
    @OperationLog(type = SysOperationLogType.LIST)
    @GetMapping("/travelNotesPageListBySearch")
    public ResponseResult<TourTravelNotesTopicSearchVo> travelsTopicListByTitleName(TourTravelNotesTopicListByNameDto tourismTravelNotesWriteDto) {

        Long userId = TokenData.takeFromRequest().getUserId();
        String searchString = tourismTravelNotesWriteDto.getTitleName();
        //搜索内容不为空时记录
        if (MyCommonUtil.isNotBlankOrNull(searchString)){
            //查询用户搜索记录
            TourTourismProjectSearchRecords rawTourTourismSearchRecords = tourTourismSearchRecordsService
                    .getOne(new LambdaQueryWrapper<TourTourismProjectSearchRecords>()
                            .eq(TourTourismProjectSearchRecords::getSearchKeyword, searchString)
                            .eq(TourTourismProjectSearchRecords::getSearchType,1)   //0游记列表1话题列表
                            .eq(TourTourismProjectSearchRecords::getCreateUserId, userId));
            //已存搜索记录在数量进行自增1
            if (Objects.nonNull(rawTourTourismSearchRecords)){
                rawTourTourismSearchRecords.setSearchResultCount(rawTourTourismSearchRecords.getSearchResultCount()+1);
                rawTourTourismSearchRecords.setSearchTime(new Date());
                rawTourTourismSearchRecords.setUpdateTime(new Date());
                tourTourismSearchRecordsService.updateById(rawTourTourismSearchRecords);
            }else{  //不存在搜索记录则进行插入
                TourTourismProjectSearchRecords tourTourismSearchRecords = new TourTourismProjectSearchRecords();
                tourTourismSearchRecords.setSearchKeyword(searchString);
                //搜索次数初始为1
                tourTourismSearchRecords.setSearchResultCount(1);
                //0游记列表1话题列表
                tourTourismSearchRecords.setSearchType(1);
                tourTourismSearchRecords.setSearchTime(new Date());
                tourTourismSearchRecordsService.saveNew(tourTourismSearchRecords);
            }
        }
        return listPage(tourismTravelNotesWriteDto);
    }

    /**
     * @param id 游记ID
     * @return {@link ResponseResult }<{@link String }>
     */
    @GetMapping("/getWriteLikeCount")
    public ResponseResult<String> getWriteLikeCount(String id){
        if(id!=null){
            TourismProjectTravelNotesWrite byId = tourismProjectTravelNotesWriteService.getById(id);
            if(byId!=null){
                return ResponseResult.success(byId.getLikeCount()+"");
            }
        }
        return ResponseResult.error("500","游记不存在");
    }


}
