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.Arrays;
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.ReviewConstants;
import com.ruoyi.web.modules.order.domain.BizGoodsReview;
import com.ruoyi.web.modules.order.dto.SellerReviewQuery;
import com.ruoyi.web.modules.order.dto.SellerReviewReplyDTO;
import com.ruoyi.web.modules.order.mapper.BizGoodsReviewMapper;
import com.ruoyi.web.modules.order.service.impl.SellerReviewServiceImpl;
import com.ruoyi.web.modules.order.support.OrderAppSupport;
import com.ruoyi.web.modules.order.vo.SellerReviewDetailVO;
import com.ruoyi.web.modules.order.vo.SellerReviewListRowVO;

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

    private static final Long REVIEW_ID = 500L;

    @Mock
    private BizGoodsReviewMapper reviewMapper;

    @Mock
    private OrderAppSupport orderAppSupport;

    @InjectMocks
    private SellerReviewServiceImpl sellerReviewService;

    @Test
    void selectSellerList_enrichesReplyStatusAndPics()
    {
        SellerReviewListRowVO row = new SellerReviewListRowVO();
        row.setReviewId(REVIEW_ID);
        row.setReplyContent("谢谢");
        row.setReviewPicsRaw("a.jpg,b.jpg");
        when(reviewMapper.selectSellerList(eq(SHOP_ID), any(SellerReviewQuery.class)))
                .thenReturn(Collections.singletonList(row));
        when(orderAppSupport.splitPics("a.jpg,b.jpg")).thenReturn(Arrays.asList("a.jpg", "b.jpg"));

        SellerReviewListRowVO result = sellerReviewService.selectSellerList(SHOP_ID, new SellerReviewQuery()).get(0);

        assertEquals(ReviewConstants.REPLY_STATUS_REPLIED, result.getReplyStatus());
        assertEquals(2, result.getReviewPics().size());
    }

    @Test
    void getSellerDetail_notFound_throws()
    {
        when(reviewMapper.selectSellerDetail(SHOP_ID, REVIEW_ID)).thenReturn(null);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerReviewService.getSellerDetail(SHOP_ID, REVIEW_ID));
        assertEquals(ReviewConstants.MSG_NOT_FOUND, ex.getMessage());
    }

    @Test
    void reply_success()
    {
        BizGoodsReview review = new BizGoodsReview();
        review.setReviewId(REVIEW_ID);
        review.setShopId(SHOP_ID);
        review.setDelFlag(ReviewConstants.DEL_NORMAL);
        when(reviewMapper.selectById(REVIEW_ID)).thenReturn(review);

        SellerReviewReplyDTO dto = new SellerReviewReplyDTO();
        dto.setReplyContent("欢迎再次光临");
        sellerReviewService.reply(SHOP_ID, REVIEW_ID, dto, "seller01");

        verify(reviewMapper).updateReply(any(BizGoodsReview.class));
    }

    @Test
    void reply_emptyContent_throws()
    {
        BizGoodsReview review = new BizGoodsReview();
        review.setReviewId(REVIEW_ID);
        review.setShopId(SHOP_ID);
        review.setDelFlag(ReviewConstants.DEL_NORMAL);
        when(reviewMapper.selectById(REVIEW_ID)).thenReturn(review);

        SellerReviewReplyDTO dto = new SellerReviewReplyDTO();
        dto.setReplyContent("  ");

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerReviewService.reply(SHOP_ID, REVIEW_ID, dto, "seller01"));
        assertEquals(ReviewConstants.MSG_REPLY_CONTENT_REQUIRED, ex.getMessage());
        verify(reviewMapper, never()).updateReply(any());
    }

    @Test
    void reply_wrongShop_throws()
    {
        BizGoodsReview review = new BizGoodsReview();
        review.setReviewId(REVIEW_ID);
        review.setShopId(999L);
        review.setDelFlag(ReviewConstants.DEL_NORMAL);
        when(reviewMapper.selectById(REVIEW_ID)).thenReturn(review);

        SellerReviewReplyDTO dto = new SellerReviewReplyDTO();
        dto.setReplyContent("回复");

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerReviewService.reply(SHOP_ID, REVIEW_ID, dto, "seller01"));
        assertEquals(ReviewConstants.MSG_NOT_FOUND, ex.getMessage());
    }

    @Test
    void deleteReview_success()
    {
        BizGoodsReview review = new BizGoodsReview();
        review.setReviewId(REVIEW_ID);
        review.setShopId(SHOP_ID);
        review.setDelFlag(ReviewConstants.DEL_NORMAL);
        when(reviewMapper.selectById(REVIEW_ID)).thenReturn(review);
        when(reviewMapper.updateDelFlag(REVIEW_ID, SHOP_ID)).thenReturn(1);

        sellerReviewService.deleteReview(SHOP_ID, REVIEW_ID, "seller01");

        verify(reviewMapper).updateDelFlag(REVIEW_ID, SHOP_ID);
    }

    @Test
    void deleteReview_deletedRow_throws()
    {
        BizGoodsReview review = new BizGoodsReview();
        review.setReviewId(REVIEW_ID);
        review.setShopId(SHOP_ID);
        review.setDelFlag(ReviewConstants.DEL_DELETED);
        when(reviewMapper.selectById(REVIEW_ID)).thenReturn(review);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> sellerReviewService.deleteReview(SHOP_ID, REVIEW_ID, "seller01"));
        assertEquals(ReviewConstants.MSG_NOT_FOUND, ex.getMessage());
        verify(reviewMapper, never()).updateDelFlag(any(), any());
    }

    @Test
    void getSellerDetail_success()
    {
        SellerReviewDetailVO detail = new SellerReviewDetailVO();
        detail.setReviewId(REVIEW_ID);
        detail.setReplyContent(null);
        detail.setReviewPicsRaw("pic.jpg");
        when(reviewMapper.selectSellerDetail(SHOP_ID, REVIEW_ID)).thenReturn(detail);
        when(orderAppSupport.splitPics("pic.jpg")).thenReturn(Collections.singletonList("pic.jpg"));

        SellerReviewDetailVO result = sellerReviewService.getSellerDetail(SHOP_ID, REVIEW_ID);

        assertEquals(ReviewConstants.REPLY_STATUS_UNREPLIED, result.getReplyStatus());
        assertEquals(1, result.getReviewPics().size());
    }
}
