package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.UserOrderDao;
import com.yonge.cooleshow.biz.dal.dao.VideoLessonGroupDao;
import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.dao.VideoLessonPurchaseRecordDao;
import com.yonge.cooleshow.biz.dal.enums.*;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import com.yonge.toolset.utils.obj.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * VideoLessonPurchaseRecordService服务实现类
 *
 * @author yzp
 * @version v1.0
 * @date 2022-03-26 00:01:38
 **/
@Service
public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLessonPurchaseRecordDao, VideoLessonPurchaseRecord> implements VideoLessonPurchaseRecordService {

    private final static Logger log = LoggerFactory.getLogger(VideoLessonPurchaseRecordServiceImpl.class);

    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private VideoLessonPurchaseRecordDao videoLessonPurchaseRecordDao;
    @Autowired
    private VideoLessonGroupDao videoLessonGroupDao;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private UserOrderDao userOrderDao;
    @Autowired
    private SysMessageService sysMessageService;
    @Autowired
    private UserOrderService userOrderService;

    public VideoLessonPurchaseRecordDao getDao() {
        return videoLessonPurchaseRecordDao;
    }

    /**
     * @Description: 购买视频课
     * @Author: cy
     * @Date: 2022/4/24
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<OrderCreateRes> buyVideoCourse(OrderReq.OrderReqInfo orderReqInfo) {
        log.info("buyVideoCourse  param:{}", JSON.toJSONString(orderReqInfo));
        Long studentId = orderReqInfo.getUserId();
        String orderNo = orderReqInfo.getOrderNo();

        //校验学生信息
        getSysUser(studentId);

        ObjectMapper objectMapper = new ObjectMapper();
        VideoLessonPurchaseRecord purchaseRecord = objectMapper.convertValue(orderReqInfo.getBizContent(), VideoLessonPurchaseRecord.class);

        //校验视频课信息
        Long groupId = purchaseRecord.getVideoLessonGroupId();
        VideoLessonGroup lessonGroup = videoLessonGroupDao.selectById(groupId);
        if (lessonGroup == null) {
            throw new BizException("课程组不存在!");
        }

        //校验课程是否购买
        VideoLessonPurchaseRecord isAlreadyBuy = videoLessonPurchaseRecordDao.selectOne(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
                .eq(VideoLessonPurchaseRecord::getStudentId, studentId)
                .eq(VideoLessonPurchaseRecord::getVideoLessonGroupId, groupId));
        if (!ObjectUtil.isEmpty(isAlreadyBuy)) {
            throw new BizException("已购买过该课程，或存在该课程未完成订单");
        }

        purchaseRecord.setOrderNo(orderNo);
        purchaseRecord.setStudentId(studentId);
        purchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
        purchaseRecord.setOriginalPrice(lessonGroup.getLessonPrice());//原价
        purchaseRecord.setExpectPrice(lessonGroup.getLessonPrice());//预计价格
        purchaseRecord.setPayMoney(orderReqInfo.getActualPrice());
        videoLessonPurchaseRecordDao.insert(purchaseRecord);

        OrderCreateRes orderCreateRes = new OrderCreateRes();
        orderCreateRes.setRes(true);
        orderCreateRes.setMerchId(lessonGroup.getTeacherId());
        orderCreateRes.setBizId(groupId);
        orderCreateRes.setOriginalPrice(lessonGroup.getLessonPrice());//原价
        orderCreateRes.setExpectPrice(lessonGroup.getLessonPrice());//预计价格
        orderCreateRes.setActualPrice(purchaseRecord.getPayMoney());//实际价格
        orderCreateRes.setGoodNum(lessonGroup.getLessonCount());
        orderCreateRes.setGoodType(GoodTypeEnum.VIDEO);
        HttpResponseResult<OrderCreateRes> httpResponseResult = new HttpResponseResult<>();
        httpResponseResult.setData(orderCreateRes);
        log.info("buyVideoCourse  return {}", httpResponseResult);
        return httpResponseResult;
    }

    /**
     * @Description: 购买视频课-成功-回调
     * @Author: cy
     * @Date: 2022/4/24
     */
    @Transactional(rollbackFor = Exception.class)
    public void buyVideoCourseSuccess(UserOrderDetailVo orderParam) {
        log.info("buyVideoCourseSuccess  param:{}", JSON.toJSONString(orderParam));
        String orderNo = orderParam.getOrderNo();
        VideoLessonPurchaseRecord purchaseRecord = videoLessonPurchaseRecordDao.selectOne(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
                .eq(VideoLessonPurchaseRecord::getOrderNo, orderNo));
        if (purchaseRecord == null) {
            throw new BizException("课程组购买记录不存在!");
        }

        //查询订单状态
        UserOrder userOrder = userOrderDao.selectOne(Wrappers.<UserOrder>lambdaQuery()
                .eq(UserOrder::getOrderNo, orderNo));
        if (userOrder == null) {
            throw new BizException("订单不存在!");
        }
        //修改支付状态
        videoLessonPurchaseRecordDao.updateStatus(orderNo, OrderStatusEnum.PAID.getCode());
        //查询组信息
        VideoLessonGroup lessonGroup = videoLessonGroupDao.selectById(purchaseRecord.getVideoLessonGroupId());
        //记录流水
        addTeacherAccount(orderParam, lessonGroup);
        videoSend(lessonGroup.getTeacherId(), purchaseRecord.getStudentId(), lessonGroup);
    }

    /**
     * 记录老师账户记录
     *
     * @param userOrderDetailVo
     * @param lessonGroup
     */
    private void addTeacherAccount(UserOrderDetailVo userOrderDetailVo, VideoLessonGroup lessonGroup) {
        //获取账期时间
        Date accountPeriodTime = userOrderService.getAccountPeriodTime(userOrderDetailVo);

        //查询视频课服务费
        BigDecimal liveServiceRate = new BigDecimal(sysConfigService.findConfigValue(SysConfigConstant.VIDEO_LESSON_SERVICE_FEE))
                .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
        //支付金额
        BigDecimal expectPrice = userOrderDetailVo.getExpectPrice();
        //服务费
        BigDecimal serviceFeeAmount = expectPrice.multiply(liveServiceRate).setScale(2, RoundingMode.HALF_UP);
        //老师入账金额
        BigDecimal transAmount = expectPrice.subtract(serviceFeeAmount).setScale(2, RoundingMode.HALF_UP);
        //插入老师账户变更记录-老师预收
        userAccountService.accountRecord(
                new UserAccountRecordDto(userOrderDetailVo.getMerchId(), PostStatusEnum.WAIT, transAmount, InOrOutEnum.IN,
                        AccountBizTypeEnum.VIDEO, lessonGroup.getId(), lessonGroup.getLessonName(), userOrderDetailVo.getOrderNo(), userOrderDetailVo.getUserId(), accountPeriodTime));
    }

    /**
     * @Description: 购买视频课-失败-回调
     * @Author: cy
     * @Date: 2022/4/24
     */
    @Transactional(rollbackFor = Exception.class)
    public void buyVideoCourseFailed(UserOrderDetailVo orderParam) {
        String orderNo = orderParam.getOrderNo();

        VideoLessonPurchaseRecord videoGroup = videoLessonPurchaseRecordDao.selectOne(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
                .eq(VideoLessonPurchaseRecord::getOrderNo, orderNo));
        if (videoGroup == null) {
            throw new BizException("课程组不存在!");
        }

        //删除video_lesson_purchase_record数据
        videoLessonPurchaseRecordDao.delete(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
                .eq(VideoLessonPurchaseRecord::getOrderNo, orderNo));
        log.info("buyVideoCourseFailed ok");
    }

    /**
     * 获取用户信息
     */
    private SysUser getSysUser(Long userId) {
        return Optional.ofNullable(userId)
                .map(sysUserFeignService::queryUserById)
                .orElseThrow(() -> new BizException("用户不存在"));
    }

    /**
     * @Description: 购买视频课消息推送
     * @Author: cy
     * @Date: 2022/5/6
     */
    public void videoSend(Long teacherId, Long studentId, VideoLessonGroup lesson) {
        //查询老师&学生信息
        SysUser teacher = sysUserFeignService.queryUserById(teacherId);
        SysUser student = sysUserFeignService.queryUserById(studentId);

        //消息接收者(Key:用户编号 value:消息接收对象)
        Map<Long, String> teacherReceivers = new HashMap<>();
        teacherReceivers.put(teacherId, teacher.getPhone());
        Map<Long, String> studentReceivers = new HashMap<>();
        studentReceivers.put(studentId, student.getPhone());
        Map<Long, String> studentSMS = new HashMap<>();
        studentSMS.put(studentId, student.getPhone());

        //老师端-学生购买视频课
        try {
            if (lesson.getLessonPrice().compareTo(BigDecimal.ZERO) >0) {
                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_BUY_VIDEO,
                                                   teacherReceivers, null, 0, null, ClientEnum.TEACHER.getCode(),
                                                   student.getUsername(), lesson.getLessonName());
                log.info("send success {}", MessageTypeEnum.STUDENT_BUY_VIDEO);
            }
        } catch (Exception e) {
            log.error("send fail {}", MessageTypeEnum.STUDENT_BUY_VIDEO);
            e.printStackTrace();
        }

        //学生端-购买视频课
        String payType = "";
        if (lesson.getLessonPrice().compareTo(BigDecimal.ZERO) >0) {
            payType = "购买";
        } else {
            payType = "领取";
        }
        try {


            String url = sysMessageService.selectConfigUrl(MessageTypeEnum.VIDEO_BUY.getCode(), lesson.getId());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.VIDEO_BUY,
                    studentReceivers, null, 0, url, ClientEnum.STUDENT.getCode(),payType,
                    teacher.getUsername(), lesson.getLessonName());
            log.info("send success {}", MessageTypeEnum.VIDEO_BUY);
        } catch (Exception e) {
            log.error("send fail {}", MessageTypeEnum.VIDEO_BUY);
            e.printStackTrace();
        }

        //学生端-购买视频课(短信)
        try {
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIDEO_BUY,
                    studentSMS, null, 0, null, null,payType,
                    teacher.getUsername(), lesson.getLessonName());
            log.info("sms send success {}", MessageTypeEnum.SMS_VIDEO_BUY);
        } catch (Exception e) {
            log.error("sms send fail {}", MessageTypeEnum.SMS_VIDEO_BUY);
            e.printStackTrace();
        }
    }
}