package com.ruoyi.frequency.appeal.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.DictConstant;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.controller.resp.AppealDetailResp;
import com.ruoyi.controller.resp.AppealPageResp;
import com.ruoyi.enums.WalletDetailEnums;
import com.ruoyi.enums.message.OrderMessageEnums;
import com.ruoyi.enums.order.OrderPriceEnums;
import com.ruoyi.enums.user.UserEnums;
import com.ruoyi.frequency.appeal.entity.Appeal;
import com.ruoyi.frequency.appeal.mapper.AppealMapper;
import com.ruoyi.frequency.appeal.model.result.AppealCount;
import com.ruoyi.frequency.appeal.service.AppealService;
import com.ruoyi.frequency.customer.service.UserService;
import com.ruoyi.frequency.order.entity.Order;
import com.ruoyi.frequency.order.service.OrderService;
import com.ruoyi.frequency.orderchangerecord.entity.OrderChangeRecord;
import com.ruoyi.frequency.orderchangerecord.service.OrderChangeRecordService;
import com.ruoyi.frequency.ordermessage.service.OrderMessageService;
import com.ruoyi.frequency.orderoperatorhistory.entity.OrderOperatorHistory;
import com.ruoyi.frequency.orderoperatorhistory.service.OrderOperatorHistoryService;
import com.ruoyi.frequency.orderpricerecord.service.OrderPriceRecordService;
import com.ruoyi.frequency.wallerecord.service.WalletRecordService;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.vo.PageBasic;
import com.ruoyi.vo.UserInfo;
import com.ruoyi.vo.UserVo;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 申诉Service业务层处理
 *
 * @author zj
 * @date 2023-10-13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AppealServiceImpl extends ServiceImpl<AppealMapper, Appeal> implements AppealService {
    @Autowired
    private AppealMapper appealMapper;

    /**
     * 查询申诉
     *
     * @param id 申诉主键
     * @return 申诉
     */
    @Override
    public Appeal selectAppealById(Long id) {

        Appeal appeal = appealMapper.selectAppealById(id);

        if (appeal != null) {

            Set<UserVo> userVoSet = new HashSet<>();
            //申诉人
            UserVo appealUserVo = new UserVo(appeal.getAppealUserType(), appeal.getAppealUserId());
            userVoSet.add(appealUserVo);

            //被申诉人
            UserVo passiveAppealUserVo = new UserVo(appeal.getPassiveAppealUserType(), appeal.getPassiveAppealUserId());
            userVoSet.add(passiveAppealUserVo);

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            appeal.setAppealUserInfo(userMap.get(appealUserVo));
            appeal.setPassiveAppealUserInfo(userMap.get(passiveAppealUserVo));
        }

        return appeal;
    }

    /**
     * 查询申诉列表
     *
     * @param appeal 申诉
     * @return 申诉
     */
    @Override
    public List<Appeal> selectAppealList(Appeal appeal) {

        List<Appeal> appeals = appealList(appeal);

        if (appeals.size() > 0) {
            Set<UserVo> userVoSet = new HashSet<>();
            appeals.stream().forEach(s -> {
                //申诉人
                UserVo appealUserVo = new UserVo(s.getAppealUserType(), s.getAppealUserId());
                userVoSet.add(appealUserVo);

                //被申诉人
                UserVo passiveAppealUserVo = new UserVo(s.getPassiveAppealUserType(), s.getPassiveAppealUserId());
                userVoSet.add(passiveAppealUserVo);
            });

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, null);

            appeals.stream().forEach(s -> {
                s.setAppealUserInfo(userMap.get(new UserVo(s.getAppealUserType(), s.getAppealUserId())));
                s.setPassiveAppealUserInfo(userMap.get(new UserVo(s.getPassiveAppealUserType(), s.getPassiveAppealUserId())));
            });
        }

        return appeals;
    }

    private List<Appeal> appealList(Appeal appeal) {
        List<Appeal> appeals = appealMapper.selectAppealList(appeal);
        return appeals;
    }

    @Override
    public AppealCount statistics(Appeal appeal) {
        List<Appeal> appeals = appealList(appeal);
        List<Long> appealIdList = appeals.stream().map(x -> x.getId()).collect(Collectors.toList());
        appealIdList.add(-1L);

        AppealCount count = baseMapper.statistics(appealIdList);
        return count;
    }

    /**
     * 新增申诉
     *
     * @param appeal 申诉
     * @return 结果
     */
    @Override
    public int insertAppeal(Appeal appeal) {
        return appealMapper.insertAppeal(appeal);
    }

    /**
     * 修改申诉
     *
     * @param appeal 申诉
     * @return 结果
     */
    @Override
    public int updateAppeal(Appeal appeal) {
        appeal.setUpdateTime(DateUtils.getNowDate());
        return appealMapper.updateAppeal(appeal);
    }

    /**
     * 批量删除申诉
     *
     * @param ids 需要删除的申诉主键
     * @return 结果
     */
    @Override
    public int deleteAppealByIds(Long[] ids) {
        this.lambdaUpdate().set(Appeal::getDelFlag, PublicCommon.删除).in(Appeal::getId, ids).update();
        return ids.length;
    }

    /**
     * 删除申诉信息
     *
     * @param id 申诉主键
     * @return 结果
     */
    @Override
    public int deleteAppealById(Long id) {
        this.lambdaUpdate().set(Appeal::getDelFlag, PublicCommon.删除).eq(Appeal::getId, id).update();
        return 1;
    }

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderMessageService orderMessageService;

    @Autowired
    private BusinessUtil businessUtil;

    @Autowired
    private WalletRecordService walletRecordService;

    @Autowired
    private OrderPriceRecordService orderPriceRecordService;

    @Autowired
    private OrderChangeRecordService orderChangeRecordService;

    @Override
    public AjaxResult handle(Appeal appeal) {
        boolean update = this.lambdaUpdate().set(Appeal::getAppealResult, appeal.getAppealResult())
                .set(Appeal::getRemark, appeal.getRemark())
                .eq(Appeal::getId, appeal.getId()).update();

        if (update) {
            Appeal byId = this.getById(appeal.getId());

            //更新订单申诉状态
            LambdaUpdateChainWrapper<Order> wrapper = orderService.lambdaUpdate().set(Order::getAppealStatus, PublicCommon.Appeal.申诉完成)
                    .eq(Order::getId, byId.getOrderId());
            //调价价格不为空 申诉结果;状态 1 待处理 2申诉人胜诉 3被申诉人胜诉
            if (ObjectUtil.equal(2, appeal.getAppealResult())) {

                Order order = orderService.getById(byId.getOrderId());

                BigDecimal difference = byId.getAmount();

                if (difference != null && difference.compareTo(BigDecimal.ZERO) > 0) {
                    //修改订单金额
                    wrapper.set(Order::getAmount, order.getAmount().subtract(difference));

                    // 调价金额小于原价格 （退还金额到用户余额）

                    //查询定金支付比例
                    SysDictData dict = businessUtil.getDict(DictConstant.OrderDict.首款支付占比);
                    //首款支付比例
                    BigDecimal ratio = BigDecimal.ZERO;

                    if (dict != null && ObjectUtil.isNotEmpty(dict.getDictValue())) {
                        ratio = new BigDecimal(dict.getDictValue());
                    }

                    //计算退还定金
                    BigDecimal refundPrice = difference.multiply(ratio).setScale(2, BigDecimal.ROUND_HALF_UP);

                    //定金
                    BigDecimal fistPrice = order.getFirstPrice().subtract(refundPrice);

                    walletRecordService.updateBalance(new UserVo(UserEnums.customer.getCode(), order.getCustomerId()), WalletDetailEnums.DEPOSIT_REFUND, byId.getId(), refundPrice, PublicCommon.Wallet.可提现);

                    wrapper.set(Order::getFirstPrice, fistPrice);

                    //订单支付金额
                    orderPriceRecordService.addOrderPriceRecord(OrderPriceEnums.appeal_sub, order.getId(), refundPrice.negate());

                    //添加调价记录 设计师调价 表现师自动同意的记录
                    OrderChangeRecord record = new OrderChangeRecord();
                    record.setChangeAmount(order.getAmount().subtract(byId.getAmount()))
                            .setOriginAmount(order.getAmount())
                            .setRemark(byId.getRemark())
                            .setOrderId(order.getId())
                            .setUserType(UserEnums.customer.getCode())
                            .setStatus(2)
                            .setUserId(order.getCustomerId());
                    orderChangeRecordService.save(record);

                    wrapper.set(Order::getChangeStatus, PublicCommon.OrderChange.已确认);

                    this.lambdaUpdate().set(Appeal::getRefundPrice, refundPrice)
                            .eq(Appeal::getId, appeal.getId()).update();
                }
            }

            wrapper.update();

            //发送消息
            orderMessageService.addOrderMessage(new UserVo(byId.getAppealUserType(), byId.getAppealUserId()), byId.getOrderId(), "", PublicCommon.Order.订单, OrderMessageEnums.APPEAL_RESULT);

            //记录订单操作日志
            orderOperatorHistoryService.insertOrderOperatorHistory(OrderOperatorHistory.addBackHistory(byId.getOrderId(), "申诉判定","申诉判定:" + (ObjectUtil.equal(2, appeal.getAppealResult()) ? "申诉人胜诉" : "申诉人败诉")));


        }
        return AjaxResult.success();
    }

    @Autowired
    private OrderOperatorHistoryService orderOperatorHistoryService;

    @Autowired
    private UserService userService;

    @Override
    public ResponseData<PageResult<Page<AppealPageResp>>> appealPage(PageBasic req, UserVo userVo) {
        Page<AppealPageResp> page = appealMapper.appealPage(new Page<>(req.getPageNo(), req.getPageSize()), userVo);

        return ResponseData.success(new PageResult<>(page));
    }

    @Override
    public ResponseData<AppealDetailResp> appealDetail(Long appealId, UserVo userVo) {
        AppealDetailResp appealDetailResp = appealMapper.appealDetail(appealId, userVo);
        if (appealDetailResp == null || !appealDetailResp.getDelFlag().equals(PublicCommon.启用)) {
            return ResponseData.error("投诉已取消");
        }

        if (appealDetailResp != null) {

            Set<UserVo> userVoSet = new HashSet<>();
            //申诉人
            UserVo appealUserVo = new UserVo(appealDetailResp.getAppealUserType(), appealDetailResp.getAppealUserId());
            userVoSet.add(appealUserVo);

            //被申诉人
            UserVo passiveAppealUserVo = new UserVo(appealDetailResp.getPassiveAppealUserType(), appealDetailResp.getPassiveAppealUserId());
            userVoSet.add(passiveAppealUserVo);

            //查询用户信息
            Map<UserVo, UserInfo> userMap = userService.selectUserInfoMap(userVoSet, userVo);

            appealDetailResp.setAppealUserInfo(userMap.get(appealUserVo));
            appealDetailResp.setPassiveAppealUserInfo(userMap.get(passiveAppealUserVo));
        }

        return ResponseData.success(appealDetailResp);
    }


}
