package cn.com.ty.lift.ud.question.service.impl;

import cn.com.ty.lift.ud.chat.mapper.ChatSessionMapper;
import cn.com.ty.lift.ud.chat.mapper.entity.LiftCaseEntity;
import cn.com.ty.lift.ud.chat.service.ILiftCaseService;
import cn.com.ty.lift.ud.question.controller.query.QuestionBankQuery;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionCollectDto;
import cn.com.ty.lift.ud.question.service.IQuestionOperateService;
import cn.com.ty.lift.ud.common.NotExamineDto;
import cn.com.ty.lift.ud.operation.mapper.entity.CommissionSettingEntity;
import cn.com.ty.lift.ud.operation.service.ICommissionSettingService;
import cn.com.ty.lift.ud.payment.mapper.entity.UserBillEntity;
import cn.com.ty.lift.ud.payment.service.IUserBillService;
import cn.com.ty.lift.ud.question.controller.query.QuestionBankAppQuery;
import cn.com.ty.lift.ud.question.mapper.QuestionBankMapper;
import cn.com.ty.lift.ud.question.mapper.entity.GiveMoneyDto;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionBankEntity;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionOperateEntity;
import cn.com.ty.lift.ud.question.service.IQuestionBankService;
import cn.com.ty.lift.ud.userCollect.mapper.entity.UserCollectDto;
import cn.com.ty.lift.ud.userCollect.mapper.entity.UserCollectEntity;
import cn.com.ty.lift.ud.userCollect.service.IUserCollectService;
import cn.com.ty.lift.ud.userInfo.mapper.entity.UserInfoEntity;
import cn.com.ty.lift.ud.userInfo.service.IUserInfoService;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 题库 -ServiceImpl
 *
 * @author Xson
 * @date 2020-04-25
 */
@Service
@Transactional
public class QuestionBankServiceImpl extends ServiceImpl<QuestionBankMapper, QuestionBankEntity>
    implements IQuestionBankService {

    public static final int EXAMINEFLAG = 1;

    @Autowired
    private QuestionBankMapper questionBankMapper;

    @Autowired
    private IUserCollectService iUserCollectService;

    @Autowired
    private IQuestionOperateService iQuestionOperateService;

    @Autowired
    private ICommissionSettingService iCommissionSettingService;

    @Autowired
    private IUserBillService iUserBillService;

    @Autowired
    private ILiftCaseService liftCaseService;
    @Autowired
    private ChatSessionMapper sessionMapper;

    @Autowired
    private IUserInfoService iUserInfoService;

    // private RedisUtil redis = ApplicationContextUtil.getBean(RedisUtil.class);

    /**
     * 批量上架或下架
     *
     * @param ids
     * @param status
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse updateByIds(List<Long> ids, Integer status) {
        for (Long id : ids) {
            //只有审核通过的才能上架或者下架
            QuestionBankEntity bankEntity = questionBankMapper.selectById(id);
            if(null != bankEntity && bankEntity.getExamineFlag() != 1){
                return RestResponse.fail("只有审核通过的题目才能上架或下架");
            }

            //上架
            QuestionBankEntity que = new QuestionBankEntity();
            que.setId(id);
            que.setStatuz(status);
            questionBankMapper.updateById(que);
        }
        return RestResponse.success(null,"操作成功");
    }

    /**
     * 置顶或者取消置顶
     *
     * @param id
     */
    @Override
    public void toUpOrDown(Long id, Integer flag) {
        // 修改当前问题的是否热门 hot_flag 为 1 热门 或者 0 普通
        questionBankMapper.toUpOrDown(id, flag);
    }

    /**
     * 审批通过，状态修改，默认3个月的有效期 审批不通过，发消息给用户
     *
     * @param neDto
     */
    @Override
    public RestResponse examineById(NotExamineDto neDto) {
        QuestionBankEntity questionBankEntity = questionBankMapper.selectById(neDto.getId());
        if (EXAMINEFLAG == neDto.getExamineFlag()) {
            questionBankMapper.examineById(neDto.getId());
            if(null != questionBankEntity && null != questionBankEntity.getLiftCaseId()) {
             // 修改诊单状态为 待评价
                liftCaseService.updateStatusById(questionBankEntity.getLiftCaseId(), 5);
            }
            return RestResponse.success(null, "审批通过");
        } else {
            // 修改状态为 驳回，并加上驳回理由
            questionBankMapper.updateInfoById(neDto.getId(), neDto.getNotExamineReason());
            if (null != questionBankEntity && null != questionBankEntity.getLiftCaseId()) {
                // 修改诊单状态为 待归档
                liftCaseService.updateStatusById(questionBankEntity.getLiftCaseId(), 4);
            }
            return RestResponse.fail(null, "审批驳回");
        }
    }

    /**
     * 后台分页查询
     *
     * @param query
     * @return
     */
    @Override
    public RestResponse selectByExample(QuestionBankQuery query) {
        IPage page = query.page();
        List<QuestionBankEntity> list = questionBankMapper.selectByQuery(query.condition(), query);
        page.setRecords(list);
        int total = questionBankMapper.countByQuery(query.condition());
        page.setTotal(total);
        return RestResponse.success(page, "Select successfully");
    }

    /**
     * app分页查询
     *
     * @param query
     * @return
     */
    @Override
    public RestResponse selectAppByExample(QuestionBankAppQuery query) {
        IPage page = query.page();
        List<QuestionBankEntity> list = questionBankMapper.selectAppByQuery(query.condition(), query);
        page.setRecords(list);
        int total = questionBankMapper.countAppByQuery(query.condition());
        page.setTotal(total);
        return RestResponse.success(page, "Select successfully");
    }

    /**
     * 点赞
     *
     * @param userId
     * @param questionId
     */
    @Override
    public void like(Long questionId, Long userId) {
        // 点赞数量加 1
        questionBankMapper.like(questionId);
        // 记录行为 question_operate
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(2);
        iQuestionOperateService.save(operateEntity);

    }

    /**
     * 收藏
     *
     * @param userId
     * @param questionId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void collect(Long questionId, Long userId) {
        // 收藏数量加 1
        questionBankMapper.collect(questionId);
        // 在我的收藏 user_collect 表中添加信息
        UserCollectDto userCollect = new UserCollectDto();
        userCollect.setUserId(userId);
        userCollect.setCollectType(1);
        userCollect.setInfoId(questionId);
        UserCollectEntity collect = iUserCollectService.isCollect(userCollect);
        // 不能重复收藏
        if (null == collect) {
            UserCollectEntity userCollectEntity = new UserCollectEntity();
            BeanUtils.copyProperties(userCollect, userCollectEntity);
            iUserCollectService.save(userCollectEntity);
        }
        // 在 题库操作表 question_operate 中添加信息
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(3);
        iQuestionOperateService.save(operateEntity);

    }

    /**
     * 浏览
     *
     * @param userId
     * @param questionId
     */
    @Override
    public void see(Long questionId, Long userId) {
        // 浏览数量加 1
        questionBankMapper.see(questionId);
        // 记录行为 question_operate
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(1);
        iQuestionOperateService.save(operateEntity);
    }

    /**
     * 打赏
     *
     * @param giveMoney
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void giveMoney(GiveMoneyDto giveMoney) {
        // todo 调用支付宝接口，支付成功后再进行下面的业务逻辑
        // 赏金
        BigDecimal reward = giveMoney.getReward();
        // 记录行为 question_operate
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(giveMoney.getUserId());
        operateEntity.setDataId(giveMoney.getId());
        operateEntity.setType(4);
        iQuestionOperateService.save(operateEntity);
        // 查询抽成设置中的题库抽成服务费
        RestResponse latestVersion = iCommissionSettingService.getLatestVersion();
        if (null != latestVersion) {
            CommissionSettingEntity data = (CommissionSettingEntity)latestVersion.getData();
            if (null != data) {
                BigDecimal questionCommission = data.getQuestionCommission();
                BigDecimal subtract = new BigDecimal("100").subtract(questionCommission);
                reward = reward.multiply(subtract).divide(new BigDecimal("100"));
            }
        }
        // 打赏数量加 1
        questionBankMapper.updateReward(giveMoney.getId(), BigDecimal.ZERO);
        // 新增专家账户流水
        QuestionBankEntity questionBankEntity = questionBankMapper.getById(giveMoney.getId());
        UserBillEntity userBillEntity = new UserBillEntity();
        userBillEntity.setAmount(reward);
        userBillEntity.setUserId(questionBankEntity.getExpert());
        userBillEntity.setType(2);
        // 查询最近一次的余额
        BigDecimal latestBalance = iUserBillService.getLatestBalance(questionBankEntity.getExpert());
        userBillEntity.setBalance(latestBalance.add(reward));
        //专家 user_info  余额修改
        if(null != questionBankEntity.getExpert()){
            UserInfoEntity uiEntity  = new UserInfoEntity();
            uiEntity.setUserId(questionBankEntity.getExpert());
            uiEntity.setBalance(latestBalance.add(reward));
            iUserInfoService.updateUser(uiEntity);
        }
        //todo 缺少流水号
        iUserBillService.save(userBillEntity);
        //新增打赏的人的流水
        BigDecimal latestUserBalance = iUserBillService.getLatestBalance(giveMoney.getUserId());
        UserBillEntity userEntity = new UserBillEntity();
        userEntity.setAmount(giveMoney.getReward());
        userEntity.setUserId(giveMoney.getUserId());
        userEntity.setType(1);
        userEntity.setBusinessType(2);
        userEntity.setBalance(latestUserBalance);
        //todo 缺少流水号
        iUserBillService.save(userEntity);

    }

    /**
     * 根据id查详情
     *
     * @param id
     * @return
     */
    @Override
    public QuestionBankEntity selectById(Long id) {
        //查询详情
        QuestionBankEntity entity = questionBankMapper.getById(id);
        return entity;
    }

    /**
     * 查询题目详情 - app
     *
     * @param questionId
     *            问题ID
     * @param userId
     *            用户ID
     * @return
     */
    @Override
    public QuestionBankEntity selectInfo(Long questionId, Long userId) {
        // 根据id查详情
        QuestionBankEntity entity = questionBankMapper.getById(questionId);
        entity.setIsTip(0);
        // 题目浏览量加1
        see(questionId, userId);
        // 查询是否收藏过
        QuestionOperateEntity favoriteEntity = new QuestionOperateEntity();
        favoriteEntity.setDataId(questionId);
        favoriteEntity.setType(3);
        favoriteEntity.setUserId(userId);
        QuestionOperateEntity faEntity = iQuestionOperateService.isCollect(favoriteEntity);
        // 查询是否点赞过
        QuestionOperateEntity likeEntity = new QuestionOperateEntity();
        likeEntity.setDataId(questionId);
        likeEntity.setType(2);
        likeEntity.setUserId(userId);
        QuestionOperateEntity lkEntity = iQuestionOperateService.isCollect(likeEntity);
        //判断是否打赏过，打赏过的可以看；vip也可以直接看
        QuestionOperateEntity qoEntity  = new QuestionOperateEntity();
        qoEntity.setDataId(questionId);
        qoEntity.setUserId(userId);
        qoEntity.setType(4);
        QuestionOperateEntity tipEntity = iQuestionOperateService.isCollect(qoEntity);
        //判断是不是会员,会员可以免费看
        UserInfoEntity userInfo = iUserInfoService.getByUserId(userId);
        //专家可以看自己的题目
        boolean isExpertSelf = false;
        if(entity.getExpert().equals(userId)){
            isExpertSelf = true;
        }
        int vipFlag = userInfo.getVipFlag();
        //设置免费浏览的题目刻意直接看
        if (null != entity) {
            // 收藏
            if (null == faEntity) {
                // 没有收藏过
                entity.setIsFavorite(0);
            } else {
                // 收藏过
                entity.setIsFavorite(1);
            }
            // 点赞
            if (null == lkEntity) {
                // 没有点赞过
                entity.setIsLike(0);
            } else {
                // 点赞过
                entity.setIsLike(1);
            }
            // 付费
            if (null != tipEntity || vipFlag == 2 || isExpertSelf || entity.getLockFlag() == 0) {
                // 付费过或者是vip或者专家查看自己写的题目或者免费浏览的题目
                entity.setIsTip(1);
            } else {
                // 没有付费过
                entity.setIsTip(0);
            }
        }
        return entity;
    }

    /**
     * 取消收藏
     *
     * @param questionId
     * @param userId
     */
    @Override
    public void noCollect(Long questionId, Long userId) {
        // 收藏数量减 1
        questionBankMapper.noCollect(questionId);
        // 在我的收藏 user_collect 表中删除信息
        UserCollectEntity userCollectEntity = new UserCollectEntity();
        userCollectEntity.setUserId(userId);
        userCollectEntity.setCollectType(1);
        userCollectEntity.setInfoId(questionId);
        iUserCollectService.noCollect(userCollectEntity);
        // 在 题库操作表 question_operate 中删除信息
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(3);
        iQuestionOperateService.deleteOne(operateEntity);

    }

    /**
     * 取消点赞
     *
     * @param questionId
     * @param userId
     */
    @Override
    public void noLike(Long questionId, Long userId) {
        // 点赞数量减 1
        questionBankMapper.noLike(questionId);
        // 记录行为 question_operate
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(2);
        iQuestionOperateService.deleteOne(operateEntity);
    }

    /**
     * 问题归档
     * 
     * @param qbEntity
     */
    private void questionCollect(QuestionCollectDto qbEntity,LiftCaseEntity liftCaseEntity) {
        QuestionBankEntity qb = new QuestionBankEntity();
        BeanUtils.copyProperties(qbEntity, qb);
        // 新增题目
        questionBankMapper.insert(qb);
        // 修改诊单状态
        //iLiftCaseService.updateStatusById(qbEntity.getLiftCaseId(), 6);

        this.cleanRedisSessionDetail(liftCaseEntity);
    }

    @Override
    public RestResponse questionCollect(QuestionCollectDto qbEntity) {
        //专家发起归档操作，需要后台审核，如果后台审核没有通过用户不能进行评价。
        // 根据诊单ID查询诊单信息
        LiftCaseEntity liftCaseEntity = liftCaseService.getById(qbEntity.getLiftCaseId());
        if (null != liftCaseEntity) {
            qbEntity.setBrandId(liftCaseEntity.getBrandId());
            qbEntity.setExpert(liftCaseEntity.getChargerId());
        }
        //问题不存在就新增，存在就修改
        QueryWrapper<QuestionBankEntity> query = new QueryWrapper<>();
        query.eq("expert",qbEntity.getExpert());
        query.eq("lift_case_id",qbEntity.getLiftCaseId());
        int count = this.count(query);
        if(count == 0){
            //新增
            qbEntity.setHotFlag(0);
            qbEntity.setStatuz(0);
            qbEntity.setExamineFlag(0);
            qbEntity.setValidPeriod(3);
            qbEntity.setLikeNum(0);
            qbEntity.setFavoriteNum(0);
            qbEntity.setBrowseNum(0);
            qbEntity.setTipNum(0);
            qbEntity.setLockFlag(1);
            this.questionCollect(qbEntity,liftCaseEntity);
        }else{
            //修改
            qbEntity.setExamineFlag(0);
            qbEntity.setNotExamineReason("");
            QuestionBankEntity entity = new QuestionBankEntity();
            BeanUtils.copyProperties(qbEntity,entity);
            boolean updateFlag = this.updateById(entity);
            QuestionBankEntity e = this.getById(qbEntity.getId());
            if (updateFlag) {
                // 修改诊单状态,评价和归档操作互换位置，因此状态值与评价互换
                //iLiftCaseService.updateStatusById(qbEntity.getLiftCaseId(), 6);
                //专家归档时，后台需要审核通过之后，用户才能进行评价,所以在专家进行归档操作的时候，当前状态不变，在问题审核通过操作的时候进行状态的变更
                //liftCaseService.updateStatusById(qbEntity.getLiftCaseId(), 5);
                return RestResponse.success(null, "问题归档完成");
            }else {
                return RestResponse.fail("问题归档失败");
            }
        }

        return RestResponse.success(null,"问题归档完成");
    }

    @Override
    public RestResponse modify(QuestionBankEntity qbEntity) {
        //问题不存在就新增，存在就修改
        QueryWrapper<QuestionBankEntity> query = new QueryWrapper<>();
        query.eq("expert",qbEntity.getExpert());
        query.eq("lift_case_id",qbEntity.getLiftCaseId());
        int count = this.count(query);
        if(count == 0){
            //新增
            qbEntity.setHotFlag(0);
            qbEntity.setStatuz(0);
            qbEntity.setExamineFlag(0);
            qbEntity.setValidPeriod(3);
            qbEntity.setLikeNum(0);
            qbEntity.setFavoriteNum(0);
            qbEntity.setBrowseNum(0);
            qbEntity.setTipNum(0);
            boolean saveFlag = this.save(qbEntity);
            QuestionBankEntity byId = this.getById(qbEntity.getId());
            if (saveFlag) {
                //新增成功，在全文索引表中插入数据
//                if(null != qbEntity.getTitle() && null != qbEntity.getId()){
//                    iSearchIndexService.insertSearchIndex(qbEntity.getTitle(),1,qbEntity.getId());
//                }
                return RestResponse.success(byId, "新增成功");
            }
            else{
                return RestResponse.fail("新增失败");
            }
        }else{
            //修改
            boolean updateFlag = this.updateById(qbEntity);
            QuestionBankEntity e = this.getById(qbEntity.getId());
            if (updateFlag) {
                return RestResponse.success(null, "修改成功");
            }else {
                return RestResponse.fail("修改失败");
            }
        }
    }

    /*
     * 清除redis缓存，关闭会话
     */
    private void cleanRedisSessionDetail(LiftCaseEntity liftCaseEntity) {
        String room = liftCaseEntity.getSessionId();
        // 关闭会话
        sessionMapper.batchUpdateEntrance(room, 0);
        // redis
    }


}
