/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.bizvideo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.bizvideo.entity.BizVideo;
import vip.xiaonuo.biz.modular.bizvideo.mapper.BizVideoMapper;
import vip.xiaonuo.biz.modular.bizvideo.param.BizVideoAddParam;
import vip.xiaonuo.biz.modular.bizvideo.param.BizVideoEditParam;
import vip.xiaonuo.biz.modular.bizvideo.param.BizVideoIdParam;
import vip.xiaonuo.biz.modular.bizvideo.param.BizVideoPageParam;
import vip.xiaonuo.biz.modular.bizvideo.service.BizVideoService;
import vip.xiaonuo.dev.api.DevConfigApi;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 视频配置Service接口实现类
 *
 * @author fanzherong
 * @date  2025/02/17 10:05
 **/
@Service
public class BizVideoServiceImpl extends ServiceImpl<BizVideoMapper, BizVideo> implements BizVideoService {

    @Resource
    private DevConfigApi devConfigApi;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Page<BizVideo> page(BizVideoPageParam bizVideoPageParam) {
        QueryWrapper<BizVideo> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isNotEmpty(bizVideoPageParam.getAreaName())){
            queryWrapper.eq("bv.video_area",bizVideoPageParam.getAreaName());
        }
        queryWrapper.eq("bv.delete_flag","NOT_DELETE");
        return this.getBaseMapper().getPageList(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public Page<BizVideo> queryVideo(BizVideoPageParam bizVideoPageParam) {
        QueryWrapper<BizVideo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("buv.delete_flag","NOT_DELETE");
        if(ObjectUtil.isNotEmpty(bizVideoPageParam.getAreaName())){
            queryWrapper.eq("ba.id",bizVideoPageParam.getAreaName());
        }
        // 判断当前是否视频监察员角色
        if(StpLoginUserUtil.getLoginUser().getRoleCodeList().contains("54ahw3iob9")){
            queryWrapper.eq("buv.user_id",StpLoginUserUtil.getLoginUser().getId());
        }else{
           return new Page<>();
        }
        return this.getBaseMapper().queryPageList(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public void add(BizVideoAddParam bizVideoAddParam) {
        checkParam(bizVideoAddParam.getVideoArea(),bizVideoAddParam.getSerial(),bizVideoAddParam.getChannelNo());
        BizVideo bizVideo = BeanUtil.toBean(bizVideoAddParam, BizVideo.class);
        this.save(bizVideo);
    }

    public void checkParam(String videoArea,String serial,Integer channelNo){
        long count = this.count(new QueryWrapper<BizVideo>().lambda().eq(BizVideo::getVideoArea, videoArea).
                eq(BizVideo::getSerial, serial).
                eq(BizVideo::getChannelNo, channelNo));
        if(count>0){
            throw new CommonException("区域已经添加过此设备号和通道号！");
        }
    }

    @Override
    public void edit(BizVideoEditParam bizVideoEditParam) {
        BizVideo bizVideo = this.queryEntity(bizVideoEditParam.getId());
        if(!StringUtils.equals(bizVideo.getVideoArea(),bizVideoEditParam.getVideoArea())){
            checkParam(bizVideoEditParam.getVideoArea(),bizVideoEditParam.getSerial(),bizVideoEditParam.getChannelNo());
        }
        BeanUtil.copyProperties(bizVideoEditParam, bizVideo);
        this.updateById(bizVideo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizVideoIdParam> bizVideoIdParamList) {
        // 执行删除
        this.removeBatchByIds(CollStreamUtil.toList(bizVideoIdParamList, BizVideoIdParam::getId));
    }

    @Override
    public BizVideo detail(BizVideoIdParam bizVideoIdParam) {
        return this.queryEntity(bizVideoIdParam.getId());
    }

    @Override
    public BizVideo queryEntity(String id) {
        BizVideo bizVideo = this.getById(id);
        if(ObjectUtil.isEmpty(bizVideo)) {
            throw new CommonException("视频配置不存在，id值为：{}", id);
        }
        return bizVideo;
    }

    @Override
    public Map<String, Object> getAppkey() {
        String appKey = devConfigApi.getValueByKey("AppKey");
        String secret = devConfigApi.getValueByKey("Secret");
        Map<String,Object> map = Maps.newHashMap();
        map.put("appKey",appKey);
        map.put("secret",secret);
        return map;
    }

    @Override
    public Map<String, Object> getVideoUrl(BizVideoIdParam bizVideoIdParam) {
        Map<String,Object> map = Maps.newHashMap();
        String accessToken = null;
        //获取到accessToken
        if(ObjectUtil.isNotEmpty(redisTemplate.opsForValue().get(bizVideoIdParam.getId()+"_accessToken")))
            accessToken = (String) redisTemplate.opsForValue().get(bizVideoIdParam.getId()+"_accessToken");
        else{
            String appKey = devConfigApi.getValueByKey("AppKey");
            String secret = devConfigApi.getValueByKey("Secret");
            //根据appKey和secret调用官方接口获取accessToken
            String result = HttpUtil.createPost("https://open.ys7.com/api/lapp/token/get?appKey=" + appKey + "&appSecret=" + secret).execute().body();
            JSONObject jsonObject = JSON.parseObject(result);
            if(StringUtils.equals(jsonObject.getString("code"),"200")){
                JSONObject data = JSON.parseObject(jsonObject.getString("data"));
                accessToken = data.getString("accessToken");
                redisTemplate.opsForValue().set(bizVideoIdParam.getId()+"_accessToken",data.get("accessToken"));
                redisTemplate.expireAt(bizVideoIdParam.getId(),new Date((Long) data.get("expireTime")));
            }
        }
        if(ObjectUtil.isNotEmpty(accessToken)){
            BizVideo bizVideo = this.queryEntity(bizVideoIdParam.getId());
            //根据accessToken和序列号获取视频url
            String body = HttpUtil.createPost("https://open.ys7.com/api/lapp/v2/live/address/get?accessToken=" + accessToken + "&deviceSerial=" + bizVideo.getSerial() + "&channelNo=" + bizVideo.getChannelNo())
                    .execute().body();
            JSONObject jsonObject = JSON.parseObject(body);
            if(StringUtils.equals(jsonObject.getString("code"),"200")){
                JSONObject data = JSON.parseObject(jsonObject.getString("data"));
                map.put("url",data.getString("url"));
                map.put("id",data.getString("id"));
                map.put("code",jsonObject.getString("code"));
                map.put("accessToken",accessToken);
                return map;
            }else{
                map.put("code",jsonObject.getString("code"));
                map.put("msg",jsonObject.getString("msg"));
            }
        }else{
            map.put("code","500");
        }
        return map;
    }
}
