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.tourism.common.additional.config.ApplicationConfig;
import com.tourism.common.additional.utils.StringUtils;
import com.tourism.common.core.annotation.DisableDataFilter;
import com.tourism.common.core.constant.ErrorCodeEnum;
import com.tourism.common.core.object.ResponseResult;
import com.tourism.common.core.object.TokenData;
import com.tourism.common.core.upload.BaseUpDownloader;
import com.tourism.common.core.upload.UpDownloaderFactory;
import com.tourism.common.core.upload.UploadResponseInfo;
import com.tourism.common.core.upload.UploadStoreInfo;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.log.annotation.OperationLog;
import com.tourism.common.log.model.constant.SysOperationLogType;
import com.tourism.common.redis.cache.SessionCacheHelper;
import com.tourism.webadmin.app.website.dto.*;
import com.tourism.webadmin.app.website.service.TourGroupService;
import com.tourism.webadmin.app.website.service.TourMemberService;
import com.tourism.webadmin.app.website.vo.GroupUserListVo;
import com.tourism.webadmin.app.website.vo.OneWayMemberVo;
import com.tourism.webadmin.app.website.vo.UserVo;
import com.tourism.webadmin.back.model.*;
import com.tourism.webadmin.back.service.TourImGroupService;
import com.tourism.webadmin.back.service.TourUserService;
import com.tourism.webadmin.back.vo.TourImMemberVo;
import com.tourism.webadmin.back.vo.TourImMessageVo;
import com.tourism.webadmin.enums.GroupRole;
import com.tourism.webadmin.ws.handle.SystemMessageHandler;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 类功能描述：
 *      获取登录用户会话列表
 * @author 大春
 * @date 2025/01/03
 */

@Tag(name = "会话列表")
@RestController
@Slf4j
@RequestMapping("/website/tourMember")
@DisableDataFilter
public class TourMemberController {
    @Autowired
    private TourMemberService tourMemberService;
    @Autowired
    private TourUserService tourUserService;
    @Autowired
    private TourImGroupService tourImGroupService;
    @Autowired
    private UpDownloaderFactory upDownloaderFactory;
    @Autowired
    private ApplicationConfig appConfig;
    @Autowired
    private SessionCacheHelper cacheHelper;
    @Autowired
    private TourGroupService tourGroupService;
    @Autowired
    private SystemMessageHandler systemMessageHandler;
    /**
     * 获取群成员信息
     */
    @GetMapping("/getTourMemberInfoList")
    public ResponseResult<List<TourImMemberVo>> getTourMemberList(Long groupId){
        //参数校验
        if (groupId == null) return null;
        //群组校验
        TourImGroup group = tourImGroupService.getById(groupId);
        if (group == null) return null;

        //查询群成员列表
        List<TourImMember> memberList = tourMemberService.list(new LambdaQueryWrapper<TourImMember>()
                .eq(TourImMember::getGroupId, groupId).eq(TourImMember::getDataState,1)
        );
        List<TourImMemberVo> memberVos = MyModelUtil.copyCollectionTo(memberList, TourImMemberVo.class);
        // 获取所有用户ID列表
        List<Long> userIds = memberList.stream().map(TourImMember::getUserId).collect(Collectors.toList());

        // 查询 tour_user 表的用户信息
        List<TourUser> userList = tourUserService.list(new LambdaQueryWrapper<TourUser>()
                        .in(TourUser::getUserId, userIds));
        //填充头像和昵称
        memberVos.forEach(member -> {
            Optional<TourUser> tourUser = userList.stream().filter(user -> user.getUserId().toString().equals(member.getUserId())).findFirst();

            if (StringUtils.isNotEmpty(tourUser.get().getHeadImageUrl())){
                member.setHeadImageUrl(tourUser.get().getHeadImageUrl());
            }
            if (StringUtils.isNotEmpty(tourUser.get().getShowName())){
                member.setGroupNickname(tourUser.get().getShowName());
            }
        });
        return ResponseResult.success(memberVos);
    }

    /**
     * 修改群聊会话信息
     */
    @PostMapping("/updateTourMember")
    public ResponseResult<Void> updateTourMember(@RequestBody UpdateTourMemberDto params){
        boolean tourMember = tourMemberService.updateTourMember(params);
        if (tourMember){
            return ResponseResult.success();
        }
        return ResponseResult.error(ErrorCodeEnum.SERVER_INTERNAL_ERROR);
    }

    /**
     *  获取用户互关列表(去重再群里的)
     * @param groupId
     * @return {@link ResponseResult }<{@link List }<{@link TourUser }>>
     */
    @GetMapping("/memberLit")
    public ResponseResult<List<UserVo>> memberLit(Long groupId){
        List<TourUser> list=tourMemberService.memberLit(groupId);
        List<UserVo> userVos = BeanUtil.copyToList(list, UserVo.class);
        return ResponseResult.success(userVos);
    }


    /**
     * 移除群成员
     * @param  params
     * @return {@link ResponseResult }<{@link Void }>
     */
    @PostMapping("/removeMember")
    public ResponseResult<String> removeMember(@RequestBody RemoveMemberDto params){
        //参数校验
        if (ObjectUtil.isEmpty(params.getGroupId()) || ObjectUtil.isEmpty(params.getDelUser())){
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
        }
        Long userId = TokenData.takeFromRequest().getUserId();
        //判断登录账户是否是管理员
        boolean admin = tourGroupService.isAdmin(params.getGroupId(),userId);
        if(!admin) {
            return ResponseResult.success("您不是管理员,操作失败!!");
        };
        tourMemberService.removeMember(params);
        return ResponseResult.success("操作成功");
    }

    /**
     * 修改通用会话信息
     * @param params
     * @return {@link ResponseResult }<{@link Void }>
     */
    @PostMapping("/updateSingleTourMember")
    public ResponseResult<Boolean> updateSingleTourMember(@RequestBody UpdateSingleTourMemberDto params){
        boolean b =  tourMemberService.updateSingleTourMember(params);
        return ResponseResult.success(b);
    }


    /**
     * 背景图片文件上传文件上传操作。
     *
     * @param fieldName  上传文件名。
     * @param asImage    是否作为图片上传。如果是图片，今后下载的时候无需权限验证。否则就是附件上传，下载时需要权限验证。
     * @param uploadFile 上传文件对象。
     */
    @OperationLog(type = SysOperationLogType.UPLOAD, saveResponse = false)
    @PostMapping("/upload")
    public void upload(
            @RequestParam String fieldName,
            @RequestParam Boolean asImage,
            @RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
        long size = 0;
        String remark = "";
        if (asImage){
            size=1024*1024*10;
            remark="图片大小不能超过20M";
        }else {
            size=1024*1024*20;
            remark="文件大小不能超过20M";
        }
        if(uploadFile.getSize()>size){
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.INVALID_UPLOAD_FILE_IOERROR, remark));
            return;
        }
        UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(TourImMember.class, fieldName);
        // 根据字段注解中的存储类型，通过工厂方法获取匹配的上传下载实现类，从而解耦。
        BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
        UploadResponseInfo responseInfo = upDownloader.doUpload(null,
                appConfig.getUploadFileBaseDir(), TourImComplait.class.getSimpleName(), fieldName, asImage, uploadFile);
        if (Boolean.TRUE.equals(responseInfo.getUploadFailed())) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.UPLOAD_FAILED, responseInfo.getErrorMessage()));
            return;
        }
        cacheHelper.putSessionUploadFile(responseInfo.getFilename());
        ResponseResult.output(ResponseResult.success(responseInfo));
    }


    /**
     *  邀请加入群聊 || 自己加入群聊
     * @return {@link ResponseResult }<{@link Void }> 1 失败  2 需要管理员验证 3 加入成功
     */
    @PostMapping("/invite")
    public ResponseResult<Boolean> invite(@RequestBody InviteToGroupDto params){
        TourImGroup group = tourGroupService.getById(params.getGroupId());
        List<TourUser> user = tourUserService.getBaseMapper().selectBatchIds(params.getIds());
        //判断群聊是否封禁、删除  人员是否存在
        if(group==null||group.getDataState().equals(-1)||group.getBannedStatus().equals(0) ||user==null||user.isEmpty()){
            return ResponseResult.error("500","群聊已经封禁或不存在");
        }
        List<Long> ids = user.stream().map(TourUser::getUserId).collect(Collectors.toList());
        Set<Long> error=tourMemberService.isExist(ids, params.getGroupId());
        if(!error.isEmpty()){
            List<TourUser> tourUsers = tourUserService.getBaseMapper().selectBatchIds(error);

            StringBuilder errorMsg = new StringBuilder();
            for (TourUser tourUser : tourUsers) {
                errorMsg.append(tourUser.getShowName()).append("、");
            }
            return ResponseResult.error("500","用户"+errorMsg+"已经申请加入群聊或已经加入群聊");
        }
        boolean b= tourMemberService.invite(group, user);
        List<Long> paramsIds = params.getIds();
        for (Long paramsId : paramsIds) {
            Map<String, WebSocketSession> sessionMap = systemMessageHandler.getSessionMap();
            if (sessionMap.containsKey(paramsId.toString())){
                WebSocketSession webSocketSession = sessionMap.get(paramsId.toString());
                Long groupId = params.getGroupId();
                Map<String, Map<String, WebSocketSession>> groupMap = systemMessageHandler.getGroupMap();
                if (groupMap.containsKey(groupId.toString())){
                    Map<String, WebSocketSession> webSocketSessionMap = groupMap.get(groupId.toString());
                    webSocketSessionMap.put(paramsId.toString(), webSocketSession);
                }
            }
        }

        return ResponseResult.success(b);
    }


    /**用户加入系统消息*/
    @GetMapping("/test")
    public ResponseResult<Void> test(){
        ArrayList<String>  groupId = new ArrayList<>();
        groupId.add("-1");
        groupId.add("-2");
        groupId.add("-3");
        for (String s : groupId) {
            Long a = Long.valueOf(s);
            TourImGroup group = tourImGroupService.getById(a);
            ArrayList<TourImMember> tourImMembers = new ArrayList<>();
            //全部用户
            List<TourUser> tourUsers = tourUserService.getBaseMapper().selectList(Wrappers.<TourUser>lambdaQuery().notIn(TourUser::getUserId,groupId));

            //遍历创建member对象
            for (TourUser l : tourUsers) {
                TourImMember member = new TourImMember();


                member.setGroupId(group.getId());
                if(l.getUserId().equals(group.getCreateUserId())){
                    member.setGroupRole(GroupRole.GROUP_LEADER.getCode());
                }else {
                    member.setGroupRole(GroupRole.ORDINARY_MEMBERS.getCode());
                }
                member.setUserId(l.getUserId());
                member.setDataState(1);
                member.setUpdateTime(new Date());
                member.setUpdateUserId(group.getCreateUserId());
                member.setCreateUserId(group.getCreateUserId());
                tourImMembers.add(member);

            }
            tourMemberService.saveBatch(tourImMembers);
        }
        return null;
    }




    /**
     *  获取群聊用户列表
     * @param groupId 群ID
     * @return {@link List }<{@link GroupUserListVo }>
     */
    @GetMapping("/getGroupUserListVo")
    public ResponseResult<List<GroupUserListVo>> getGroupUserListVo(String groupId){
        TourImGroup byId = tourGroupService.getById(groupId);
        if(byId==null) return null;
        List<TourImMember> tourImMembers = tourMemberService.getBaseMapper()
                .selectList(Wrappers.<TourImMember>lambdaQuery()
                        .eq(TourImMember::getGroupId, groupId)
                        .eq(TourImMember::getDataState, 1));
        List<GroupUserListVo> groupUserListVos = new ArrayList<>();
        //群成员
        List<Long> collect = tourImMembers.stream().map(TourImMember::getUserId).collect(Collectors.toList());

        List<TourUser> tourUsers = tourUserService.getBaseMapper().selectBatchIds(collect);
        HashMap<String, TourUser> userMap = new HashMap<>();
        for (TourUser tourUser : tourUsers) {
            userMap.put(tourUser.getUserId().toString(),tourUser);
        }
        for (TourImMember tourImMember : tourImMembers) {
            TourUser tourUser = userMap.get(tourImMember.getUserId().toString());
            if(!ObjectUtil.isEmpty(tourUser)){
                GroupUserListVo bean = BeanUtil.toBean(tourUser, GroupUserListVo.class);
                bean.setGroupRole(tourImMember.getGroupRole().toString());
                bean.setGroupNickname(tourImMember.getGroupNickname());
                groupUserListVos.add(bean);
            }
        }

        if(!groupUserListVos.isEmpty()){
            List<GroupUserListVo> collect1 = groupUserListVos.stream().filter(o -> GroupRole.GROUP_LEADER.getCode().toString().equals(o.getGroupRole())).collect(Collectors.toList());
            List<GroupUserListVo> collect2 = groupUserListVos.stream().filter(o -> GroupRole.ADMINISTRATORS.getCode().toString().equals(o.getGroupRole())).collect(Collectors.toList());
            List<GroupUserListVo> collect3 = groupUserListVos.stream().filter(o -> GroupRole.ORDINARY_MEMBERS.getCode().toString().equals(o.getGroupRole())).collect(Collectors.toList());
            collect1.addAll(collect2);
            collect1.addAll(collect3);
            //对ID进行加密
            for (GroupUserListVo vo : groupUserListVos) {
                String id = vo.getUserId();
//                String encrypt = aesUtil.encrypt(id);
                vo.setPass(id);
            }
            return ResponseResult.success(collect1);
        }
        return ResponseResult.success(new ArrayList<>());
    }


    /**
     *  单聊获取会话信息
     * @param groupId
     * @return {@link ResponseResult }<{@link List }<{@link OneWayMemberVo }>>
     */

    @GetMapping("/getOneWayMember")
    public ResponseResult<List<OneWayMemberVo>> getOneWayMember(String groupId){
        Long userId = TokenData.takeFromRequest().getUserId();
        TourUser my = tourUserService.getById(userId);
        if(my==null) return ResponseResult.error("500","用户不存在或被封禁");
        TourImGroup group = tourImGroupService.getById(groupId);
        if(group==null) return ResponseResult.error("500","会话不存在或被封禁");
        LambdaQueryWrapper<TourImMember> query = Wrappers.<TourImMember>lambdaQuery().eq(TourImMember::getGroupId, groupId)
                .eq(TourImMember::getDataState, 1);
        List<TourImMember> list1 = tourMemberService.list(query);
        if(list1.isEmpty())return ResponseResult.success(null);
        List<OneWayMemberVo> oneWayMemberVos = BeanUtil.copyToList(list1, OneWayMemberVo.class);
        OneWayMemberVo member = new OneWayMemberVo();
        if (list1.size()==1) {
            member = oneWayMemberVos.get(0);
        }else if (list1.size()==2) {
            List<OneWayMemberVo> collect = oneWayMemberVos.stream().filter(o -> o.getUserId().equals(my.getUserId().toString())).collect(Collectors.toList());
            member = collect.get(0);
        }
        //对方没创建 member  手动构建对方的member
        OneWayMemberVo tourImMember = new OneWayMemberVo();
        TourUser toUser = tourUserService.getById(member.getPartnerId());
        if(toUser==null) return ResponseResult.success(null);
        if(list1.size()==1){
            tourImMember.setGroupRemark(my.getShowName());
            tourImMember.setUserId(toUser.getUserId().toString());
            tourImMember.setPartnerId(my.getUserId().toString());
            oneWayMemberVos.add(tourImMember);
        }
        for (OneWayMemberVo oneWayMemberVo : oneWayMemberVos) {
            if(oneWayMemberVo.getUserId().equals(my.getUserId().toString())){
                if (ObjectUtil.isEmpty(oneWayMemberVo.getGroupRemark())){
                    oneWayMemberVo.setGroupRemark(toUser.getShowName());
                }
                oneWayMemberVo.setHeadImage(toUser.getHeadImageUrl());
            }
            if(oneWayMemberVo.getPartnerId().equals(my.getUserId().toString())){
                if (ObjectUtil.isEmpty(oneWayMemberVo.getGroupRemark())){
                    oneWayMemberVo.setGroupRemark(my.getShowName());
                }
                oneWayMemberVo.setHeadImage(my.getHeadImageUrl());
            }
        }
        return ResponseResult.success(oneWayMemberVos);
    }
}
