package com.ruoyi.web.modules.order.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.account.domain.BizMember;
import com.ruoyi.web.modules.account.facade.IMemberFacade;
import com.ruoyi.web.modules.order.constant.CheckoutConstants;
import com.ruoyi.web.modules.order.constant.OrderAppConstants;
import com.ruoyi.web.modules.order.constant.OrderConstants;
import com.ruoyi.web.modules.order.domain.BizOrder;
import com.ruoyi.web.modules.order.domain.BizOrderAftersale;
import com.ruoyi.web.modules.order.domain.BizOrderItem;
import com.ruoyi.web.modules.order.dto.OrderAftersaleSubmitDTO;
import com.ruoyi.web.modules.order.mapper.BizOrderAftersaleMapper;
import com.ruoyi.web.modules.order.mapper.BizOrderItemMapper;
import com.ruoyi.web.modules.order.mapper.BizOrderMapper;
import com.ruoyi.web.modules.order.service.IOrderAftersaleAppService;
import com.ruoyi.web.modules.order.support.OrderAppSupport;
import com.ruoyi.web.modules.order.vo.OrderAftersaleDetailVO;
import com.ruoyi.web.modules.order.vo.OrderAftersaleListRowVO;
import com.ruoyi.web.modules.order.vo.OrderAftersaleSubmitResultVO;

/**
 * C 端订单售后 Service 实现
 */
@Service
public class OrderAftersaleAppServiceImpl implements IOrderAftersaleAppService
{
    @Autowired
    private IMemberFacade memberFacade;

    @Autowired
    private BizOrderMapper orderMapper;

    @Autowired
    private BizOrderItemMapper orderItemMapper;

    @Autowired
    private BizOrderAftersaleMapper aftersaleMapper;

    @Autowired
    private OrderAppSupport orderAppSupport;

    @Override
    public List<OrderAftersaleListRowVO> list(Long memberId, String tab)
    {
        assertMemberEnabled(memberId);
        String aftersaleTab = StringUtils.isEmpty(tab) ? OrderAppConstants.AFTERSALE_TAB_IN_PROGRESS : tab;
        List<BizOrderAftersale> list = aftersaleMapper.selectMemberList(memberId, aftersaleTab);
        if (list == null || list.isEmpty())
        {
            return Collections.emptyList();
        }
        List<OrderAftersaleListRowVO> rows = new ArrayList<>(list.size());
        for (BizOrderAftersale item : list)
        {
            rows.add(toListRow(item));
        }
        return rows;
    }

    @Override
    public OrderAftersaleDetailVO getDetail(Long memberId, Long aftersaleId)
    {
        assertMemberEnabled(memberId);
        BizOrderAftersale aftersale = aftersaleMapper.selectByIdAndMember(aftersaleId, memberId);
        if (aftersale == null)
        {
            throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_NOT_FOUND);
        }
        return toDetail(aftersale);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderAftersaleSubmitResultVO submit(Long memberId, OrderAftersaleSubmitDTO dto)
    {
        assertMemberEnabled(memberId);
        validateSubmitDto(dto);
        BizOrder order = requireOrder(memberId, dto.getOrderId());
        List<BizOrderItem> orderItems = requireOrderItems(dto.getOrderId());
        validateApplyType(order, dto, orderItems);
        assertAftersaleWithinLimit(order);
        if (aftersaleMapper.countInProgressByOrderId(order.getOrderId()) > 0)
        {
            throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_IN_PROGRESS);
        }
        BigDecimal applyAmount = dto.getApplyAmount();
        if (applyAmount.compareTo(order.getPayAmount()) > 0)
        {
            throw new ServiceException(OrderAppConstants.MSG_APPLY_AMOUNT_EXCEED);
        }
        BizMember member = memberFacade.getMember(memberId);
        Date now = new Date();
        BizOrderAftersale aftersale = new BizOrderAftersale();
        aftersale.setAftersaleNo(orderAppSupport.nextAftersaleNo());
        aftersale.setOrderId(order.getOrderId());
        aftersale.setOrderItemId(null);
        fillWholeOrderGoodsSnapshot(aftersale, orderItems);
        aftersale.setMemberId(memberId);
        aftersale.setShopId(order.getShopId());
        aftersale.setApplyType(dto.getApplyType());
        aftersale.setApplyReason(dto.getApplyReason());
        aftersale.setReturnQuantity(resolveReturnQuantity(dto.getApplyType(), orderItems));
        aftersale.setApplyAmount(applyAmount);
        aftersale.setDescription(dto.getDescription());
        aftersale.setEvidencePics(orderAppSupport.joinPics(dto.getEvidencePics()));
        aftersale.setOrderNo(order.getOrderNo());
        aftersale.setPayAmount(order.getPayAmount());
        aftersale.setMemberNickName(member != null ? member.getNickName() : order.getMemberNickName());
        aftersale.setConsigneeName(order.getConsigneeName());
        aftersale.setConsigneeMobile(order.getConsigneeMobile());
        aftersale.setConsigneeAddress(order.getConsigneeAddress());
        aftersale.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS);
        aftersale.setCreateTime(now);
        aftersale.setUpdateTime(now);
        aftersaleMapper.insert(aftersale);
        OrderAftersaleSubmitResultVO result = new OrderAftersaleSubmitResultVO();
        result.setAftersaleId(aftersale.getAftersaleId());
        result.setAftersaleNo(aftersale.getAftersaleNo());
        return result;
    }

    private void validateSubmitDto(OrderAftersaleSubmitDTO dto)
    {
        if (dto == null || dto.getOrderId() == null
                || StringUtils.isEmpty(dto.getApplyType()) || StringUtils.isEmpty(dto.getApplyReason())
                || dto.getApplyAmount() == null)
        {
            throw new ServiceException("请填写完整售后信息");
        }
    }

    private void validateApplyType(BizOrder order, OrderAftersaleSubmitDTO dto, List<BizOrderItem> orderItems)
    {
        String type = dto.getApplyType();
        String status = order.getOrderStatus();
        if (OrderAppConstants.AFTERSALE_TYPE_REFUND_UNSHIPPED.equals(type))
        {
            if (!OrderConstants.STATUS_PENDING_SHIP.equals(status))
            {
                throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_TYPE_INVALID);
            }
            return;
        }
        if (OrderAppConstants.AFTERSALE_TYPE_REFUND_SHIPPED.equals(type)
                || OrderAppConstants.AFTERSALE_TYPE_RETURN_REFUND.equals(type))
        {
            if (!OrderConstants.STATUS_PENDING_SHIP.equals(status)
                    && !OrderConstants.STATUS_SHIPPED.equals(status)
                    && !OrderConstants.STATUS_COMPLETED.equals(status))
            {
                throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_TYPE_INVALID);
            }
            if (sumOrderQuantity(orderItems) <= 0)
            {
                throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_ORDER_EMPTY);
            }
            return;
        }
        throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_TYPE_INVALID);
    }

    private Integer resolveReturnQuantity(String applyType, List<BizOrderItem> orderItems)
    {
        if (OrderAppConstants.AFTERSALE_TYPE_REFUND_UNSHIPPED.equals(applyType))
        {
            return null;
        }
        return sumOrderQuantity(orderItems);
    }

    private void fillWholeOrderGoodsSnapshot(BizOrderAftersale aftersale, List<BizOrderItem> orderItems)
    {
        BizOrderItem first = orderItems.get(0);
        aftersale.setGoodsId(first.getGoodsId());
        aftersale.setGoodsImage(first.getGoodsImage());
        if (orderItems.size() == 1)
        {
            aftersale.setGoodsName(first.getGoodsName());
            aftersale.setGoodsSpec(first.getGoodsSpec());
            return;
        }
        aftersale.setGoodsName(first.getGoodsName() + "等" + orderItems.size() + "件商品");
        aftersale.setGoodsSpec("整单售后");
    }

    private int sumOrderQuantity(List<BizOrderItem> orderItems)
    {
        int sum = 0;
        for (BizOrderItem item : orderItems)
        {
            if (item.getQuantity() != null)
            {
                sum += item.getQuantity();
            }
        }
        return sum;
    }

    private void assertAftersaleWithinLimit(BizOrder order)
    {
        if (orderAppSupport.isAftersaleExpired(order))
        {
            throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_EXPIRED);
        }
    }

    private OrderAftersaleListRowVO toListRow(BizOrderAftersale aftersale)
    {
        OrderAftersaleListRowVO row = new OrderAftersaleListRowVO();
        row.setAftersaleId(aftersale.getAftersaleId());
        row.setAftersaleNo(aftersale.getAftersaleNo());
        row.setAftersaleStatus(aftersale.getAftersaleStatus());
        row.setApplyType(aftersale.getApplyType());
        row.setApplyReason(aftersale.getApplyReason());
        row.setApplyAmount(aftersale.getApplyAmount());
        row.setGoodsName(aftersale.getGoodsName());
        row.setGoodsImage(aftersale.getGoodsImage());
        row.setGoodsSpec(aftersale.getGoodsSpec());
        row.setCreateTime(aftersale.getCreateTime());
        return row;
    }

    private OrderAftersaleDetailVO toDetail(BizOrderAftersale aftersale)
    {
        OrderAftersaleDetailVO vo = new OrderAftersaleDetailVO();
        vo.setAftersaleId(aftersale.getAftersaleId());
        vo.setAftersaleNo(aftersale.getAftersaleNo());
        vo.setAftersaleStatus(aftersale.getAftersaleStatus());
        vo.setProgressStage(orderAppSupport.aftersaleProgressStage(aftersale.getAftersaleStatus()));
        vo.setApplyType(aftersale.getApplyType());
        vo.setApplyReason(aftersale.getApplyReason());
        vo.setReturnQuantity(aftersale.getReturnQuantity());
        vo.setApplyAmount(aftersale.getApplyAmount());
        vo.setDescription(aftersale.getDescription());
        vo.setEvidencePics(aftersale.getEvidencePics());
        vo.setGoodsId(aftersale.getGoodsId());
        vo.setGoodsName(aftersale.getGoodsName());
        vo.setGoodsSpec(aftersale.getGoodsSpec());
        vo.setGoodsImage(aftersale.getGoodsImage());
        vo.setOrderNo(aftersale.getOrderNo());
        vo.setCreateTime(aftersale.getCreateTime());
        vo.setFinishTime(aftersale.getFinishTime());
        vo.setProcessResult(aftersale.getProcessResult());
        return vo;
    }

    private BizOrder requireOrder(Long memberId, Long orderId)
    {
        BizOrder order = orderMapper.selectByIdAndMember(orderId, memberId);
        if (order == null)
        {
            throw new ServiceException(OrderConstants.MSG_NOT_FOUND);
        }
        return order;
    }

    private List<BizOrderItem> requireOrderItems(Long orderId)
    {
        List<BizOrderItem> items = orderItemMapper.selectByOrderId(orderId);
        if (items == null || items.isEmpty())
        {
            throw new ServiceException(OrderAppConstants.MSG_AFTERSALE_ORDER_EMPTY);
        }
        return items;
    }

    private void assertMemberEnabled(Long memberId)
    {
        if (!memberFacade.isMemberEnabled(memberId))
        {
            throw new ServiceException(CheckoutConstants.MSG_MEMBER_DISABLED, 403);
        }
    }
}
