package com.ruoyi.web.modules.booking.support;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.ruoyi.web.modules.farming.mapper.BizServiceAppointmentReviewMapper;
import com.ruoyi.web.modules.farming.mapper.BizTechResourceMapper;
import com.ruoyi.web.modules.farming.support.TechResourceRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("ExpertRatingRecalculator")
class ExpertRatingRecalculatorTest
{
    @Mock
    private BizServiceAppointmentReviewMapper reviewMapper;

    @Mock
    private BizTechResourceMapper techResourceMapper;

    @Test
    @DisplayName("三项总和除以3")
    void scoreFormula()
    {
        when(reviewMapper.selectExpertRatingScoreByProviderId(10L)).thenReturn(new BigDecimal("13.3"));
        ExpertRatingRecalculator.recalculateAndUpdate(10L, reviewMapper, techResourceMapper);
        verify(techResourceMapper).updateExpertRating(eq(10L), eq(new BigDecimal("13.3")));
    }

    @Test
    @DisplayName("无评价用默认5.0")
    void defaultWhenNoReviews()
    {
        when(reviewMapper.selectExpertRatingScoreByProviderId(10L)).thenReturn(null);
        ExpertRatingRecalculator.recalculateAndUpdate(10L, reviewMapper, techResourceMapper);
        verify(techResourceMapper).updateExpertRating(eq(10L), eq(TechResourceRules.DEFAULT_EXPERT_RATING));
    }

    @Test
    @DisplayName("批量同步有评价专家")
    void syncAll()
    {
        when(reviewMapper.selectExpertProviderIdsForRatingSync())
                .thenReturn(Arrays.asList(10L, 20L));
        when(reviewMapper.selectExpertRatingScoreByProviderId(10L)).thenReturn(new BigDecimal("9.0"));
        when(reviewMapper.selectExpertRatingScoreByProviderId(20L)).thenReturn(null);
        assertEquals(2, ExpertRatingRecalculator.recalculateAllWithReviews(reviewMapper, techResourceMapper));
        verify(techResourceMapper).updateExpertRating(eq(10L), eq(new BigDecimal("9.0")));
        verify(techResourceMapper).updateExpertRating(eq(20L), eq(TechResourceRules.DEFAULT_EXPERT_RATING));
    }

    @Test
    @DisplayName("无专家需同步")
    void syncNone()
    {
        when(reviewMapper.selectExpertProviderIdsForRatingSync()).thenReturn(Collections.emptyList());
        assertEquals(0, ExpertRatingRecalculator.recalculateAllWithReviews(reviewMapper, techResourceMapper));
    }
}
