package com.slodon.b2b2c.controller.helpdesk.admin;

import com.slodon.b2b2c.core.constant.AdminConst;
import com.slodon.b2b2c.core.constant.HelpdeskConst;
import com.slodon.b2b2c.core.constant.StoreConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.core.util.UserUtil;
import com.slodon.b2b2c.core.util.WebUtil;
import com.slodon.b2b2c.helpdesk.dto.VendorContactDTO;
import com.slodon.b2b2c.helpdesk.pojo.HelpdeskMsg;
import com.slodon.b2b2c.model.seller.StoreModel;
import com.slodon.b2b2c.model.seller.VendorModel;
import com.slodon.b2b2c.model.system.AdminModel;
import com.slodon.b2b2c.seller.example.StoreExample;
import com.slodon.b2b2c.seller.example.VendorExample;
import com.slodon.b2b2c.seller.pojo.Store;
import com.slodon.b2b2c.seller.pojo.Vendor;
import com.slodon.b2b2c.system.example.AdminExample;
import com.slodon.b2b2c.system.pojo.Admin;
import com.slodon.b2b2c.util.MongoDBUtil;
import com.slodon.b2b2c.vo.helpdesk.HelpdeskMsgLogVO;
import com.slodon.b2b2c.vo.helpdesk.HelpdeskMsgVO;
import com.slodon.b2b2c.vo.helpdesk.HelpdeskStoreVO;
import com.slodon.b2b2c.vo.helpdesk.HelpdeskVendorVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.slodon.b2b2c.socket.helpdesk.server.ImSocketServer.MSG_PREFIX;
import static com.slodon.b2b2c.socket.helpdesk.server.ImSocketServer.VENDOR_CONTACT_PREFIX;


@Api(tags = "admin-聊天管理")
@RestController
@RequestMapping("v3/helpdesk/admin/chat")
public class AdminChatController extends BaseController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private StoreModel storeModel;
    @Resource
    private AdminModel adminModel;
    @Resource
    private VendorModel vendorModel;
    @Resource
    private MongoTemplate mongoTemplate;

    @ApiOperation("平台供应商列表")
    @GetMapping("storeList")
    public JsonResult<List<HelpdeskStoreVO>> storeList(HttpServletRequest request) {
        Admin admin = UserUtil.getUser(request, Admin.class);
        //查看其他客服聊天记录，只有超级管理员有权限
        AssertUtil.isTrue(admin.getIsSuper() != AdminConst.IS_SUPER_ADMIN_YES, "无权查看");
        StoreExample storeExample = new StoreExample();
        storeExample.setState(StoreConst.STORE_STATE_OPEN);
        List<Store> storeList = storeModel.getStoreList(storeExample,null);
        List<HelpdeskStoreVO> vos = new ArrayList<>();
        vos.add(new HelpdeskStoreVO(0L,"平台"));
        storeList.forEach(store -> {
            vos.add(new HelpdeskStoreVO(store));
        });
        return SldResponse.success(vos);
    }

    @ApiOperation("供应商客服列表")
    @GetMapping("vendorList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "供应商id，0表示平台", paramType = "query")
    })
    public JsonResult<List<HelpdeskVendorVO>> vendorList(HttpServletRequest request,
                                                         @RequestParam(value = "storeId") Long storeId) {
        Admin admin = UserUtil.getUser(request, Admin.class);
        //查看其他客服聊天记录，只有超级管理员有权限
        AssertUtil.isTrue(admin.getIsSuper() != AdminConst.IS_SUPER_ADMIN_YES, "无权查看");
        List<HelpdeskVendorVO> vos = new ArrayList<>();
        if (storeId.equals(0L)){
            //平台
            AdminExample adminExample = new AdminExample();
            adminExample.setState(AdminConst.ADMIN_STATE_NORM);
            List<Admin> adminList = adminModel.getAdminList(adminExample,null);
            adminList.forEach(admin1 -> {
                vos.add(new HelpdeskVendorVO(admin1));
            });
        }else {
            //供应商
            VendorExample vendorExample = new VendorExample();
            vendorExample.setStoreId(storeId);
            List<Vendor> vendorList = vendorModel.getVendorList(vendorExample,null);
            vendorList.forEach(vendor -> {
                vos.add(new HelpdeskVendorVO(vendor));
            });
        }
        return SldResponse.success(vos);
    }

    @ApiOperation("聊天列表会员")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "msgId", value = "已获取到的最早的一条消息的id", paramType = "query"),
            @ApiImplicitParam(name = "memberName", value = "会员名称", paramType = "query"),
            @ApiImplicitParam(name = "vendorId", value = "客服Id，查看自己的聊天记录时不传", paramType = "query"),
            @ApiImplicitParam(name = "storeId", value = "供应商id，查看自己的聊天记录时不传", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<List<HelpdeskMsgVO>> chatList(HttpServletRequest request, String memberName, Long vendorId, Long storeId,
                                                    @RequestParam(value = "msgId", required = false, defaultValue = Long.MAX_VALUE + "") Long msgId) {
        Admin admin = UserUtil.getUser(request, Admin.class);
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        if (storeId != null) {
            //查看其他客服聊天记录，只有超级管理员有权限
            AssertUtil.isTrue(admin.getIsSuper() != AdminConst.IS_SUPER_ADMIN_YES, "无权查看");
            //返回管理员可查看的记录
            return this.adminCheckList(memberName,vendorId,storeId,msgId,pager);
        }else {
            //查看自己的聊天记录
            vendorId = Long.valueOf(admin.getAdminId());
            storeId = 0L;
        }
        List<VendorContactDTO> list = MongoDBUtil.getVendorContactList(VENDOR_CONTACT_PREFIX, memberName,
                vendorId, msgId, pager);
        List<HelpdeskMsgVO> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return SldResponse.success(result);
        }
        //供应商id=0即为平台客服

        for (VendorContactDTO vendorContact : list) {
            //会员id
            Integer memberId = vendorContact.getMemberId();
            //先从MongoDB中获取
            HelpdeskMsg helpdeskMsg = MongoDBUtil.getChatDetail(MSG_PREFIX, vendorContact.getMsgId());
            if (helpdeskMsg != null) {
                if (StringUtils.isEmpty(helpdeskMsg.getMemberAvatar())) {
                    helpdeskMsg.setVendorAvatar(stringRedisTemplate.opsForValue().get("default_image_store_logo"));
                }
                //未读数量
                Long unreadNum = MongoDBUtil.getUnReadNum(MSG_PREFIX, helpdeskMsg.getStoreId(), memberId, HelpdeskConst.ROLE_TYPE_MEMBER);
                helpdeskMsg.setReceiveMsgNumber(StringUtil.isNullOrZero(unreadNum) ? 0 : unreadNum.intValue());
                result.add(new HelpdeskMsgVO(helpdeskMsg));
            }
        }
        return SldResponse.success(result);
    }

    /**
     * 管理员可查看的记录，客服删除了聊天记录，管理员也可查看
     *
     * @param memberName 会员名
     * @param vendorId 客服id
     * @param storeId 店铺id
     * @param msgId 已获取到的最早的一条消息的id
     * @param pager 分页
     * @return 管理员可查看的记录
     */
    private JsonResult<List<HelpdeskMsgVO>> adminCheckList(String memberName, Long vendorId, Long storeId, Long msgId, PagerInfo pager) {
        //直接查询消息表
        List<HelpdeskMsgVO> result = new ArrayList<>();
        Criteria criteria = new Criteria();
        criteria.and("storeId").is(storeId);
        criteria.and("vendorId").is(vendorId);
        if (!StringUtils.isEmpty(memberName)) {
            criteria.and("memberName").regex("^.*" + memberName + ".*$");
        }
        AggregationResults<ModelMap> aggregate = mongoTemplate.aggregate(Aggregation.newAggregation(
                Aggregation.match(criteria),//按条件过滤
                Aggregation.sort(Sort.by(Sort.Direction.DESC,"msgId")),//排序
                Aggregation.group("memberId").first("msgId").as("msgId"),//按会员id分组
                Aggregation.match(Criteria.where("msgId").lt(msgId)),
                Aggregation.sort(Sort.by(Sort.Direction.DESC,"msgId")),//排序
                Aggregation.limit(pager.getPageSize()),//分页
                Aggregation.group().addToSet("msgId").as("list")//将符合条件的msgId放入列表
        ), MSG_PREFIX, ModelMap.class);
        List<ModelMap> mappedResults = aggregate.getMappedResults();
        if (CollectionUtils.isEmpty(mappedResults)){
            return SldResponse.success(result);
        }
        //取符合条件的msgId
        List<?> msgIdList = (List<?>) mappedResults.get(0).get("list");
        List<HelpdeskMsg> helpdeskMsgList = mongoTemplate.find(
                Query.query(Criteria.where("msgId").in(msgIdList)).with(Sort.by(Sort.Direction.DESC,"msgId")),
                HelpdeskMsg.class, "helpdesk_msg");

        helpdeskMsgList.forEach(helpdeskMsg -> {
            if (StringUtils.isEmpty(helpdeskMsg.getMemberAvatar())) {
                helpdeskMsg.setVendorAvatar(stringRedisTemplate.opsForValue().get("default_image_store_logo"));
            }
            //未读数量
            Long unreadNum = MongoDBUtil.getUnReadNum(MSG_PREFIX, helpdeskMsg.getStoreId(), helpdeskMsg.getMemberId(), HelpdeskConst.ROLE_TYPE_MEMBER);
            helpdeskMsg.setReceiveMsgNumber(StringUtil.isNullOrZero(unreadNum) ? 0 : unreadNum.intValue());
            result.add(new HelpdeskMsgVO(helpdeskMsg));
        });
        return SldResponse.success(result);
    }

    @ApiOperation("聊天记录列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "会员id", paramType = "query"),
            @ApiImplicitParam(name = "vendorId", value = "客服Id，查看自己的聊天记录时不传", paramType = "query"),
            @ApiImplicitParam(name = "storeId", value = "供应商id，查看自己的聊天记录时不传", paramType = "query"),
            @ApiImplicitParam(name = "msgContent", value = "消息内容", paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query"),
            @ApiImplicitParam(name = "msgId", value = "已获取到的最早的一条消息的id", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("logList")
    public JsonResult<PageVO<HelpdeskMsgLogVO>> chatLogList(HttpServletRequest request, Integer memberId, Long vendorId, Long storeId,
                                                            String msgContent, Date startTime, Date endTime, Long msgId) {
        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        List<HelpdeskMsg> list = MongoDBUtil.getHelpDeskMsgLogList(MSG_PREFIX, storeId, memberId, vendorId,
                msgContent, startTime, endTime, msgId, pager);
        List<HelpdeskMsgLogVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(helpdeskMsg -> {
                vos.add(0, new HelpdeskMsgLogVO(helpdeskMsg));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("聊天记录,返回比msgId小的10条记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "memberId", value = "会员id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "storeId", value = "会员要咨询的供应商id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "msgId", value = "已获取到的最早的一条消息的id", paramType = "query"),
    })
    @PostMapping("msgLog")
    public JsonResult<List<HelpdeskMsgVO>> msgLog(HttpServletRequest request, @RequestParam(value = "memberId") Integer memberId,
                                                  @RequestParam(value = "storeId") Long storeId,
                                                  @RequestParam(value = "msgId", required = false, defaultValue = Long.MAX_VALUE + "") Long msgId) {
        //每次获取消息条数
        int pageSize = 10;
        //先从MongoDB中获取
        List<HelpdeskMsg> msgList = MongoDBUtil.getHelpDeskMsgList(MSG_PREFIX, storeId, memberId, msgId, pageSize);
        List<HelpdeskMsgVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(msgList)) {
            for (HelpdeskMsg helpdeskMsg : msgList) {
                if (StringUtils.isEmpty(helpdeskMsg.getMemberAvatar())) {
                    helpdeskMsg.setMemberAvatar(stringRedisTemplate.opsForValue().get("default_image_user_portrait"));
                }
                vos.add(0, new HelpdeskMsgVO(helpdeskMsg));
            }
        }
        return SldResponse.success(vos);
    }

}
