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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.order.constant.OrderAppConstants;
import com.ruoyi.web.modules.order.constant.OrderConstants;
import com.ruoyi.web.modules.order.domain.BizOrderAftersale;
import com.ruoyi.web.modules.order.dto.SellerAftersaleFinishDTO;
import com.ruoyi.web.modules.order.dto.SellerAftersaleQuery;
import com.ruoyi.web.modules.order.mapper.BizOrderAftersaleMapper;
import com.ruoyi.web.modules.order.mapper.BizOrderMapper;
import com.ruoyi.web.modules.order.service.impl.SellerAftersaleServiceImpl;
import com.ruoyi.web.modules.order.support.OrderAppSupport;
import com.ruoyi.web.modules.pay.service.IOrderAftersaleRefundService;
import com.ruoyi.web.modules.order.vo.SellerAftersaleDetailVO;
import com.ruoyi.web.modules.order.vo.SellerAftersaleListRowVO;

@ExtendWith(MockitoExtension.class)
class SellerAftersaleServiceImplTest
{
    private static final Long SHOP_ID = 101L;

    private static final Long AFTERSALE_ID = 900L;

    @Mock
    private BizOrderAftersaleMapper aftersaleMapper;

    @Mock
    private BizOrderMapper orderMapper;

    @Mock
    private OrderAppSupport orderAppSupport;

    @Mock
    private IOrderAftersaleRefundService orderAftersaleRefundService;

    @InjectMocks
    private SellerAftersaleServiceImpl sellerAftersaleService;

    @Test
    void selectSellerList_enrichesTextAndMasksMobile()
    {
        SellerAftersaleListRowVO row = new SellerAftersaleListRowVO();
        row.setApplyType(OrderAppConstants.AFTERSALE_TYPE_RETURN_REFUND);
        row.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS);
        row.setConsigneeMobile("13800138000");
        when(aftersaleMapper.selectSellerList(eq(SHOP_ID), any(SellerAftersaleQuery.class)))
                .thenReturn(Collections.singletonList(row));
        when(orderAppSupport.aftersaleApplyTypeText(OrderAppConstants.AFTERSALE_TYPE_RETURN_REFUND))
                .thenReturn("退货退款");
        when(orderAppSupport.aftersaleStatusText(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS))
                .thenReturn("进行中");

        SellerAftersaleListRowVO result = sellerAftersaleService.selectSellerList(SHOP_ID, new SellerAftersaleQuery()).get(0);

        assertEquals("退货退款", result.getApplyTypeText());
        assertEquals("进行中", result.getAftersaleStatusText());
    }

    @Test
    void getSellerDetail_notFound_throws()
    {
        when(aftersaleMapper.selectSellerDetail(SHOP_ID, AFTERSALE_ID)).thenReturn(null);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerAftersaleService.getSellerDetail(SHOP_ID, AFTERSALE_ID));
        assertEquals(OrderAppConstants.MSG_AFTERSALE_NOT_FOUND, ex.getMessage());
    }

    @Test
    void finish_success()
    {
        BizOrderAftersale aftersale = new BizOrderAftersale();
        aftersale.setAftersaleId(AFTERSALE_ID);
        aftersale.setShopId(SHOP_ID);
        aftersale.setOrderId(500L);
        aftersale.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS);
        when(aftersaleMapper.selectByIdAndShop(AFTERSALE_ID, SHOP_ID)).thenReturn(aftersale);
        when(aftersaleMapper.updateForFinish(any(BizOrderAftersale.class))).thenReturn(1);

        SellerAftersaleFinishDTO dto = new SellerAftersaleFinishDTO();
        dto.setProcessResult("已同意退款");

        sellerAftersaleService.finish(SHOP_ID, AFTERSALE_ID, dto, "seller01");

        verify(aftersaleMapper).updateForFinish(any(BizOrderAftersale.class));
        verify(orderMapper).updateForAftersaleClose(500L, SHOP_ID, OrderConstants.CLOSE_TYPE_REFUND, "seller01");
        verify(orderAftersaleRefundService).refundOnAftersaleFinish(aftersale);
    }

    @Test
    void finish_alreadyFinished_throws()
    {
        BizOrderAftersale aftersale = new BizOrderAftersale();
        aftersale.setAftersaleId(AFTERSALE_ID);
        aftersale.setShopId(SHOP_ID);
        aftersale.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_FINISHED);
        when(aftersaleMapper.selectByIdAndShop(AFTERSALE_ID, SHOP_ID)).thenReturn(aftersale);

        SellerAftersaleFinishDTO dto = new SellerAftersaleFinishDTO();
        dto.setProcessResult("已同意退款");

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerAftersaleService.finish(SHOP_ID, AFTERSALE_ID, dto, "seller01"));
        assertEquals(OrderAppConstants.MSG_AFTERSALE_ALREADY_FINISHED, ex.getMessage());
        verify(aftersaleMapper, never()).updateForFinish(any());
        verify(orderMapper, never()).updateForAftersaleClose(any(), any(), any(), any());
    }

    @Test
    void finish_emptyProcessResult_throws()
    {
        BizOrderAftersale aftersale = new BizOrderAftersale();
        aftersale.setAftersaleId(AFTERSALE_ID);
        aftersale.setShopId(SHOP_ID);
        aftersale.setAftersaleStatus(OrderAppConstants.AFTERSALE_STATUS_IN_PROGRESS);
        when(aftersaleMapper.selectByIdAndShop(AFTERSALE_ID, SHOP_ID)).thenReturn(aftersale);

        SellerAftersaleFinishDTO dto = new SellerAftersaleFinishDTO();
        dto.setProcessResult("  ");

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerAftersaleService.finish(SHOP_ID, AFTERSALE_ID, dto, "seller01"));
        assertEquals(OrderAppConstants.MSG_AFTERSALE_PROCESS_REQUIRED, ex.getMessage());
    }
}
