package com.starry.admin.modules.shop.service;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
import com.starry.admin.modules.shop.service.IPlayCommodityInfoService;
import com.starry.admin.modules.shop.service.IPlayCouponDetailsService;
import com.starry.admin.modules.shop.service.IPlayCouponInfoService;
import com.starry.admin.modules.shop.service.impl.PlayCouponInfoServiceImpl;
import com.starry.admin.modules.weichat.controller.WxCouponController;
import com.starry.admin.modules.weichat.entity.WxCouponReceiveReturnVo;
import com.starry.common.result.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
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;

@ExtendWith(MockitoExtension.class)
public class CouponWhitelistTest {

    @Test
    @DisplayName("领取校验-白名单：白名单用户可领，非白名单被拒")
    void testWhitelistCheckInService() {
        PlayCouponInfoServiceImpl service = new PlayCouponInfoServiceImpl();

        PlayCouponInfoEntity coupon = new PlayCouponInfoEntity();
        coupon.setClaimConditionType("2");
        coupon.setCustomWhitelist(Arrays.asList("userA", "userB"));

        PlayCustomUserInfoEntity userA = new PlayCustomUserInfoEntity();
        userA.setId("userA");

        PlayCustomUserInfoEntity userX = new PlayCustomUserInfoEntity();
        userX.setId("userX");

        String ok = service.getReasonForNotObtainingCoupons(coupon, userA);
        String deny = service.getReasonForNotObtainingCoupons(coupon, userX);

        assertEquals("", ok, "白名单用户应允许领取");
        assertEquals("非指定用户", deny, "非白名单用户应被拒绝");
    }

    @Mock
    private IPlayCouponDetailsService couponDetailsService;

    @Mock
    private IPlayCouponInfoService couponInfoService;

    @Mock
    private IPlayCommodityInfoService commodityInfoService;

    @InjectMocks
    private WxCouponController wxCouponController;

    @AfterEach
    void clearTL() { ThreadLocalRequestDetail.remove(); }

    @Test
    @DisplayName("列表过滤-白名单：非白名单用户不可见")
    void testWhitelistHiddenInQueryAll() {
        // 当前用户
        PlayCustomUserInfoEntity current = new PlayCustomUserInfoEntity();
        current.setId("uid-1");
        ThreadLocalRequestDetail.setRequestDetail(current);

        // 构造两张券：一张白名单包含uid-1，一张不包含
        PlayCouponInfoEntity visible = new PlayCouponInfoEntity();
        visible.setId("c1");
        visible.setCouponOnLineState("1");
        visible.setClaimConditionType("2");
        visible.setCustomWhitelist(Collections.singletonList("uid-1"));

        PlayCouponInfoEntity hidden = new PlayCouponInfoEntity();
        hidden.setId("c2");
        hidden.setCouponOnLineState("1");
        hidden.setClaimConditionType("2");
        hidden.setCustomWhitelist(Collections.singletonList("other"));

        when(couponDetailsService.selectByCustomId("uid-1")).thenReturn(new ArrayList<>());
        when(couponInfoService.queryAll()).thenReturn(Arrays.asList(visible, hidden));

        R resp = wxCouponController.queryAll();
        @SuppressWarnings("unchecked")
        List<WxCouponReceiveReturnVo> list = (List<WxCouponReceiveReturnVo>) resp.getData();

        assertNotNull(list);
        assertEquals(1, list.size(), "非白名单券应被过滤不可见");
        assertEquals("c1", list.get(0).getId());
    }
}
