package com.dora.util;

import com.dora.mapper.GiftCodeUsageMapper;
import com.dora.mapper.OrderMapper;
import com.dora.mapper.UserMapper;
import com.dora.entity.User;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDateTime;

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

/**
 * MembershipUtil 单元测试
 */
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class MembershipUtilTest {

    @Mock
    private GiftCodeUsageMapper giftCodeUsageMapper;

    @Mock
    private OrderMapper orderMapper;

    @Mock
    private UserMapper userMapper;

    private MembershipUtil membershipUtil;

    @BeforeEach
    void setUp() {
        membershipUtil = new MembershipUtil(giftCodeUsageMapper, orderMapper, userMapper);
    }

    @Test
    void testIsExchangeMemberWithoutRevenue_NullUserId() {
        // 测试用户ID为null的情况
        assertFalse(membershipUtil.isExchangeMemberWithoutRevenue(null));
    }

    @Test
    void testIsExchangeMemberWithoutRevenue_PureExchangeMember() {
        // 测试纯兑换会员（有兑换记录但没有付费记录）
        Long userId = 3L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(1);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(0);

        assertTrue(membershipUtil.isExchangeMemberWithoutRevenue(userId));
    }

    @Test
    void testIsExchangeMemberWithoutRevenue_ExchangeMemberWithPaidOrder() {
        // 测试有兑换记录且有付费记录的用户（兑换后付费会员）
        Long userId = 2L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(1);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(1);

        assertFalse(membershipUtil.isExchangeMemberWithoutRevenue(userId));
    }

    @Test
    void testIsGiftMember_RecentVipUser() {
        // 测试赠送会员：2天内注册的VIP用户，无付费和兑换记录
        Long userId = 10L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusHours(12)); // 12小时前注册

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(0);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(0);

        assertTrue(membershipUtil.isGiftMember(userId));
        assertTrue(membershipUtil.isExchangeMemberWithoutRevenue(userId)); // 赠送会员不参与收益
        assertEquals("赠送会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testIsGiftMember_OldVipUser() {
        // 测试2天外注册的VIP用户，无付费和兑换记录
        Long userId = 11L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(5)); // 5天前注册

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(0);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(0);

        assertFalse(membershipUtil.isGiftMember(userId)); // 不是赠送会员
        assertFalse(membershipUtil.isExchangeMemberWithoutRevenue(userId)); // 可以参与收益
        assertEquals("非会员", membershipUtil.getMembershipTypeDescription(userId)); // 2天外无记录视为非会员
    }

    @Test
    void testGetMembershipTypeDescription_NonMember() {
        // 测试非会员用户
        Long userId = 4L;
        User user = new User();
        user.setId(userId);
        user.setRole(1); // 普通用户
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);

        assertEquals("非会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testGetMembershipTypeDescription_PaidMember() {
        // 测试付费会员
        Long userId = 5L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(0);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(1);

        assertEquals("付费会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testGetMembershipTypeDescription_ExchangeAfterPaidMember() {
        // 测试兑换后付费会员
        Long userId = 6L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(1);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(1);

        assertEquals("兑换后付费会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testGetMembershipTypeDescription_PureExchangeMember() {
        // 测试纯兑换会员
        Long userId = 7L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusDays(10));

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(1);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(0);

        assertEquals("纯兑换会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testGetMembershipTypeDescription_GiftMember() {
        // 测试赠送会员的类型描述
        Long userId = 12L;
        User user = new User();
        user.setId(userId);
        user.setRole(2); // VIP
        user.setCreateTime(LocalDateTime.now().minusHours(6)); // 6小时前注册

        when(userMapper.selectById(userId)).thenReturn(user);
        when(giftCodeUsageMapper.countByUserAndType(userId, 2)).thenReturn(0);
        when(orderMapper.countSuccessOrdersByUserId(userId)).thenReturn(0);

        assertEquals("赠送会员", membershipUtil.getMembershipTypeDescription(userId));
    }

    @Test
    void testGetMembershipTypeDescription_NullUserId() {
        // 测试用户ID为null的情况
        assertEquals("非会员", membershipUtil.getMembershipTypeDescription(null));
    }

    @Test
    void testIsExchangeMemberWithoutRevenue_ExceptionHandling() {
        // 测试异常处理
        Long userId = 8L;
        when(giftCodeUsageMapper.countByUserAndType(userId, 2))
                .thenThrow(new RuntimeException("Database error"));

        // 异常情况下应该返回false（允许参与收益）
        assertFalse(membershipUtil.isExchangeMemberWithoutRevenue(userId));
    }
}