package co.yixiang.yshop.module.order.service.storeaftersales;

import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.order.controller.admin.storeaftersales.vo.StoreAfterSalesPageReqVO;
import co.yixiang.yshop.module.order.controller.admin.storeaftersales.vo.StoreAfterSalesRespVO;
import co.yixiang.yshop.module.order.controller.admin.storeaftersales.vo.StoreAfterSalesUpdateReqVO;
import co.yixiang.yshop.module.order.controller.app.afterorder.param.AppOrderRefundParam;
import co.yixiang.yshop.module.order.convert.storeaftersales.StoreAfterSalesConvert;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersales.StoreAfterSalesDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeaftersalesitem.StoreAfterSalesItemDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorderdetail.StoreOrderDetailDO;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersales.StoreAfterSalesMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeaftersalesitem.StoreAfterSalesItemMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorderdetail.StoreOrderDetailMapper;
import co.yixiang.yshop.module.order.dal.redis.ofterorder.AfterOrderRedisDAO;
import co.yixiang.yshop.module.order.enums.*;
import co.yixiang.yshop.module.order.service.storeaftersalesstatus.StoreAfterSalesStatusService;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import co.yixiang.yshop.module.product.enums.product.StockBackTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.ORDER_ADDRESS_REQUERED;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_AFTER_SALES_NOT_EXISTS;

/**
 * 售后记录 Service 实现类
 *
 * @author yshop
 */
@Service
@Validated
public class StoreAfterSalesServiceImpl implements StoreAfterSalesService {

    @Resource
    private StoreAfterSalesMapper storeAfterSalesMapper;
    @Resource
    private StoreAfterSalesItemMapper storeAfterSalesItemMapper;
    @Resource
    private MemberUserMapper memberUserMapper;
    @Resource
    private StoreOrderMapper storeOrderMapper;
    @Resource
    private AfterOrderRedisDAO afterOrderRedisDAO;
    @Resource
    private AppStoreOrderService appStoreOrderService;
    @Resource
    private StoreAfterSalesStatusService storeAfterSalesStatusService;

    @Resource
    private StoreOrderCartInfoMapper storeOrderCartInfoMapper;

    @Resource
    private StoreOrderDetailMapper orderDetailMapper;


    @Override
    public void updateStoreAfterSales(StoreAfterSalesUpdateReqVO updateReqVO) throws Exception {
        // 校验存在
        validateStoreAfterSalesExists(updateReqVO.getId());

        this.salesCheck(updateReqVO.getId(), updateReqVO.getOrderCode(),
                updateReqVO.getType(), updateReqVO.getConsignee(), updateReqVO.getPhoneNumber(), updateReqVO.getAddress());

    }

    @Override
    public void taskAfterSalesConfirm(Long id) throws Exception {
        StoreAfterSalesDO storeAfterSales = storeAfterSalesMapper.selectById(id);
        salesCheck(id, storeAfterSales.getOrderCode(), AfterTypeEnum.AGREE.getValue(), storeAfterSales.getConsignee(), storeAfterSales.getPhoneNumber(), storeAfterSales.getAddress());
    }

    /**
     * 售后处理
     *
     * @param salesId        售后id
     * @param orderCode      订单号
     * @param approvalStatus 审核状态1-同意 2-拒绝
     */
    private void salesCheck(Long salesId, String orderCode, Integer approvalStatus, String consignee, String phoneNumber, String address) throws Exception {
        StoreAfterSalesDO storeAfterSales = storeAfterSalesMapper.selectOne(Wrappers.<StoreAfterSalesDO>lambdaQuery()
                .eq(StoreAfterSalesDO::getOrderCode, orderCode).eq(StoreAfterSalesDO::getId, salesId));
        //审核成功
        if (AfterTypeEnum.AGREE.getValue().equals(approvalStatus)) {
            // 退款参数
            AppOrderRefundParam param = new AppOrderRefundParam(salesId, storeAfterSales.getOrderCode(),
                    storeAfterSales.getRefundAmount(), StockBackTypeEnum.DEFAULT.getValue(),
                    storeAfterSales.getRefundIntegral());
            //退货退款
            if (AfterTypeEnum.RETURNS_REFUNDS.getValue().equals(storeAfterSales.getServiceType())) {
                if (Objects.equals(AfterSalesStatusEnum.USER_SHIPPED.getValue(), storeAfterSales.getState())) {
                    //退款金额大于0才生成退款单
                    appStoreOrderService.orderRefund(param);
                    storeAfterSales.setState(AfterSalesStatusEnum.REFUND_SUCCESS.getValue());
                    storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId()
                            , AfterChangeTypeEnum.PAYMENT.getValue(), AfterChangeTypeEnum.PAYMENT.getDesc());
                } else {
                    if (StringUtils.isEmpty(consignee) || StringUtils.isEmpty(phoneNumber) || StringUtils.isEmpty(address)) {
                        throw exception(ORDER_ADDRESS_REQUERED);
                    }
                    storeAfterSales.setConsignee(consignee);
                    storeAfterSales.setPhoneNumber(phoneNumber);
                    storeAfterSales.setAddress(address);
                    storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId()
                            , AfterChangeTypeEnum.AUDIT_SUCCESS.getValue(), AfterChangeTypeEnum.AUDIT_SUCCESS.getDesc());

                    storeAfterSales.setState(AfterSalesStatusEnum.AUDITED.getValue());
                }
                //退款退货得后面一步同意退款才退
            } else {
                //仅仅退款直接退款
                appStoreOrderService.orderRefund(param);
                storeAfterSales.setState(AfterSalesStatusEnum.REFUND_SUCCESS.getValue());
                storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId()
                        , AfterChangeTypeEnum.PAYMENT.getValue(), AfterChangeTypeEnum.PAYMENT.getDesc());
            }


        } else {
            //拒绝
            storeAfterSales.setState(AfterSalesStatusEnum.MERCHANT_REJECTION.getValue());
            // storeAfterSales.setSalesState(AfterTypeEnum.REFUSE.getValue());
            //操作记录
            storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId()
                    , AfterChangeTypeEnum.AUDIT_FAILED.getValue(), AfterChangeTypeEnum.AUDIT_FAILED.getDesc());

            StoreOrderDO yxStoreOrder = storeOrderMapper.selectOne(Wrappers.<StoreOrderDO>lambdaQuery().eq(StoreOrderDO::getOrderId, storeAfterSales.getOrderCode()));
            String o = afterOrderRedisDAO.get(yxStoreOrder.getOrderId(), yxStoreOrder.getUid());
            yxStoreOrder.setStatus(o == null ? 0 : Integer.parseInt(o));
            // 退款状态重置
            yxStoreOrder.setRefundStatus(OrderInfoEnum.REFUND_STATUS_NORMAL.getValue());
            storeOrderMapper.updateById(yxStoreOrder);
            afterOrderRedisDAO.delete(storeAfterSales.getOrderCode(), storeAfterSales.getUserId());
            // 订单详情重置是否售后字段
            List<StoreOrderCartInfoDO> yxStoreOrderCartInfos = storeOrderCartInfoMapper.selectList(Wrappers.<StoreOrderCartInfoDO>lambdaQuery()
                    .eq(StoreOrderCartInfoDO::getOid, yxStoreOrder.getId()));
            for (StoreOrderCartInfoDO yxStoreOrderCartInfo : yxStoreOrderCartInfos) {
                yxStoreOrderCartInfo.setIsAfterSales(ShopCommonEnum.YES.getValue());
                storeOrderCartInfoMapper.updateById(yxStoreOrderCartInfo);
            }
        }
        storeAfterSalesMapper.updateById(storeAfterSales);
    }


    /**
     * 立即退款
     *
     * @param id 编号
     */
    @Override
    public void payStoreAfterSales(Long id) throws Exception {
        StoreAfterSalesDO storeAfterSales = storeAfterSalesMapper.selectOne(Wrappers.<StoreAfterSalesDO>lambdaQuery()
                .eq(StoreAfterSalesDO::getId, id));

        storeAfterSales.setState(AfterSalesStatusEnum.REFUND_SUCCESS.getValue());
        storeAfterSalesStatusService.create(storeAfterSales.getUserId(), storeAfterSales.getId()
                , AfterChangeTypeEnum.PAYMENT.getValue(), AfterChangeTypeEnum.PAYMENT.getDesc());
        // 退款参数
        AppOrderRefundParam param = new AppOrderRefundParam(id, storeAfterSales.getOrderCode(),
                storeAfterSales.getRefundAmount(), StockBackTypeEnum.DEFAULT.getValue(),
                storeAfterSales.getRefundIntegral());
        appStoreOrderService.orderRefund(param);

    }


    private void validateStoreAfterSalesExists(Long id) {
        if (storeAfterSalesMapper.selectById(id) == null) {
            throw exception(STORE_AFTER_SALES_NOT_EXISTS);
        }
    }

    @Override
    public StoreAfterSalesDO getStoreAfterSales(Long id) {
        return storeAfterSalesMapper.selectById(id);
    }


    /**
     * 获得售后记录分页
     *
     * @param pageReqVO 分页查询
     * @return 售后记录分页
     */
    @Override
    public PageResult<StoreAfterSalesRespVO> getStoreAfterSalesPage(StoreAfterSalesPageReqVO pageReqVO) {
        PageResult<StoreAfterSalesDO> pageResult = storeAfterSalesMapper.selectPage(pageReqVO);
        PageResult<StoreAfterSalesRespVO> storeAfterSalesRespVOPageResult = StoreAfterSalesConvert.INSTANCE.convertPage(pageResult);
        for (StoreAfterSalesRespVO storeAfterSalesRespVO : storeAfterSalesRespVOPageResult.getList()) {
            LambdaQueryWrapper<StoreAfterSalesItemDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreAfterSalesItemDO::getStoreAfterSalesId, storeAfterSalesRespVO.getId());
            List<StoreAfterSalesItemDO> storeAfterSalesItemDOS = storeAfterSalesItemMapper.selectList(wrapper);
            MemberUserDO memberUserDO = memberUserMapper.selectById(storeAfterSalesRespVO.getUserId());
            UserRespVO userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
            storeAfterSalesRespVO.setStoreOrderCartInfoDOList(storeAfterSalesItemDOS);
            storeAfterSalesRespVO.setUserRespVO(userRespVO);
        }
        return storeAfterSalesRespVOPageResult;
    }


}
