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

import cn.com.ty.lift.common.model.PushMessage;
import cn.com.ty.lift.common.model.PushUserInfo;
import cn.com.ty.lift.ud.chat.controller.model.LiftCaseReq;
import cn.com.ty.lift.ud.chat.controller.query.LiftCaseQuery;
import cn.com.ty.lift.ud.chat.mapper.ChatSessionMapper;
import cn.com.ty.lift.ud.chat.mapper.LiftCaseMapper;
import cn.com.ty.lift.ud.chat.mapper.entity.ChatSessionEntity;
import cn.com.ty.lift.ud.chat.mapper.entity.LiftCaseEntity;
import cn.com.ty.lift.ud.chat.mapper.entity.MyCaseVo;
import cn.com.ty.lift.ud.chat.service.ILiftCaseService;
import cn.com.ty.lift.ud.common.RandomizingID;
import cn.com.ty.lift.ud.coupon.mapper.CouponMapper;
import cn.com.ty.lift.ud.coupon.mapper.entity.Coupon;
import cn.com.ty.lift.ud.coupon.service.ICouponService;
import cn.com.ty.lift.ud.dataBank.mapper.LiftBrandMapper;
import cn.com.ty.lift.ud.dataBank.mapper.entity.LiftBrandEntity;
import cn.com.ty.lift.ud.liftCaseAppeal.controller.query.LiftCaseAppealQuery;
import cn.com.ty.lift.ud.liftCaseAppeal.mapper.LiftCaseAppealMapper;
import cn.com.ty.lift.ud.liftCaseAppeal.mapper.entity.LiftCaseAppealEntity;
import cn.com.ty.lift.ud.liftCaseAppeal.service.ILiftCaseAppealService;
import cn.com.ty.lift.ud.neety.task.RoomInfo;
import cn.com.ty.lift.ud.neety.task.UserInfo;
import cn.com.ty.lift.ud.operation.mapper.CommissionSettingMapper;
import cn.com.ty.lift.ud.operation.mapper.OtherSettingMapper;
import cn.com.ty.lift.ud.operation.mapper.entity.CommissionSettingEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.OtherSettingEntity;
import cn.com.ty.lift.ud.operation.service.ICommissionSettingService;
import cn.com.ty.lift.ud.payment.mapper.UserBillMapper;
import cn.com.ty.lift.ud.payment.mapper.entity.UserBillEntity;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionBankEntity;
import cn.com.ty.lift.ud.question.service.IQuestionBankService;
import cn.com.ty.lift.ud.redis.RedisUtil;
import cn.com.ty.lift.ud.userAccount.mapper.UserAccountMapper;
import cn.com.ty.lift.ud.userAccount.mapper.entity.UserAccount;
import cn.com.ty.lift.ud.userAccount.service.IUserAccountService;
import cn.com.ty.lift.ud.userCoupon.mapper.UserCouponMapper;
import cn.com.ty.lift.ud.userInfo.mapper.UserInfoMapper;
import cn.com.ty.lift.ud.userInfo.mapper.entity.UserInfoEntity;
import cn.com.ty.lift.ud.userInfo.service.IUserInfoService;
import cn.com.ty.lift.ud.utils.UUIDUtil;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;


//                问诊：0待付款 1待接单 2已接单 3用户待确认 4待归档 5待评价 6已完成 7申诉中 8已拒绝
//                出诊：0待接单 1待报价 2用户待付款 3待打卡 4用户待确认 5待评价 6已完成 7申诉中 8已拒绝
/**
 * 诊单 -ServiceImpl
 *
 * @author Xson
 * @date 2020-04-23
 */
@Slf4j
@Service
@Transactional
public class LiftCaseServiceImpl extends ServiceImpl<LiftCaseMapper, LiftCaseEntity> implements ILiftCaseService {
    @Autowired
    private LiftCaseMapper caseMapper;
    @Autowired
    private RedisUtil redis;
    @Autowired
    private LiftBrandMapper liftBrandMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private UserAccountMapper udUserAccountMapper;
    @Autowired
    private OtherSettingMapper otherSettingMapper;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private ChatSessionMapper sessionMapper;

    @Autowired
    private CommissionSettingMapper commissionSettingMapper;

    @Autowired
    private UserBillMapper userBillMapper;
    @Autowired
    private IUserAccountService iUserAccountService;
    @Autowired
    private ChatSessionMapper chatSessionMapper;

    @Autowired
    private LiftCaseAppealMapper liftCaseAppealMapper;

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private IQuestionBankService iQuestionBankService;

    @Autowired
    private ICommissionSettingService iCommissionSettingService;

    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ICouponService couponService;
    @Autowired
    private ILiftCaseAppealService liftCaseAppealService;
    @Autowired
    private IQuestionBankService questionBankService;

    @Override
    public RestResponse createLiftCase(LiftCaseReq req) {

        LiftCaseEntity entity = new LiftCaseEntity();
        BeanUtils.copyProperties(req, entity);
        entity.setIsInvoice(0);
        entity.setAcceptStatus(0);
        entity.setStatuz(0);
        entity.setArrivedFlag(0);
        entity.setSessionId(null);
        entity.setCreateUserId(req.getCreateUserId().longValue());
        entity.setIsPlatformSpecified(0);
        entity.setColorGrade(0);
        int count = baseMapper.insert(entity);

        if (count > 0) {
            return RestResponse.success(entity.getId(), "Updated successfully");
        } else {
            return RestResponse.fail("Updated unsuccessfully");
        }
    }

    @Override
    public RestResponse selectByExample(LiftCaseQuery query) {
        IPage page = query.page();
        List<LiftCaseEntity> list = null;
        int total = 0;
        switch (query.getType()) {
            case "USER_ALL": // 全部
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryUserAll(query);
                total = caseMapper.queryUserAllCount(query);
                break;
            case "CHARGE_ALL": // 全部
//                query.setAcceptStatus(1);
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryChargeAll(query);
                total = caseMapper.queryChargeAllCount(query);
                break;
            case "TO_PAY": // 待付款
//                query.setStatuz1("0");
//                query.setStatuz2("2");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryToPay(query);
                total = caseMapper.queryToPayCount(query);
                break;
            case "USER_TO_SURE": // 待确认
//                query.setStatuz1("2,3");
//                query.setStatuz2("3,4");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryUserToSure(query);
                total = caseMapper.queryUserToSureCount(query);
                break;
            case "TO_EVA": // 待评价
//                query.setStatuz1("5");
//                query.setStatuz2("5");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryToEva(query);
                total = caseMapper.queryToEvaCount(query);
                break;
            case "TO_APPEAL": // 申诉
                LiftCaseAppealQuery liftCaseAppealQuery = new LiftCaseAppealQuery();
                liftCaseAppealQuery.setAppealerId(query.getCreateUserId().toString());
                list = liftCaseAppealMapper.selectListByUserForCase(liftCaseAppealQuery);
                total = liftCaseAppealMapper.selectCountByUserForCase(liftCaseAppealQuery);
                break;
            case "TO_OFFER": // 待报价（专家）
//                query.setStatuz2("1");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryToOffer(query);
                total = caseMapper.queryToOfferCount(query);
                break;
            case "TO_CLOCK": // 待打卡
//                query.setDataTable("2");
//                query.setArrivedFlag(0);
//                query.setStatuz2("3");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryToClock(query);
                total = caseMapper.queryToClockCount(query);
                break;
            case "CHARGE_TO_SURE": // 待确认
//                query.setDataTable("2");
//                query.setArrivedFlag(1);
//                query.setStatuz1("2,3");
//                query.setStatuz2("3");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryChargeToSure(query);
                total = caseMapper.queryChargeToSureCount(query);
                break;
            case "TO_ARCHIVE": // 待归档
//                query.setStatuz1("4");
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryToAchive(query);
                total = caseMapper.queryToAchiveCount(query);
                break;
            case "WORKBENCH": // 工作台
//                query.setStatuz1("1");
//                query.setStatuz2("0");
//                query.setAcceptStatus(0);
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryWorkbench(query);
                total = caseMapper.queryWorkbenchCount(query);
                break;
            case "BACKQUERY": // 后台监控中心
                query.setHaveSessionId(true);
//                list = caseMapper.selectByQuery(query);
//                total = caseMapper.countByQuery(query);
                list = caseMapper.queryMonitoringCenter(query);
                total = caseMapper.queryMonitoringCenterCount(query);
                break;
            default:
                break;
        }
        for (LiftCaseEntity le : list) {
            UserInfoEntity chargeInfo = userInfoMapper.getByUserId(le.getChargerId());
            if (chargeInfo != null) {
                le.setChargeName(chargeInfo.getName());
            }
            if (query.getUserType() == null || query.getUserType() == 1) {
                UserInfoEntity charge = userInfoMapper.getByUserId(le.getChargerId());
                if (charge != null) {
                    le.setName(charge.getName());
                    le.setAvatarUrl(charge.getAvatarUrl());
                }
            }
            if (query.getUserType() != null && query.getUserType() == 2) {
                UserInfoEntity charge = userInfoMapper.getByUserId(le.getCreateUserId());
                if (charge != null) {
                    le.setName(charge.getName());
                    le.setAvatarUrl(charge.getAvatarUrl());
                }
            }
        }
        page.setRecords(list);
        page.setTotal(total);
        return RestResponse.success(page);
    }

    @Override
    public LiftCaseEntity getOneMoreById(Long id) {
        LiftCaseEntity liftcase = caseMapper.selectById(id);
        LiftBrandEntity brand = liftBrandMapper.selectById(liftcase.getBrandId());
        if (brand != null) {
            liftcase.setBrandName(brand.getName());
        }
        if (liftcase.getChargerId() != null) {
            UserInfoEntity userinfo = userInfoMapper.getByUserId(liftcase.getChargerId());
            if (userinfo != null) {
                liftcase.setName(userinfo.getName());
                liftcase.setAvatarUrl(userinfo.getAvatarUrl());
            }
        }

        return liftcase;
    }

    public static void main(String[] args) {
        System.out.println(UUIDUtil.getUuidByTime(8).length());
    }

    /**
     * 1 已删除状态
     */
    final int deleteFlag = 1;

    /**
     * 0 不是专家
     */
    final int expertFlag = 0;

    /**
     * 2 红包状态 0:已失效1:可使用2：已使用',
     */
    final int usedFlag = 2;

    /**
     * 1 卡券使用范围 0:全场通用1:出诊问诊2:题库3:视频',
     */
    final int scenario = 1;

    @Override
    public RestResponse generateOrder(LiftCaseQuery request) {

        // 诊单id
        final Integer caseId = request.getId();
        // 专家id
        final Long chargerId = request.getChargerId();
        // 订单号（22位） = 时间戳+上随机生成8位数
        final String orderNo = UUIDUtil.getUuidByTime(8);

        LiftCaseEntity liftcase = caseMapper.selectById(caseId);

        if (null == liftcase) {
            return RestResponse.fail("诊单不存在,请检查！");
        }
        if (liftcase.getStatuz() == 8) {
            liftcase.setAcceptStatus(0);
        }
        Long userId = liftcase.getCreateUserId().longValue();
        /** 问诊费用 */
        BigDecimal amount = BigDecimal.ZERO;
        // 完善诊单信息 填充专家，获取专家问诊费用
        if (null != chargerId) {
            /** 用户自己选择专家 */
            UserInfoEntity userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfoEntity>().eq("user_id", chargerId));

            UserAccount userAccount = udUserAccountMapper.selectOne(new QueryWrapper<UserAccount>().eq("user_id", chargerId));

            if (null == userAccount || null == userInfo) {
                return RestResponse.fail("用户ID有误,请检查！");
            }
            if (deleteFlag == userAccount.getDeleteFlag()) {
                return RestResponse.fail("所选专家已删除,请检查！");
            }
            if (expertFlag == userAccount.getExpertFlag()) {
                return RestResponse.fail("所选用户不是专家,请检查！");
            }
            if (liftcase.getDataTable() == 2) {
                amount = liftcase.getTotalCost();
            } else {
                // 获取当前专家服务费
                amount = userInfo.getServiceFee();
                liftcase.setServiceCost(amount);
                if (liftcase.getStatuz() == 8) {
                    liftcase.setStatuz(0);
                }
            }
            // liftcase.setStatuz(0);

            liftcase.setChargerId(chargerId);

            liftcase.setUpdateTime(LocalDateTime.now());
            liftcase.setIsPlatformSpecified(0);
            // caseMapper.updateByPrimaryKeySelective(liftcase);
        } else {
            /** 平台指定专家 */
            // 获取平台指定专家的服务费
            amount = otherSettingMapper.getLatestVersion().getAppointExpertPrice();
            liftcase.setChargerId(-2l);
            liftcase.setServiceCost(amount);
            liftcase.setUpdateTime(LocalDateTime.now());
            liftcase.setIsPlatformSpecified(1);
            // caseMapper.updateByPrimaryKeySelective(liftcase);
        }
        final BigDecimal totalAmount = amount;
        // 卡券id
        Long couponId = null == request.getCouponId() ? null : request.getCouponId();
        // 红包id
        Long packetId = null == request.getPacketId() ? null : request.getPacketId();

        boolean couponFlag = false;
        boolean packetFlag = false;

        // 计算折扣券
        Coupon coupon = couponMapper.findListByUserIdAndCouponId(userId, couponId, 1);
        if (null != coupon) {
            // 满多少可用
            BigDecimal fullReduction = coupon.getFullReduction();
            log.info("折扣券满：{}可用", fullReduction);
            if (amount.compareTo(fullReduction) != -1) {
                // 计算满减
                amount = amount.subtract(coupon.getDiscount());
                couponFlag = true;

                // 实际支付金额小于零的时候设置支付金额为零
                if (amount.compareTo(BigDecimal.ZERO) != 1) {
                    amount = BigDecimal.ZERO;
                }

                log.info("扣除折扣券之后，还需要支付：{}", amount);
            } else {
                log.warn("未达到折扣要求，不能使用折扣券：{}-：{}", fullReduction, amount);
                return RestResponse.fail("未达到折扣要求，不能使用折扣券！");
            }
        }

        // 计算红包
        Coupon packet = couponMapper.findListByUserIdAndPacketId(userId, packetId, 1);
        // 当前需要支付的金额大于零，并且红包真实存在
        if (null != packet && amount.compareTo(BigDecimal.ZERO) == 1) {
            // 红包抵扣可能为零
            amount = amount.subtract(packet.getPrice());
            packetFlag = true;
            // 实际支付金额小于零的时候设置支付金额为零
            if (amount.compareTo(BigDecimal.ZERO) != 1) {
                amount = BigDecimal.ZERO;
            }

            log.info("扣除红包之后，还需要支付：{}", amount);
        } else if (amount.compareTo(BigDecimal.ZERO) != 1) {
            log.warn("折扣之后需支付金额已经为零，无需使用红包了！：{}", amount);
            return RestResponse.fail("折扣之后需支付金额已经为零，无需使用红包了！");
        }

        /** 创建订单 等待支付完成之后创建 问诊房间 */
        liftcase.setOrderNo(orderNo);
        if (liftcase.getDataTable() == 1) {
            liftcase.setTotalCost(totalAmount);
        }
        liftcase.setPayCost(amount);
        liftcase.setCouponId(couponFlag ? couponId.longValue() : null);
        liftcase.setRedEnvelopeId(packetFlag ? packetId.longValue() : null);
        caseMapper.updateById(liftcase);

        if (liftcase.getDataTable() == 1 && chargerId != null) {
            PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(chargerId.toString());
            PushMessage pushMessage = PushMessage.orderChargeStatus("待接单");
            pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
        }

        return RestResponse.success(liftcase.getOrderNo());
    }

    @Override
    public RestResponse platformServiceFee() {
        BigDecimal amount = otherSettingMapper.getLatestVersion().getAppointExpertPrice();
        return RestResponse.success(amount);
    }

    @Override
    public RestResponse queryPageByInvoiceId(LiftCaseQuery query) {
        IPage page = query.page();
        List<LiftCaseEntity> list = caseMapper.queryPageByInvoiceId(query.getInvoiceId(), query);
        int total = caseMapper.countByInvoiceId(query.getInvoiceId());
        if (!list.isEmpty()) {
            for (LiftCaseEntity le : list) {
                UserInfoEntity byUserId = userInfoMapper.getByUserId(le.getCreateUserId());
                if (byUserId != null) {
                    le.setAvatarUrl(byUserId.getAvatarUrl());
                    le.setName(byUserId.getName());
                }
                LiftBrandEntity selectById = liftBrandMapper.selectById(le.getBrandId());
                le.setBrandName(null == selectById ? "" : selectById.getName());
            }
        }
        page.setRecords(list);
        page.setTotal(total);
        return RestResponse.success(page);
    }

    @Override
    public void updateStatusById(Long caseId, Integer status) {
        caseMapper.updateStatusById(caseId, status);
    }

    /**
     * 0待接单1已接单2拒绝接单
     */
    final int flag = 1;

    @Override
    public RestResponse inviteExperts(LiftCaseEntity request) {

        QueryWrapper<LiftCaseEntity> queryWrapper = new QueryWrapper<LiftCaseEntity>();
        queryWrapper.eq("id", request.getId());
        LiftCaseEntity caseEntity = caseMapper.selectOne(queryWrapper);

        if (null == caseEntity) {
            return RestResponse.fail("诊单不存在，请检查");
        }

        if (flag == caseEntity.getAcceptStatus()) {
            return RestResponse.fail("重复接单，请检查");
        }

        caseEntity.setAcceptStatus(1);
        if (caseEntity.getDataTable() == 1) {
            caseEntity.setStatuz(2);
        }
        if (caseEntity.getDataTable() == 2) {
            caseEntity.setStatuz(1);
        }
        caseMapper.updateByPrimaryKeySelective(caseEntity);
        // if (flag == request.getAcceptStatus()) {
        ChatSessionEntity session = sessionMapper.selectOne(new QueryWrapper<ChatSessionEntity>().eq("sessionid", caseEntity.getSessionId()));
        session.setUserId(session.getUserId() + "," + caseEntity.getChargerId());
        sessionMapper.updateByPrimaryKeySelective(session);
        /*ChatSessionEntity record = new ChatSessionEntity();
        record.setSessionid(caseEntity.getSessionId());
        record.setStatuz(1); // 状态1:正常0:屏蔽
        record.setUserId(caseEntity.getChargerId().toString());
        record.setDataTable(caseEntity.getDataTable());// '问诊出诊 1问诊2出诊',
        record.setDataId(caseEntity.getId().intValue());
        sessionMapper.insertSelective(record);*/

        // 在redis中创建房间
        RoomInfo roomInfo2 = redis.get("ROOM:" + session.getSessionid(), RoomInfo.class);
        UserInfo expert = new UserInfo();
        expert.setUserId(caseEntity.getChargerId().toString());
        roomInfo2.getUserLIst().add(expert);
        redis.setValue("ROOM:" + session.getSessionid(), roomInfo2);


        // 更新服务次数
        UserInfoEntity userInfo = userInfoMapper.getByUserId(caseEntity.getChargerId());
        userInfo.setServiceCounts(userInfo.getServiceCounts() == null ? 1 : (userInfo.getServiceCounts() + 1));
        userInfoMapper.updateById(userInfo);

        PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(caseEntity.getCreateUserId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("已接单");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);

        return RestResponse.success("success");
    }

    /**
     * 用户确认诊单
     *
     * @param id
     * @return
     */
    @Override
    public RestResponse userMakeSureCase(Long id) {
        LiftCaseEntity selectById = caseMapper.selectById(id);
        if (selectById.getDataTable() == 1) {
            if (selectById.getStatuz() != 3) {
                return RestResponse.fail("请安流程操作");
            }
            caseMapper.updateStatusById(id, 4);
        } else {
            if (selectById.getStatuz() != 4) {
                return RestResponse.fail("请安流程操作");
            }
            caseMapper.updateStatusById(id, 5);
        }
        // 获取抽成设置，更新专家余额
        CommissionSettingEntity latestVersion = commissionSettingMapper.getLatestVersion();

        BigDecimal total = BigDecimal.ZERO;
        UserInfoEntity charger = userInfoMapper.getByUserId(selectById.getChargerId());
        int chargeSureNum = charger.getAdoptCounts() == null ? 0 : charger.getAdoptCounts();
        if (chargeSureNum < latestVersion.getNewExpertAnswerNum()) {
            total = selectById.getServiceCost().add(latestVersion.getNewExpertBoon());
            userInfoMapper.rechargePayBalance(selectById.getChargerId(), total);
        } else {
            BigDecimal questionCommission = latestVersion.getExpertCommission();
            BigDecimal subtract = new BigDecimal("100").subtract(questionCommission);
            total = selectById.getServiceCost().multiply(subtract).divide(new BigDecimal("100"));
            userInfoMapper.rechargePayBalance(selectById.getChargerId(), total);
        }
        UserInfoEntity byUserId = userInfoMapper.getByUserId(selectById.getChargerId());

        UserBillEntity ube = new UserBillEntity();
        ube.setUserId(selectById.getChargerId());
        ube.setTargetUserId(selectById.getCreateUserId());
        ube.setBalance(byUserId.getBalance());
        ube.setType(2);
        ube.setBusinessType(4);
        ube.setDescr("诊单业务收入");
        ube.setFlowNum(selectById.getOrderSerialNumber());
        ube.setAmount(total);
        userBillMapper.insert(ube);

        // 更新采纳次数
        byUserId.setAdoptCounts(byUserId.getAdoptCounts() == null ? 1 : (byUserId.getAdoptCounts() + 1));
        userInfoMapper.updateById(byUserId);

        PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(selectById.getChargerId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("用户已确认");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);

        return RestResponse.success("success");
    }

    @Override
    public RestResponse toOffer(LiftCaseEntity liftCaseEntity) {
        BigDecimal total = liftCaseEntity.getServiceCost().add(liftCaseEntity.getTravelCost());
        int offer = caseMapper.toOffer(liftCaseEntity.getId(), liftCaseEntity.getServiceCost(),
                liftCaseEntity.getTravelCost(), total);
        if (offer > 0) {
            LiftCaseEntity selectById = caseMapper.selectById(liftCaseEntity.getId());
            PushUserInfo pushUserInfo =
                    iUserAccountService.getPushUserInfoByUserId(selectById.getCreateUserId().toString());
            PushMessage pushMessage = PushMessage.orderChargeStatus("专家已报价");
            pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
            return RestResponse.success("success");
        } else {
            return RestResponse.fail("fail");
        }
    }

    @Override
    public RestResponse chargeMakeSureCase(LiftCaseEntity liftCaseEntity) {
        LiftCaseEntity selectById = caseMapper.selectById(liftCaseEntity.getId());
        if (selectById.getDataTable() == 1) {
            selectById.setStatuz(3);
            caseMapper.updateById(selectById);
        }
        if (selectById.getDataTable() == 2 && liftCaseEntity.getAfterRepair() == null) {
            return RestResponse.fail("请上传维修后视频");
        }
        if (selectById.getDataTable() == 2 && liftCaseEntity.getAfterRepair() != null) {
            selectById.setStatuz(4);
            selectById.setAfterRepair(liftCaseEntity.getAfterRepair());
            caseMapper.updateById(selectById);
        }

        PushUserInfo pushUserInfo =
                iUserAccountService.getPushUserInfoByUserId(selectById.getCreateUserId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("专家已确认");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
        return RestResponse.success("success");
    }

    @Override
    public RestResponse chargeToClock(LiftCaseEntity liftCaseEntity) {
        if (liftCaseEntity.getLat() == null || liftCaseEntity.getLng() == null) {
            caseMapper.userToClock(liftCaseEntity.getId(), liftCaseEntity.getBeforeRepair());
            return RestResponse.success("打卡成功");
        }
        Long chargeToClock =
                caseMapper.chargeToClock(liftCaseEntity.getId(), liftCaseEntity.getLat(), liftCaseEntity.getLng());
        liftCaseEntity.setArrivedFlag(1);
        OtherSettingEntity latestVersion = otherSettingMapper.getLatestVersion();
        if (chargeToClock >= latestVersion.getClockInArea()) {
            return RestResponse.fail("不在打卡范围内，无法打卡");
        }
        caseMapper.userToClock(liftCaseEntity.getId(), liftCaseEntity.getBeforeRepair());

        LiftCaseEntity selectById = caseMapper.selectById(liftCaseEntity.getId());
        PushUserInfo pushUserInfo =
                iUserAccountService.getPushUserInfoByUserId(selectById.getCreateUserId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("专家已打卡");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);

        return RestResponse.success("打卡成功");
    }

    @Override
    public RestResponse userToClock(Long id) {
        int userToClock = caseMapper.userToClock1(id);
        if (userToClock > 0) {
            LiftCaseEntity selectById = caseMapper.selectById(id);
            UserInfoEntity byUserId = userInfoMapper.getByUserId(selectById.getChargerId());
            BigDecimal travelFree = null;
            if (selectById.getTravelCost() == null) {
                travelFree = BigDecimal.ZERO;
            } else {
                travelFree = selectById.getTravelCost();
            }
            // 差旅费流水
            UserBillEntity travelBill = new UserBillEntity();
            travelBill.setUserId(selectById.getChargerId());
            travelBill.setTargetUserId(selectById.getCreateUserId());
            travelBill.setBalance(byUserId.getBalance());
            travelBill.setType(2);
            travelBill.setBusinessType(13);
            travelBill.setDescr("差旅费");
            travelBill.setFlowNum(RandomizingID.getBillId());
            travelBill.setAmount(travelFree);
            userBillMapper.insert(travelBill);
            // 更新余额
            userInfoMapper.rechargePayBalance(selectById.getChargerId(), travelFree);

            PushUserInfo pushUserInfo =
                    iUserAccountService.getPushUserInfoByUserId(selectById.getChargerId().toString());
            PushMessage pushMessage = PushMessage.orderChargeStatus("用戶已确认打卡");
            pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);

            return RestResponse.success("success");
        } else {
            return RestResponse.fail("fail");
        }
    }

    @Override
    public RestResponse refusedExperts(Long id) {
        LiftCaseEntity selectById = caseMapper.selectById(id);
        if (selectById.getAcceptStatus() == 2) {
            return RestResponse.fail("订单已拒绝");
        }
        if (selectById.getDataTable() == 1) {
            // 退款
            userInfoMapper.rechargePayBalance(selectById.getCreateUserId(), selectById.getPayCost() == null ? BigDecimal.ZERO : selectById.getPayCost());
            // 插入个人流水记录
            UserInfoEntity byUserId = userInfoMapper.getByUserId(selectById.getCreateUserId());
            UserBillEntity ube = new UserBillEntity();
            ube.setUserId(selectById.getCreateUserId());
            ube.setTargetUserId(selectById.getChargerId());
            ube.setBalance(byUserId.getBalance());
            ube.setType(2);
            ube.setBusinessType(8);
            ube.setDescr("拒绝接单退款到余额");
            ube.setFlowNum(selectById.getOrderSerialNumber());
            ube.setAmount(selectById.getPayCost() == null ? BigDecimal.ZERO : selectById.getPayCost());
            userBillMapper.insert(ube);
        }
        // 清除房间
        chatSessionMapper.delete(new QueryWrapper<ChatSessionEntity>()
                .eq("data_id", id)
                .eq("user_id", selectById.getCreateUserId()));
        // 返还卡券
        if (selectById.getCouponId() != null) {
            couponMapper.updateUserCouponStatuz(selectById.getCouponId());
        }
        if (selectById.getRedEnvelopeId() != null) {
            couponMapper.updateUserCouponStatuz(selectById.getRedEnvelopeId());
        }
        // 修改诊单状态
        caseMapper.refusedExperts(id);
        // 推送消息
        PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(selectById.getCreateUserId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("已拒绝");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);

        return RestResponse.success("success");
    }

    @Override
    public RestResponse generateRoom(LiftCaseQuery request) {
        // 诊单id
        final Integer caseId = request.getId();
        // 专家id
        final Long chargerId = request.getChargerId();

        LiftCaseEntity liftcase = caseMapper.selectById(caseId);

        if (null == liftcase) {
            return RestResponse.fail("诊单不存在,请检查！");
        }

        // 问诊出诊 1问诊2出诊
        if (2 != liftcase.getDataTable()) {
            return RestResponse.fail("不是出诊诊单,请检查！");
        }
        // 出诊：0待接单(创建订单) =》 1已接单（待报价） =》 2待付款（已报价） =》 3已付款（已付款，专家待确认） =》 4专家确认完成 =》 5用户确认完成（待评价） =》 6已评价（已完成） =》 7申诉中
        if (0 != liftcase.getStatuz() && 8 != liftcase.getStatuz()) {
            return RestResponse.fail("诊单状态有误,请检查！");
        }


        Long userId = liftcase.getCreateUserId().longValue();

        if (null != chargerId) {
            // 用户指定专家
            liftcase.setChargerId(chargerId);
            liftcase.setIsPlatformSpecified(0);
            // 消息
            PushUserInfo pushUserInfo = iUserAccountService.getPushUserInfoByUserId(chargerId.toString());
            PushMessage pushMessage = PushMessage.orderChargeStatus("待接单");
            pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
        } else {
            liftcase.setChargerId(-2L);
            liftcase.setIsPlatformSpecified(1);
        }

        String sessionId = UUIDUtil.getUuidByTime9();
        liftcase.setSessionId(sessionId);
        // 如果此单已被拒绝，再次进来的时候，把是否接单置为0--》待接单
        if (liftcase.getStatuz() == 8) {
            liftcase.setStatuz(0);
            liftcase.setAcceptStatus(0);
        }
        caseMapper.updateByPrimaryKeySelective(liftcase);

        // 每次生成房间号，都查询出诊单对应的房间，先删除再生成
        sessionMapper.delete(new QueryWrapper<ChatSessionEntity>().eq("data_id", liftcase.getId())
                .eq("user_id", liftcase.getCreateUserId()));
        // 支付完成生成聊天室
        ChatSessionEntity entity = new ChatSessionEntity();
        entity.setSessionid(sessionId);
        entity.setStatuz(1); // 状态1:正常0:屏蔽
        entity.setUserId(userId.toString());
        entity.setCreateUserId(userId + "");
        entity.setDataTable(2);// '问诊出诊 1问诊2出诊',
        entity.setDataId(liftcase.getId().intValue());
        entity.setCreateTime(LocalDateTime.now());
        entity.setEntrance(1);// 房间入口状态：1、打开0关闭
        sessionMapper.insertSelective(entity);

        // 在redis中创建房间
        RoomInfo roomInfo = new RoomInfo();
        roomInfo.setSessionid(entity.getSessionid());
        roomInfo.setDataTable(entity.getDataTable());
        roomInfo.setLastTime(entity.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setUserId(entity.getUserId());
        List<UserInfo> userList = new ArrayList<>();
        userList.add(userInfo1);
        roomInfo.setUserLIst(userList);
        redis.setValue("ROOM:" + entity.getSessionid(), roomInfo);

        return RestResponse.success();
    }

    @Override
    public List<String> findListByUserId(String userId) {
        return caseMapper.findListByUserId(userId);
    }

    @Override
    public RestResponse getAllCaseToInvoice(Long userId) {
        List<LiftCaseEntity> allCaseToInvoice = caseMapper.getAllCaseToInvoice(userId);
        return RestResponse.success(allCaseToInvoice, "Queried successfully");
    }

    @Override
    public LiftCaseEntity getAllById(Long id) {
        return caseMapper.getAllById(id);
    }

    /**
     * 计算专家应该获得的服务费提成
     *
     * @param chargerId 专家ID
     * @return
     */
    @Override
    public BigDecimal getExpertFee(Long chargerId) {
        BigDecimal fee = new BigDecimal("0");
        UserInfoEntity infoEntity = userInfoMapper.getByUserId(chargerId);
        // 专家服务费
        BigDecimal serviceFee = infoEntity.getServiceFee() == null ? new BigDecimal("0") : infoEntity.getServiceFee();
        // 计算专家已经审核通过的问题个数
        QueryWrapper<QuestionBankEntity> query = new QueryWrapper<>();
        query.eq("expert", chargerId);
        query.eq("examine_flag", 1);
        // 专家问题个数,包含出诊和问诊，问诊的题目会归档，出诊的只会记录在 lift_case
        // 问诊
        int num = iQuestionBankService.count(query);
        // 出诊
        UserInfoEntity charger = userInfoMapper.getByUserId(chargerId);
        int sureNum = charger.getAdoptCounts() == null ? 0 : charger.getAdoptCounts();
        num = num + sureNum;
        // 判断专家此时的诊单是补贴还是抽成，并计算最终的服务费金额
        RestResponse latestVersion = iCommissionSettingService.getLatestVersion();
        if (null != latestVersion.getData()) {
            CommissionSettingEntity latestVersionData = (CommissionSettingEntity) latestVersion.getData();
            // 补贴金额
            BigDecimal newExpertBoon = latestVersionData.getNewExpertBoon();
            // 前期问题个数
            int newExpertAnswerNum = latestVersionData.getNewExpertAnswerNum();
            // 专家抽成
            BigDecimal expertCommission = latestVersionData.getExpertCommission();
            if (num <= newExpertAnswerNum) {
                // 如果是前期专家，专家收入 = 服务费 + 平台补贴
                fee = serviceFee.add(newExpertBoon);
            } else {
                // 如果是后期专家，专家收入 = 服务费 - 平台抽成
                fee = serviceFee.subtract(serviceFee.multiply(expertCommission).divide(new BigDecimal("100")));
            }
        } else {
            // 没有相应的设置，不让平台抽成，也不补贴
            fee = serviceFee;
        }
        // 四舍五入保留2位小数
        fee = fee.setScale(2, BigDecimal.ROUND_HALF_UP);
        return fee;
    }

    @Override
    public void sureLiftCaseTask() {
        List<LiftCaseEntity> allToSueLiftCase = caseMapper.getAllToSueLiftCase();
        for (LiftCaseEntity le : allToSueLiftCase) {
            this.userMakeSureCase(le.getId());
        }
    }

    @Override
    public void refusedLiftCaseTask() {
        List<LiftCaseEntity> allToSueLiftCase = caseMapper.getAllTimeOutCase();
        for (LiftCaseEntity le : allToSueLiftCase) {
            this.refusedExperts(le.getId());
        }
    }

    @Override
    public RestResponse invitationExpert(LiftCaseEntity liftCaseEntity) {
        LiftCaseEntity selectById = caseMapper.selectById(liftCaseEntity.getId());
        if (selectById.getIsPlatformSpecified() == 1) {
            if (selectById.getDataTable() == 1 && selectById.getStatuz() == 1) {
                caseMapper.invitationExpert(liftCaseEntity.getId(), liftCaseEntity.getChargerId());
            }
            if (selectById.getStatuz() == 8) {
                caseMapper.invitationExpert(liftCaseEntity.getId(), liftCaseEntity.getChargerId());
            }
            if (selectById.getDataTable() == 2 && selectById.getStatuz() == 0) {
                caseMapper.invitationExpert(liftCaseEntity.getId(), liftCaseEntity.getChargerId());
            }
        } else {
            return RestResponse.fail("该订单无法再次邀请专家");
        }
        return RestResponse.success("邀请成功");
    }

    @Override
    public RestResponse updateCustomerServiceId(LiftCaseEntity liftCaseEntity) {
        caseMapper.updateCustomerServiceId(liftCaseEntity.getId(), liftCaseEntity.getCustomerServiceId());
        return RestResponse.success("更新成功");
    }

    @Override
    public void updateColorGrade() {
        List<LiftCaseEntity> caseIsToAccept = caseMapper.getCaseIsToAccept();
        for (LiftCaseEntity liftCase : caseIsToAccept) {
            caseMapper.updateColorGarde(liftCase.getId());
        }
    }

    /**
     * 我的接单
     * 返回 总收益（根据流水查询）、问诊单数（全部状态的）、出诊单数（全部状态的）、待处理数量（问诊出诊都是 已接单 状态）
     * 专家收益 =
     * 收入：打赏 2  出诊问诊收入 4  专家惩罚 9
     * 支出：专家惩罚 9  申诉退款 10
     *
     * @param userId
     * @return
     */
    @Override
    public RestResponse getMyCase(Long userId) {
        //问诊数量
        int askNum = caseMapper.selectDataTableCount(1, userId);
        //出诊数量
        int outNum = caseMapper.selectDataTableCount(2, userId);
        //问诊待处理数量就是，待评价之前所有状态的，不包括申诉的  即状态值 小于4的
        int totalDealingNum = caseMapper.selectDealingCount(userId);
        //出诊待处理数量就是，待评价之前所有状态的，不包括申诉的  即状态值 小于5的
//        int outDealingNum = caseMapper.selectDealingCount(2, userId, 5);
        //总的待处理数量
//        int totalDealingNum = askDealingNum + outDealingNum;
        //根据流水查询总收益
        //专家收入：打赏 2  出诊问诊收入 4  专家惩罚 9 （撤销惩罚）    之和
        //专家支出：专家惩罚 9   申诉退款 10  之和
        BigDecimal income = userBillMapper.selectIncome(userId);
        BigDecimal outcome = userBillMapper.selectOutcome(userId);
        income = income == null ? new BigDecimal(0) : income;
        outcome = outcome == null ? new BigDecimal(0) : outcome;
        BigDecimal total = income.subtract(outcome);
        //汇总
        MyCaseVo vo = new MyCaseVo();
        vo.setTotalMoney(total);
        vo.setAskNum(askNum);
        vo.setOutNum(outNum);
        vo.setDealingNum(totalDealingNum);
        return RestResponse.success(vo, "查询成功");
    }

    @Override
    public RestResponse cancelCase(Long id) {
        LiftCaseEntity selectById = caseMapper.selectById(id);
        if (selectById.getAcceptStatus() == 9) {
            return RestResponse.fail("订单已取消");
        }
        if (selectById.getDataTable() == 1 && selectById.getStatuz() == 1) {
            // 退款
            userInfoMapper.rechargePayBalance(selectById.getCreateUserId(), selectById.getPayCost() == null ? BigDecimal.ZERO : selectById.getPayCost());
            // 插入个人流水记录
            UserInfoEntity byUserId = userInfoMapper.getByUserId(selectById.getCreateUserId());
            UserBillEntity ube = new UserBillEntity();
            ube.setUserId(selectById.getCreateUserId());
            ube.setTargetUserId(selectById.getChargerId());
            ube.setBalance(byUserId.getBalance());
            ube.setType(2);
            ube.setBusinessType(14);
            ube.setDescr("取消订单退款到余额");
            ube.setFlowNum(selectById.getOrderSerialNumber());
            ube.setAmount(selectById.getPayCost() == null ? BigDecimal.ZERO : selectById.getPayCost());
            userBillMapper.insert(ube);
        }
        // 清除房间
        chatSessionMapper.delete(new QueryWrapper<ChatSessionEntity>()
                .eq("data_id", id)
                .eq("create_user_id",selectById.getCreateUserId())
//                .last("and FIND_IN_SET("+selectById.getCreateUserId()+",user_id)")
        );
        // 返还卡券
        if (selectById.getCouponId() != null) {
            couponMapper.updateUserCouponStatuz(selectById.getCouponId());
        }
        if (selectById.getRedEnvelopeId() != null) {
            couponMapper.updateUserCouponStatuz(selectById.getRedEnvelopeId());
        }
        // 修改诊单状态
        caseMapper.cancelCase(id);

        return RestResponse.success("success");
    }

    @Override
    public RestResponse queryDetail(Long id) {
        LiftCaseEntity entity = getAllById(id);
        if (entity != null) {
            LiftCaseAppealEntity byDataId = liftCaseAppealService.getByDataId(entity.getId());
            entity.setLiftCaseAppealEntity(byDataId);
            Coupon byId2 = couponService.getByCouponId(entity.getRedEnvelopeId());
            if (byId2 != null) {
                entity.setRedEnvelopeDeduction(byId2.getPrice());
            } else {
                entity.setRedEnvelopeDeduction(new BigDecimal("0.00"));
            }

            Coupon byId3 = couponService.getByCouponId(entity.getCouponId());
            if (byId3 != null) {
                entity.setCouponDeduction(byId3.getDiscount());
            } else {
                entity.setCouponDeduction(new BigDecimal("0.00"));
            }
            UserInfoEntity charge = userInfoService.getByUserId(entity.getCreateUserId());
            if (charge != null) {
                entity.setName(charge.getName());
                entity.setAvatarUrl(charge.getAvatarUrl());
            }
            QuestionBankEntity one = questionBankService.getOne(new QueryWrapper<QuestionBankEntity>().eq("lift_case_id", id));
            if (one != null) {
                entity.setQuestionBankEntity(one);
            }
        } else {
            return RestResponse.fail("fail");
        }
        return RestResponse.success(entity, "Queried successfully");

    }
}
