package com.sqx.modules.course.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.ApiAccessLimitUtil;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.app.utils.JwtUtils;
import com.sqx.modules.common.dao.CommonInfoDao;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.course.dao.CourseCollectDao;
import com.sqx.modules.course.dao.CourseDao;
import com.sqx.modules.course.dao.CourseDetailsDao;
import com.sqx.modules.course.dao.CourseUserDao;
import com.sqx.modules.course.entity.Course;
import com.sqx.modules.course.entity.CourseCollect;
import com.sqx.modules.course.entity.CourseDetails;
import com.sqx.modules.course.entity.CourseUser;
import com.sqx.modules.course.service.CourseDetailsService;
import com.sqx.modules.course.vo.CourseDetailsIn;
import com.sqx.modules.orders.dao.OrdersDao;
import com.sqx.modules.orders.service.OrdersService;
import com.sqx.modules.redisService.impl.RedisServiceImpl;
import com.sqx.modules.utils.EasyPoi.ExcelUtils;
import com.sqx.modules.utils.HttpClientUtil;
import com.sqx.modules.utils.SenInfoCheckUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class CourseDetailsServiceImpl extends ServiceImpl<CourseDetailsDao, CourseDetails> implements CourseDetailsService {

    @Autowired
    private CourseDao courseDao;
    @Autowired
    private CourseCollectDao courseCollectDao;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private CourseUserDao courseUserDao;
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private UserService userService;
    @Autowired
    private OrdersDao ordersDao;
    @Autowired
    private CommonInfoDao commonInfoDao;
    @Autowired
    private RedisServiceImpl redisServiceImpl;
    @Autowired
    private CourseDetailsDao courseDetailsDao;


    @Override
    public Result insert(CourseDetails courseDetails) {
        if (courseDetails.getGoodNum() == null) {
            courseDetails.setGoodNum(0);
        }
        baseMapper.insert(courseDetails);
        return Result.success();
    }

    @Override
    public Result updateCourseDetails(CourseDetails courseDetails) {
        baseMapper.updateById(courseDetails);
        return Result.success();
    }

    @Override
    public Result deleteCourseDetails(String ids) {
        String[] split = ids.split(",");
        baseMapper.deleteCourseDetails(split);
        return Result.success();
    }

    /**
     * 校验用户是否达到免费播放购买次数
     *
     * @param userId 用户id
     * @return true 可观看
     */
    private boolean checkFreeWatchPayCount(Long userId) {
        Boolean isExpire = redisServiceImpl.getFreeWatchTimeIsExpire(userId);
        if (isExpire == null) {
            Integer count = ordersDao.countPayOrderByDay(userId);
            CommonInfo needCountCommonInfo = commonInfoDao.selectOne(new LambdaQueryWrapper<CommonInfo>()
                    .eq(CommonInfo::getType, 916));
            CommonInfo freeTimeCommonInfo = commonInfoDao.selectOne(new LambdaQueryWrapper<CommonInfo>()
                    .eq(CommonInfo::getType, 917));
            if (needCountCommonInfo == null || freeTimeCommonInfo == null
                    || StrUtil.isBlank(needCountCommonInfo.getValue()) || StrUtil.isBlank(freeTimeCommonInfo.getValue())) {
                log.warn("系统未配置全免次数或时间");
                return false;
            }

            // 购买次数超过，设置redis标识
            if (count >= Integer.parseInt(needCountCommonInfo.getValue())) {
                redisServiceImpl.setFreeWatchTime(userId, Integer.parseInt(freeTimeCommonInfo.getValue()) * 60, false);
                // 触发计时
                redisServiceImpl.getFreeWatchTimeIsExpire(userId);
                isExpire = false;
            } else {
                isExpire = true;
            }
        }
        return !isExpire;

    }

    private void setCourseView(Course course) {
        if (ApiAccessLimitUtil.isAccessAllowed("setCourseView:" + course.getCourseId(), "updateAuthCertInfo", 1, 600)) {
            int courseViewCount = redisServiceImpl.getCourseWeekViewCount(course.getCourseId());
            course.setWeekView(courseViewCount);
            courseDao.updateById(course);
        }
    }

    @Override
    public Result selectCourseDetailsById(Long id, String token, String courseDetailsId) {
        Course bean = courseDao.selectById(id);
        if (bean.getViewCounts() == null) {
            bean.setViewCounts(1);
        } else {
            bean.setViewCounts(bean.getViewCounts() + 1);
        }
        courseDao.updateById(bean);

        setCourseView(bean);

        Long userId = null;
        if (StringUtils.isNotEmpty(token)) {
            Claims claims = jwtUtils.getClaimByToken(token);
            if (claims != null && !jwtUtils.isTokenExpired(claims.getExpiration())) {
                userId = Long.parseLong(claims.getSubject());
            }
        }
        bean.setIsCollect(0);
        if (userId != null) {
            bean.setIsCollect(courseCollectDao.selectCount(new QueryWrapper<CourseCollect>().eq("user_id", userId).eq("classify", 1).eq("course_id", bean.getCourseId())));
            UserEntity userEntity = userService.selectUserById(userId);
            //查询用户是否购买了整集
            CourseUser courseUser = courseUserDao.selectCourseUser(id, userId);
            // 每天购买超过上限，获得免费时间段资格
            boolean freeWatch = checkFreeWatchPayCount(userId);
            if (freeWatch || courseUser != null || (userEntity != null && userEntity.getMember() != null && userEntity.getMember() == 2)) {
                bean.setListsDetail(baseMapper.findByCourseId(id, userId));
            } else {
                List<CourseDetails> list = baseMapper.findByCourseIdNotUrl(id, userId);
                bean.setListsDetail(list);
                //查询用户是否单独购买了集
                List<CourseUser> courseUsers = courseUserDao.selectCourseUserList(id, userId);
                if (courseUsers.size() > 0) {
                    for (CourseUser courseUser1 : courseUsers) {
                        for (CourseDetails courseDetails : bean.getListsDetail()) {
                            if (courseUser1.getCourseDetailsId().equals(courseDetails.getCourseDetailsId())) {
                                CourseDetails courseDetails1 = baseMapper.selectById(courseDetails.getCourseDetailsId());
                                courseDetails.setVideoUrl(courseDetails1.getVideoUrl());
                            }
                        }
                    }
                }
            }
            /*for (CourseDetails courseDetails:bean.getListsDetail()){
                courseDetails.setIsCollect(courseCollectDao.selectCount(new QueryWrapper<CourseCollect>()
                        .eq("user_id", userId).eq("course_details_id", courseDetails.getCourseDetailsId()).eq("classify",1)));
                courseDetails.setIsGood(courseCollectDao.selectCount(new QueryWrapper<CourseCollect>()
                        .eq("user_id", userId).eq("course_details_id", courseDetails.getCourseDetailsId()).eq("classify",2)));
            }*/

        } else {
            bean.setListsDetail(baseMapper.findByCourseIdNotUrl(id, null));
        }
        if (courseDetailsId != null) {
            if (bean.getListsDetail().size() > 0) {
                for (CourseDetails courseDetails : bean.getListsDetail()) {
                    if (courseDetails.getCourseDetailsId().equals(Long.parseLong(courseDetailsId))) {
                        //微信内
                        String url = "https://api.weixin.qq.com/wxa/sec/vod/getmedialink?access_token=" + SenInfoCheckUtil.getMpToken();
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("media_id", courseDetails.getWxCourseDetailsId());
                        jsonObject.put("t", (new Date().getTime() / 1000) + 7200);
                        String s = HttpClientUtil.doPostJson(url, jsonObject.toJSONString());
                        JSONObject jsonObject1 = JSONObject.parseObject(s);
                        String errcode = jsonObject1.getString("errcode");
                        if (!"0".equals(errcode)) {
                            return Result.error("获取微信播放链接失败：" + jsonObject1.getString("errmsg"));
                        }
                        JSONObject media_info = jsonObject1.getJSONObject("media_info");
                        String mp4_url = media_info.getString("mp4_url");
                        courseDetails.setWxUrl(mp4_url);
                        break;
                    }
                }
            }
        }
        CourseCollect courseCollect = courseCollectDao.selectOne(Wrappers.<CourseCollect>lambdaQuery()
                .select(CourseCollect::getCourseDetailsId)
                .eq(CourseCollect::getCourseId, id)
                .eq(CourseCollect::getClassify, 3)
                .eq(CourseCollect::getUserId, userId)
                .orderByDesc(CourseCollect::getUpdateTime).last("limit 1")
        );
        if (courseCollect != null && courseCollect.getCourseDetailsId() != null) {
            CourseDetails courseDetails = courseDetailsDao.selectById(courseCollect.getCourseDetailsId());
            if (courseDetails != null) {
                bean.setCourseDetailsId(courseDetails.getCourseDetailsId());
                bean.setCourseDetailsName(courseDetails.getCourseDetailsName());
                bean.setCourseDetailsCount(courseDetails.getCourseDetailsCount());
            }
        }else{
            //默认取第一集
            CourseDetails courseDetails = courseDetailsDao.selectOne(Wrappers.<CourseDetails>lambdaQuery().eq(CourseDetails::getCourseId, id)
                    .orderByAsc(CourseDetails::getSort).last(" limit 1"));
            if (courseDetails != null) {
                bean.setCourseDetailsId(courseDetails.getCourseDetailsId());
                bean.setCourseDetailsName(courseDetails.getCourseDetailsName());
                bean.setCourseDetailsCount(courseDetails.getCourseDetailsCount());
            }
        }
        return Result.success().put("data", bean);
    }

    @Override
    public Result selectCourseDetailsList(Integer page, Integer limit, String token, String randomNum, Integer wxShow, Integer dyShow) {
        PageHelper.startPage(page, limit);
        Long userId = null;
        if (StringUtils.isNotEmpty(token)) {
            Claims claims = jwtUtils.getClaimByToken(token);
            if (claims != null && !jwtUtils.isTokenExpired(claims.getExpiration())) {
                userId = Long.parseLong(claims.getSubject());
            }
        }
        if(!Validator.isNumber(randomNum)){
            throw new SqxException("随机码必须是数字");
        };
        List<CourseDetails> list = baseMapper.selectCourseDetailsList(randomNum, wxShow, dyShow);
        PageInfo<CourseDetails> pageInfo = new PageInfo<>(list);

        if (userId != null) {
            List<CourseDetails> records = pageInfo.getList();
            for (CourseDetails courseDetails : records) {
                courseDetails.setIsCollect(courseCollectDao.selectCount(new QueryWrapper<CourseCollect>()
                        .eq("user_id", userId).eq("course_details_id", courseDetails.getCourseDetailsId()).eq("classify", 1)));
                courseDetails.setIsGood(courseCollectDao.selectCount(new QueryWrapper<CourseCollect>()
                        .eq("user_id", userId).eq("course_details_id", courseDetails.getCourseDetailsId()).eq("classify", 2)));
                courseDetails.setCourse(courseDao.selectById(courseDetails.getCourseId()));
                courseDetails.setTitle(courseDetails.getCourse().getTitle());
                courseDetails.setCourseDetailsCount(baseMapper.selectCount(new QueryWrapper<CourseDetails>().eq("course_id", courseDetails.getCourseId())));
            }
        }
        return Result.success().put("data", PageUtils.page(pageInfo));
    }

    @Override
    public Result courseDetailsListExcelIn(MultipartFile file, Long courseId) throws IOException {
        Course course = courseDao.selectById(courseId);
        if (course == null) {
            return Result.error("所选剧不存在");
        }
        List<CourseDetailsIn> courseDetailsList = ExcelUtils.importExcel(file, 2, 1, CourseDetailsIn.class);
        if (CollectionUtils.isEmpty(courseDetailsList)) {
            return Result.error("Excel数据为空，excel转化失败！");
        }
        //当前行索引（Excel的数据从第几行开始,就填写几）
        int index = 4;
        //失败条数
        int repeat = 0;
        //成功条数
        int successIndex = 0;
        //空数据
        int emptyCount = 0;
        for (CourseDetailsIn courseDetailsIn : courseDetailsList) {
            if (courseDetailsIn.getCourseDetailsName() == null) {
                emptyCount++;
                continue;
            }
            if (courseDetailsIn.getIsPrice() != 2) {
                if (courseDetailsIn.getPrice() == null || courseDetailsIn.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
                    return Result.error("第【" + index + "】行数据为收费,但并没有设置价格");
                }
            }
            index++;
            Integer count = baseMapper.selectCount(new QueryWrapper<CourseDetails>().eq("course_details_name", courseDetailsIn.getCourseDetailsName()).eq("course_id", courseId));
            if (count <= 0) {
                CourseDetails courseDetails = new CourseDetails();
                courseDetails.setCourseId(courseId);
                courseDetails.setCreateTime(DateUtils.format(new Date()));
                courseDetails.setViewCount(0L);
                courseDetails.setPlayCompleteCount(0L);
                BeanUtils.copyProperties(courseDetailsIn, courseDetails);
                int result = baseMapper.insert(courseDetails);
                if (result > 0) {
                    successIndex++;
                } else {
                    repeat++;
                }
            }

        }
        return Result.success("导入成功,共新增【" + successIndex + "】条,失败【" + (courseDetailsList.size() - successIndex - emptyCount) + "】条,其中过滤重复数据【" + repeat + "】条");
    }


}
