package com.cirle.scientific.controller.live;


import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.cirle.scientific.constants.ShareConsts;
import com.cirle.scientific.constants.TaskConsts;
import com.cirle.scientific.dao.QkjLiveDao;
import com.cirle.scientific.dto.ShareRankDto;
import com.cirle.scientific.po.QkjShare;
import com.cirle.scientific.service.QkjShareService;
import com.cirle.scientific.utils.DeviceUtil;
import com.cirle.scientific.utils.UserLoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSONObject;
import com.cirle.scientific.dto.QkjLiveCommentsDTO;
import com.cirle.scientific.dto.QkjLiveDetailDTO;
import com.cirle.scientific.po.QkjLive;
import com.cirle.scientific.po.QkjQuestionAnswer;
import com.cirle.scientific.pojo.BizCodeEnum;
import com.cirle.scientific.pojo.Result;
import com.cirle.scientific.server.WebSocketOneToMany;
import com.cirle.scientific.service.LiveService;
import com.cirle.scientific.service.OrderService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Controller
@RequestMapping("/live")
@Api("直播相关接口")
@Slf4j
public class LiveController {

    @Autowired
    private LiveService liveService;

    @Autowired
    private QkjLiveDao qkjLiveDao;

    @Autowired
    private WebSocketOneToMany webSocketOneToMany;

    @Autowired
    private OrderService orderService;


    @Autowired
    private QkjShareService qkjShareService;

    @PostMapping("/pushUser")
    @ResponseBody
    @ApiOperation("推送流量")
    /**
     * JSONObject
     * {
     *  "liveId":117,
     *  "users":[
     *      张三,李四,王五
     *  ]
     * }
     * users:用户数组
     */
    public Result pushUser(@RequestBody JSONObject data) {
        webSocketOneToMany.sendComing(data);
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @PostMapping("/sendStartLive")
    @ResponseBody
    @ApiOperation("推送开启或者关闭直播")
    public Result sendStartLive(
            @RequestParam(name = "liveId", required = true) Long liveId,
            @RequestParam(name = "liveStatus", required = true) Integer liveStatus
    ) {
        webSocketOneToMany.sendStartOrStopLive(liveId, liveStatus);
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @PostMapping("/sendImgPath")
    @ResponseBody
    @ApiOperation("推送图片")
    public Result sendImgPath(
            @RequestParam(name = "liveId", required = true) Long liveId,
            @RequestParam(name = "imgPath", required = true) String imgPath
    ) {
        webSocketOneToMany.sendImgPath(liveId, imgPath);
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @PostMapping("/sendLiveUserCount")
    @ResponseBody
    @ApiOperation("推送直播人气(当前在线人数)")
    public Result sendLiveUserCount(
            @RequestParam(name = "liveId", required = true) Long liveId,
            @RequestParam(name = "count", required = true) Integer count
    ) {
        webSocketOneToMany.sendLiveUserCount(liveId, count);
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @PostMapping("/pushBarrage")
    @ResponseBody
    @ApiOperation("推送弹幕")
    /**
     * JSONObject
     * {
     *  "liveId":117,
     *  "barrage":[
     *     {
     *         "name":"李四",
     *         "time":"11:11:11"  只要时分秒,
     *         "headImg":"xxxxxxxx.png",
     *         "content":"你好"
     *     },
     *     {
     *      *         "name":"李四",
     *      *         "time":"11:11:11"  只要时分秒,
     *      *         "headImg":"xxxxxxxx.png",
     *      *         "content":"你好"
     *      *     }
     *  ],
     * }
     * barrage :弹幕数组
     */
    public Result pushBarrage(@RequestBody JSONObject data) {
        webSocketOneToMany.pushBarrage(data);
        return Result.success(BizCodeEnum.SUCCESS);
    }

    @GetMapping("/getOnlineUser")
    @ResponseBody
    @ApiOperation("获取当前在线用户的memcard")
    public Result<JSONArray> getOnlineUser(@RequestParam(name = "liveId", required = true) Long liveId
    ) {
        Result<JSONArray> onlineUser = webSocketOneToMany.getOnlineUser(liveId);
        return onlineUser;
    }

    @GetMapping("/getOnlineUserCount")
    @ResponseBody
    @ApiOperation("获取当前在线人数")
    public Result<Integer> getOnlineUserCount(@RequestParam(name = "liveId", required = true) Long liveId
    ) {
        Result<Integer> onlineUsers = webSocketOneToMany.getOnlineUserCount(liveId);
        return onlineUsers;
    }

    @GetMapping("/index")
    @ApiOperation(value = "去往直播首页")
    public String gotoLiveIndex(
            @ApiParam(name = "from", value = "请求类型 web：网站 H5：手机端") @RequestParam(name = "from", required = true) String from
    ) {



        if (StringUtils.isNotBlank(from) && from.equals("H5")) {
            return "html5/live/live-index";
        } else {
            return "web/live/live-index";
        }
    }

    @GetMapping("/liveQuestion")
    @ApiOperation(value = "去往直播专区问卷")
    public String gotoLiveQuestion(
            @ApiParam(name = "from", value = "请求类型 web：网站 H5：手机端") @RequestParam(name = "from", required = true) String from
    ) {
        if (StringUtils.isNotBlank(from) && from.equals("H5")) {
            return "html5/live/live-questionnaire";
        } else {
            return "";
        }
    }

    @PostMapping("/getIndexData")
    @ApiOperation(value = "获取首页数据")
    @ResponseBody
    public Result indexData(HttpServletRequest request, @RequestAttribute(value = "memCard", required = false) String memCard) {
        // 默认展示pc端内容  0全部不显示 、1全部显示 、2m端显示、3pc端显示
        Integer status = 3;
        if(DeviceUtil.isMobileDevice(request)) {
            status = 2;
        }
        if (request.getSession().getAttribute("UserCard") != null) {
            memCard = (String) request.getSession().getAttribute("UserCard");
        }
        return Result.success(liveService.indexData(memCard, status));
    }

    @PostMapping("/liveList")
    @ApiOperation(value = "获取首页直播列表")
    @ResponseBody
    public Result<List<QkjLiveDetailDTO>> liveList(HttpServletRequest request,
                                                   @RequestAttribute(value = "memCard", required = false) String memCard,
                                                   @ApiParam(name = "cId", value = "分类ID") @RequestParam(name = "cId", required = true) Integer cId,
                                                   @ApiParam(name = "page", value = "分页") @RequestParam(name = "page", required = true, defaultValue = "1") Integer page,
                                                   @ApiParam(name = "size", value = "每页数量") @RequestParam(name = "size", required = true, defaultValue = "10") Integer size
    ) {
        if (request.getSession().getAttribute("UserCard") != null) {
            memCard = (String) request.getSession().getAttribute("UserCard");
        }
        return Result.success(liveService.getLiveList(memCard, cId, page, size));
    }

    @PostMapping("/livepage")
    @ApiOperation(value = "获取首页直播列表")
    @ResponseBody
    public Result<Map> livePage(HttpServletRequest request,
                                @RequestAttribute(value = "memCard", required = false) String memCard,
                                @ApiParam(name = "cId", value = "分类ID") @RequestParam(name = "cId", required = true) Integer cId,
                                @ApiParam(name = "page", value = "分页") @RequestParam(name = "page", required = true, defaultValue = "1") Integer page,
                                @ApiParam(name = "size", value = "每页数量") @RequestParam(name = "size", required = true, defaultValue = "10") Integer size
    ) {
        if (request.getSession().getAttribute("UserCard") != null) {
            memCard = (String) request.getSession().getAttribute("UserCard");
        }
        boolean isPC= DeviceUtil.isMobileDevice(request);
        return Result.success(liveService.pageLiveList(memCard, cId, page, size,isPC));
    }

    @GetMapping("/detail")
    @ApiOperation(value = "去往直播详情页面")
    public String detail(
            HttpServletRequest request,
            @ApiParam(name = "from", value = "请求类型 web：网站 H5：手机端") @RequestParam(name = "from", required = true) String from,
            @ApiParam(name = "fromMemCard", value = "分享者的ID") @RequestParam(name = "fromMemCard", required = false) String fromMemCard,
            @ApiParam(name = "liveId", value = "分类ID") @RequestParam(name = "liveId", required = true) Long liveId, Model model
    ) {
        String refererUrl = request.getHeader("Referer");
        if(refererUrl!=null && refererUrl.contains("login")){
            model.addAttribute("fromlogin","1");
        }else{
            model.addAttribute("fromlogin","0");
        }
        //获取详情
        QkjLive liveInfo = liveService.getLiveInfo(liveId);
        request.setAttribute("liveId", liveId);
        if(StringUtils.isNotBlank(fromMemCard)){
            request.setAttribute("fromMemCard", fromMemCard);
        }

        if (StringUtils.isNotBlank(from) && from.equals("H5")) {
            if (liveInfo.getLiveType() == 2) {
                return "html5/live/live-prefecture";
            } else {
                return "html5/live/live-alive";
            }
        } else {
            if (liveInfo.getLiveType() == 2) {
                return "web/live/live-zhuanquxq";
            } else {
                return "web/live/live-prefecture";
            }
        }
    }

    @PostMapping("/getDetailData")
    @ApiOperation(value = "获取直播详情")
    @ResponseBody
    public Result<QkjLiveDetailDTO> getDetailData(HttpServletRequest request,
                                                  @RequestHeader(value="referer", defaultValue = "0") String referer,
                                                  @RequestHeader(value="user-agent", defaultValue = "0") String userAgent,
                                                  @RequestAttribute(value = "memCard", required = false) String memCard,
                                                  @RequestParam(value = "fromMemCard", required = false) String fromMemCard,
                                                  @ApiParam(name = "liveId", value = "直播ID") @RequestParam(name = "liveId", required = true) Long liveId
    ) {
        log.info("getDetailData  memCard:{} fromMemCard:{} referer:{} userAgent:{}", memCard, fromMemCard, referer, userAgent);
        //借助详情的接口做分享的保存，点记者从分享者的链接进入必定调用这个接口
        QkjShare share = QkjShare.builder()
                .shareMemcard(fromMemCard)
                .clickMemcard(memCard)
                .objType(ShareConsts.obj_type_live)
                .objId(liveId.intValue())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        qkjShareService.saveQkjShare(share);
        return liveService.getLiveDetail(liveId, memCard);
    }

    @PostMapping("/infoByMember")
    @ApiOperation(value = "获取直播详情")
    @ResponseBody
    public Result infoByMember(HttpServletRequest request,
                               @RequestAttribute(value = "memCard", required = false) String memCard,
                               @ApiParam(name = "liveId", value = "直播ID") @RequestParam(name = "liveId", required = true) Long liveId
    ) {
        if (request.getSession().getAttribute("UserCard") != null) {
            memCard = (String) request.getSession().getAttribute("UserCard");
        }
        return liveService.infoByMember(liveId, memCard);
    }

    @PostMapping("/commentList")
    @ApiOperation(value = "获取直播评论列表")
    @ResponseBody
    public Result<List<QkjLiveCommentsDTO>> commentList(HttpServletRequest request,
                                                        @RequestAttribute(value = "memCard", required = false) String memCard,
                                                        @ApiParam(name = "liveId", value = "直播ID") @RequestParam(name = "liveId", required = true) Long liveId,
                                                        @ApiParam(name = "cId", value = "分页") @RequestParam(name = "cId", required = true) Integer cId
    ) {
        if (request.getSession().getAttribute("UserCard") != null) {
            memCard = (String) request.getSession().getAttribute("UserCard");
        }
        return liveService.getLiveComments(memCard, liveId, cId);
    }

    @PostMapping("/addLiveComment")
    @ApiOperation(value = "添加直播评论")
    @ResponseBody
    public Result<Boolean> addLiveComment(HttpServletRequest request,
                                          @RequestAttribute(value = "memCard", required = false) String memCard,
                                          @ApiParam(name = "liveId", value = "直播ID") @RequestParam(name = "liveId", required = true) Long liveId,
                                          @ApiParam(name = "content", value = "评论内容") @RequestParam(name = "content", required = true) String content
    ) {
        if (memCard == null && request.getSession().getAttribute("UserCard") == null) {
            return Result.failed(BizCodeEnum.NO_LOGIN);
        }
        memCard = memCard == null ? (String) request.getSession().getAttribute("UserCard") : memCard;
        return Result.success(liveService.addLiveComment(liveId, memCard, content));
    }

    @GetMapping("/liveRanking")
    @ApiOperation(value = "去往直播榜单页面")
    public String liveRanking(
            HttpServletRequest request,
            @ApiParam(name = "from", value = "请求类型 web：网站 H5：手机端") @RequestParam(name = "from", required = true) String from,
            @ApiParam(name = "liveId", value = "直播ID") @RequestParam(name = "liveId", required = true) Long liveId
    ) {
        request.setAttribute("liveId", liveId);
        if (StringUtils.isNotBlank(from) && from.equals("H5")) {
            return "html5/live/live-ranking";
        } else {
            return "";
        }
    }

    @PostMapping("/rankList")
    @ResponseBody
    public Result<JSONObject> rankList(
            @RequestAttribute(value = "memCard", required = false) String memCard,
            @RequestParam Integer objType,
            @RequestParam Integer objId
    ) {
        List<ShareRankDto> rs = qkjShareService.inviteRank("", objType, objId);
        JSONArray jsonArray = new JSONArray();
        if (CollectionUtils.isNotEmpty(rs)) {
            jsonArray = JSONArray.parseArray(JSON.toJSONString(rs));
        }
        JSONObject rstData = new JSONObject();
        rstData.put("rankList", jsonArray);
        return Result.success(rstData);
    }

    @RequestMapping(value = "/addRemind", method = RequestMethod.POST)
    @ResponseBody
    public Result<Map<String, Object>> addRemind(HttpServletRequest request,
                                                 @RequestAttribute(value = "memCard", required = false) String memCard,
                                                 @RequestParam Long liveId
    ) {
        if (memCard == null && request.getSession().getAttribute("UserCard") == null) {
            return Result.failed(BizCodeEnum.NO_LOGIN);
        }
        memCard = memCard == null ? (String) request.getSession().getAttribute("UserCard") : memCard;
        return liveService.reserveOrBets(memCard, liveId.toString());
    }

    @RequestMapping(value = "/saveQuestionAnswer", method = RequestMethod.POST)
    @ResponseBody
    public Result saveQuestionAnswer(HttpServletRequest request,
                                     @RequestAttribute(value = "memCard", required = false) String memCard,
                                     @RequestParam String questions,
                                     @RequestParam Integer liveId
    ) {
        if (memCard == null && request.getSession().getAttribute("UserCard") == null) {
            return Result.failed(BizCodeEnum.NO_LOGIN);
        }
        memCard = memCard == null ? (String) request.getSession().getAttribute("UserCard") : memCard;
        return liveService.saveQuestionAnswer(memCard, questions, liveId);
    }

    /**
     * 阿里云监听推流回调通知
     * @param request
     * @return
     */
    @GetMapping("/pushStreamCallback")
    @ResponseBody
    public Result pushStreamCallback(HttpServletRequest request) {
        liveService.pushStreamCallback(request);
        return Result.success(true);
    }


    @GetMapping("/auto/inc")
    @ResponseBody
    @ApiOperation("自动增长参与人数和预约人数")
    public Result aotuLiveNum(
            HttpServletRequest request,
            @ApiParam(name = "memCard", value = "用户唯一标识") @RequestAttribute(name = "memCard", required = false) String memCard,
            @RequestParam(value = "params", required = false) String params
    ) {
        if (StringUtils.isBlank(memCard)) {//pc从session去 m从参数取
            memCard = UserLoginUtil.isUserLogin(request);
        }
        log.info("aotuLiveNum memCard is null   {}",params);

        return Result.success(liveService.autoIncNum(params));
    }

    @GetMapping("/shenmi")
    @ResponseBody
    @ApiOperation("运营人员操作改变joinnumber")
    public Result updateJoinNumber(
            HttpServletRequest request,
            @ApiParam(name = "memCard", value = "用户唯一标识") @RequestAttribute(name = "memCard", required = false) String memCard,
            @RequestParam(value = "liveId", required = true) Long liveId,
            @RequestParam(value = "num", required = true) Long num
    ) {
        log.info("updateJoinNumber liveId :{} num:{}", liveId, num);

        if(num>0){
            qkjLiveDao.updateJoinMembers(num, liveId);
        }else  if (num<0){
            qkjLiveDao.reduceJoinMembers(Math.abs(num), liveId);
        } else if (num ==0) {
            QkjLive byLiveId = qkjLiveDao.findById(String.valueOf(liveId));
            if(Objects.nonNull(byLiveId)){
                return Result.success(byLiveId.getJoinMembers());
            }
        }
        return Result.success("修改成功");
    }

    @GetMapping("/getUserInfoByLiveId")
    @ResponseBody
    @ApiOperation("获取当前观看直播的人的信息")
    public Result getUserInfoByLiveId(
            @RequestParam(name = "liveId", required = true) Integer liveId,
            @RequestAttribute(value = "memCard", required = false) String memCard
    ) {

        if(StringUtils.isBlank(memCard)){
            return Result.failed(BizCodeEnum.NO_LOGIN);
        }
        return liveService.getUserInfoByLiveId(memCard, liveId);
    }
}
