/**
 * FileName: liveStuController
 * Author:   wenjunlong
 * Date:     2018/4/25 11:27
 * Description: 直播app端接口
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.yizhi.application.live.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;

import com.yizhi.application.live.util.HttpUtil;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.live.application.feign.LiveActivityClient;
import com.yizhi.live.application.request.LiveReleaseReviewReq;
import com.yizhi.live.application.vo.*;
import com.yizhi.site.application.enums.FunctionTypeCode;
import com.yizhi.site.application.feign.api.FunctionDisplayConfigApiClients;
import com.yizhi.site.application.vo.domain.FunctionDisplayConfigVo;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.util.application.domain.BizResponse;
import com.yizhi.util.application.domain.Response;
import com.yizhi.util.application.enums.i18n.Constants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 〈一句话功能简述〉<br> 
 * 〈直播app端接口〉
 *
 * @author wenjunlong
 * @create 2018/4/25
 * @since 1.0.0
 */
@Api(tags = "学员端-直播相关接口")
@RestController
@RequestMapping("/api/live")
public class liveStuController {

    private static final Logger LOG = LoggerFactory.getLogger(liveStuController.class);

    @Autowired
    LiveActivityClient liveActivityClient;

    @Autowired
    AccountClient accountClient;
    @Autowired
    FunctionDisplayConfigApiClients functionDisplayConfigApiClients;

    @GetMapping("/channelNo/get")
    @ApiOperation(value = "直播频道号获取", notes = "根据直播id")
    public Response getChannelNo(@RequestParam("id") Long id){
        Map<String,Object> data = new HashMap<>();
        data.put("liveChannelNo",liveActivityClient.getChannelNo(id));
        return Response.ok(data);
    }

    @GetMapping("/list")
    @ApiOperation(value = "app直播列表", notes = "app直播列表",response = PageLiveVo.class)
    public Response list(
            @ApiParam(name = "title", value = "直播主题", required = false)@RequestParam(value = "title",required = false) String title,
            @ApiParam(name = "pageNo", value = "跳转页数,默认第一页", required = true) @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize", value = "每页条数,默认20条", required = true) @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize) {
        RequestContext requestContext = ContextHolder.get();
        Page<PageLiveVo> page =  liveActivityClient.apiPageList(title,requestContext.getCompanyId(),requestContext.getSiteId(),
                requestContext.getRelationIds(),pageNo,pageSize);
        return Response.ok(page);
    }

    @GetMapping("/homePage/list")
    @ApiOperation(value = "app首页列表", notes = "app首页列表",response = PageLiveVo.class)
    public Response apiList(
            @ApiParam(name = "title", value = "直播主题", required = false)@RequestParam(value = "title",required = false) String title,
            @ApiParam(name = "pageNo", value = "跳转页数,默认第一页", required = true) @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize", value = "每页条数,默认20条", required = true) @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize) {
        RequestContext requestContext = ContextHolder.get();
        List<PageLiveVo> list =  liveActivityClient.apiList(title,requestContext.getCompanyId(),requestContext.getSiteId(),
                requestContext.getRelationIds(),pageNo,pageSize);
        return Response.ok(list);
    }




    @ApiOperation(value = "直播签名获得", notes = "直播签名获得",response = LiveAppIdVo.class)
    @PostMapping("/signature")
    public Response signature() {
        LiveAppIdVo liveAppIdVo = liveActivityClient.signature();
        return Response.ok(liveAppIdVo);
    }


    @GetMapping("/get")
    @ApiOperation(value = "获取直播详细信息", notes = "直播详细信息", response = LiveActivityVO.class)
    public Response list(@RequestParam("id") Long id) {
        LiveActivityResultVO liveActivity = liveActivityClient.get(id);
        return Response.ok(liveActivity);
    }

    @GetMapping("/get/playUrl")
    public Response playurl(
            @RequestParam(name = "channelId", required = true) String channelId
    ) {
        RequestContext requestContext = ContextHolder.get();
        String url = "https://live.polyv.cn/auth/" + channelId + "/pc-custom";
        String result;
        LOG.info("*******************请求的 channelId = {}",channelId);
        try {
            result = HttpUtil.doGet(url);
            LOG.info("[LiveStuController:playurl]执行结果result={}",result);
        } catch (Exception e) {
            //e.printStackTrace();
            LOG.info("发送结果异常{}",JSON.toJSONString(e));
            return Response.fail("直播频道不存在或已关闭");
        }

        String sign;
        String ts;
        String callbackUrl;
        try {
            JSONObject jsonObject = JSON.parseObject(result);
            sign = jsonObject.getString("sign");
            ts = jsonObject.getString("ts");
            callbackUrl = jsonObject.getString("url");
        } catch (Exception e) {
            LOG.info("解析结果异常{}",e);
            //e.printStackTrace();
            return Response.fail("直播频道响应异常");
        }

        Boolean vailResult = StringUtils.isEmpty(sign) || StringUtils.isEmpty(ts) || StringUtils.isEmpty(callbackUrl);
        if (vailResult) {
            return Response.fail("结果错误");
        }

        LiveActivityVO liveActivity = liveActivityClient.viewByChannelId(channelId);
        if (null != liveActivity) {
            StringBuilder vailSign = new StringBuilder();
            vailSign.append(liveActivity.getSecretKey());
            vailSign.append(channelId);
            vailSign.append(liveActivity.getSecretKey());
            vailSign.append(ts);
            String md5VailSign = getMD5(vailSign.toString());
            LOG.info("md5VailSign:"+md5VailSign);
            LOG.info("sign:"+sign);
            if (md5VailSign.equals(sign)) {

                AccountVO accountVO = accountClient.findById(requestContext.getAccountId());
                if (null != accountVO) {
                    long timeMillis = System.currentTimeMillis();
                    StringBuilder callBackSign = new StringBuilder();
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(channelId);
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(timeMillis);
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(accountVO.getName());


                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("sign", getMD5(callBackSign.toString()));
                    resultMap.put("ts", timeMillis);
                    resultMap.put("url", callbackUrl);
                    resultMap.put("userid",accountVO.getName());
                    resultMap.put("nickname", accountVO.getFullName());
                    resultMap.put("avatar", accountVO.getHeadPortrait()+"");
                    JSONObject resultJson = JSONObject.parseObject(JSONObject.toJSONString(resultMap));
                    return Response.ok(resultJson);
                }
            }
        }
        return Response.fail();
    }

    public static String getMD5(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            String md5=new BigInteger(1, md.digest()).toString(16);
            //BigInteger会把0省略掉，需补全至32位
            return fillMD5(md5);
        } catch (Exception e) {
            throw new RuntimeException("MD5加密错误:"+e.getMessage(),e);
        }
    }

    public static String fillMD5(String md5){
        return md5.length()==32?md5:fillMD5("0"+md5);
    }


    @GetMapping("/pc/pageList")
    @ApiOperation(value = "直播列表", notes = "直播列表", response = PageLiveVo.class)
    public Response pcPageList(@ApiParam(name = "title", value = "直播主题", required = false) @RequestParam(value = "title", required = false) String title,
                               @ApiParam(name = "ids", value = "ids里面可能有accountId 、部门Id", required = true)@RequestParam(name = "ids", required = false) List<Long> ids,
                               @ApiParam(name = "pageNo", value = "跳转页数,默认第一页", required = true) @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                               @ApiParam(name = "pageSize", value = "每页条数,默认15条", required = true) @RequestParam(name = "pageSize", defaultValue = "15") Integer pageSize
                             ) {

        Page<PageLiveVo> page = liveActivityClient.pcPageList(title,ids,pageNo,pageSize);
        Map<String,Integer> pageMap = new HashMap<>();
        pageMap.put("pageNo",page.getCurrent());
        pageMap.put("pageSize",page.getSize());
        pageMap.put("pageTotal",page.getPages());
        pageMap.put("pageRecords", page.getTotal());
        LOG.info("直播列表 返回参数：pageNo="+pageMap.get("pageNo")+"----pageSize="+pageMap.get("pageSize")+"----pageTotal="+pageMap.get("pageTotal"));
        return Response.ok(page,pageMap);
    }

    /**
     * 根据频道号，返回url
     * @param channelId
     * @return
     */
    @GetMapping("/pc/get/playUrl")
    @ApiOperation(value = "根据频道号，返回url")
    public Response pcPlayurl(@ApiParam(value = "channelId")
            @RequestParam(name = "channelId", required = true) String channelId) {
        RequestContext requestContext = ContextHolder.get();
        String url = "https://live.polyv.cn/auth/" + channelId + "/pc-custom";
        String result;
        LOG.info("*******************请求的 channelId = {}",channelId);
        try {
            result = HttpUtil.doGet(url);
        } catch (Exception e) {
            LOG.info("发送结果异常{}",e);
            return Response.fail(Constants.LIVE_MSG_CHANNEL_NOT_EXIST_OR_CLOSED.getCode().toString(),Constants.LIVE_MSG_CHANNEL_NOT_EXIST_OR_CLOSED.getName());
        }

        String sign;
        String ts;
        String callbackUrl;
        try {
            JSONObject jsonObject = JSON.parseObject(result);
            sign = jsonObject.getString("sign");
            ts = jsonObject.getString("ts");
            callbackUrl = jsonObject.getString("url");
        } catch (Exception e) {
            LOG.info("解析结果异常{}",e);
            //e.printStackTrace();
            return Response.fail(Constants.LIVE_MSG_CHANNEL_RESPONSE_EXCEPTION.getCode().toString(),Constants.LIVE_MSG_CHANNEL_RESPONSE_EXCEPTION.getName());
        }

        Boolean vailResult = StringUtils.isEmpty(sign) || StringUtils.isEmpty(ts) || StringUtils.isEmpty(callbackUrl);
        if (vailResult) {
            return Response.fail(Constants.LIVE_MSG_CHANNEL_RESPONSE_EXCEPTION.getCode().toString(),Constants.LIVE_MSG_CHANNEL_RESPONSE_EXCEPTION.getName());
        }

        LiveActivityVO liveActivity = liveActivityClient.viewByChannelId(channelId);
        if (null != liveActivity) {
            StringBuilder vailSign = new StringBuilder();
            vailSign.append(liveActivity.getSecretKey());
            vailSign.append(channelId);
            vailSign.append(liveActivity.getSecretKey());
            vailSign.append(ts);
            String md5VailSign = getMD5(vailSign.toString());
            LOG.info("md5VailSign:"+md5VailSign);
            LOG.info("sign:"+sign);
            if (md5VailSign.equals(sign)) {

                AccountVO accountVO = accountClient.findById(requestContext.getAccountId());
                if (null != accountVO) {
                    Long currentTimeMillis = System.currentTimeMillis();
                    StringBuilder callBackSign = new StringBuilder();
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(channelId);
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(currentTimeMillis);
                    callBackSign.append(liveActivity.getSecretKey());
                    callBackSign.append(accountVO.getName());


                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("sign", getMD5(callBackSign.toString()));
                    resultMap.put("ts", currentTimeMillis);
                    resultMap.put("url", callbackUrl);
                    resultMap.put("userid",accountVO.getName());
                    resultMap.put("nickname", accountVO.getFullName());
                    resultMap.put("avatar", accountVO.getHeadPortrait()+"");
                    JSONObject resultJson = JSONObject.parseObject(JSONObject.toJSONString(resultMap));
                    return Response.ok(resultJson);
                }
            }
        }
        return Response.fail(Constants.LIVE_MSG_CHANNEL_NOT_EXIST_OR_CLOSED.getCode().toString(),Constants.LIVE_MSG_CHANNEL_NOT_EXIST_OR_CLOSED.getName());
    }

    @GetMapping("/review/list")
    @ApiOperation(value = "获取直播回放列表")
    public BizResponse<Page<LiveReplayVo>> liveReviewList(LiveReleaseReviewReq reviewReq) {
        RequestContext context = ContextHolder.get();
        reviewReq.setRequestContext(context);
        return BizResponse.ok(liveActivityClient.getReleaseReplayList(reviewReq));
    }

    @GetMapping("/review/switch/on/live/list")
    @ApiOperation(value = "查询有直播回放的直播间列表")
    public BizResponse<Page<LiveTitleVo>> haveReviewLiveList(LiveReleaseReviewReq req) {
        RequestContext context = ContextHolder.get();
        req.setRequestContext(context);
        return BizResponse.ok(liveActivityClient.getHasReplayLiveList(req));
    }

    @GetMapping("/reviews/get")
    @ApiOperation(value = "根据直播间查询直播回放")
    public BizResponse<List<LiveReplayVo>> reviewsList(@RequestBody LiveReviewsVo liveReviewsVo) {

        return liveActivityClient.reviewsList(liveReviewsVo);
    }

    @GetMapping("/review/one/get")
    @ApiOperation(value = "查询直播回放详情")
    public BizResponse<LiveReplayVo> getReview(@RequestParam(name = "replayId") Long replayId) {
        return liveActivityClient.getReview(replayId);
    }

    @GetMapping("/show/config/status/get")
    @ApiOperation(value = "查询直播回放显示配置按钮状态")
    public BizResponse<Boolean> getLiveShowStatus() {
        // 查询直播回放显示配置按钮状态 true:开启；false:关闭
        RequestContext context = ContextHolder.get();
        Long siteId = context.getSiteId();
        List<FunctionDisplayConfigVo> functionDisplayConfigVoList = functionDisplayConfigApiClients.getBySiteId(siteId);
        if (null == functionDisplayConfigVoList || functionDisplayConfigVoList.isEmpty() ){
            LOG.info("查询直播回放显示配置按钮状态列表为空,siteId = {}",siteId);
            return BizResponse.ok(true);
        }
        for (FunctionDisplayConfigVo configVo : functionDisplayConfigVoList) {
            String functionType = configVo.getFunctionType();
            if (FunctionTypeCode.LIVEREPLAY.getCode().equals(functionType)){
                Boolean showDisplay = configVo.getShowDisplay();
                if (null == showDisplay){
                    LOG.warn("查询直播回放显示配置按钮状态为空,siteId = {},showDisplay={}",siteId,showDisplay);
                    return BizResponse.ok(true);
                }
                return BizResponse.ok(configVo.getShowDisplay());
            }
        }
        return BizResponse.ok(true);
    }



}
