package com.ruoyi.web.modules.account.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.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.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.web.modules.account.constant.MemberConstants;
import com.ruoyi.web.modules.account.domain.BizMember;
import com.ruoyi.web.modules.account.domain.BizMemberLevel;
import com.ruoyi.web.modules.account.dto.MemberOrderQueryDTO;
import com.ruoyi.web.modules.account.dto.MemberStatusDTO;
import com.ruoyi.web.modules.account.facade.IOrderFacade;
import com.ruoyi.web.modules.account.mapper.BizMemberAddressMapper;
import com.ruoyi.web.modules.account.mapper.BizMemberLevelMapper;
import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
import com.ruoyi.web.modules.account.service.impl.MemberServiceImpl;
import com.ruoyi.web.modules.account.vo.MemberDetailVO;
import com.ruoyi.web.modules.account.vo.MemberListVO;

@ExtendWith(MockitoExtension.class)
class MemberServiceImplTest
{
    @Mock
    private BizMemberMapper memberMapper;

    @Mock
    private BizMemberLevelMapper memberLevelMapper;

    @Mock
    private BizMemberAddressMapper addressMapper;

    @Mock
    private IOrderFacade orderFacade;

    @InjectMocks
    private MemberServiceImpl memberService;

    @Test
    void updateStatus_success()
    {
        BizMember member = new BizMember();
        member.setMemberId(1L);
        when(memberMapper.selectById(1L)).thenReturn(member);

        MemberStatusDTO dto = new MemberStatusDTO();
        dto.setStatus(MemberConstants.STATUS_DISABLED);
        memberService.updateMemberStatus(1L, dto, "admin");

        verify(memberMapper).updateStatus(1L, MemberConstants.STATUS_DISABLED, "admin");
    }

    @Test
    void selectMemberOrders_delegatesOrderFacade()
    {
        when(memberMapper.selectById(1L)).thenReturn(new BizMember());
        TableDataInfo table = new TableDataInfo();
        table.setRows(Collections.emptyList());
        table.setTotal(0L);
        when(orderFacade.pageOrdersByMember(eq(1L), any(MemberOrderQueryDTO.class))).thenReturn(table);

        memberService.selectMemberOrders(1L, new MemberOrderQueryDTO());

        verify(orderFacade).pageOrdersByMember(eq(1L), any(MemberOrderQueryDTO.class));
    }

    @Test
    void selectMemberDetail_notFound()
    {
        when(memberMapper.selectById(99L)).thenReturn(null);
        assertThrows(ServiceException.class, () -> memberService.selectMemberDetail(99L));
    }

    @Test
    void selectMemberDetail_usesBizMemberLevelName()
    {
        BizMember member = new BizMember();
        member.setMemberId(1L);
        member.setMemberCode("user01");
        member.setMemberLevel(0);
        member.setStatus(MemberConstants.STATUS_ENABLED);
        when(memberMapper.selectById(1L)).thenReturn(member);
        when(addressMapper.selectByMemberId(1L)).thenReturn(Collections.emptyList());

        BizMemberLevel level = new BizMemberLevel();
        level.setLevelNo(0);
        level.setLevelName("普通会员");
        when(memberLevelMapper.selectEnabledList()).thenReturn(Collections.singletonList(level));

        MemberDetailVO vo = memberService.selectMemberDetail(1L);
        assertEquals("普通会员", vo.getMemberLevelLabel());
    }

    @Test
    void selectMemberLevelList_returnsEnabledLevels()
    {
        BizMemberLevel level = new BizMemberLevel();
        level.setLevelId(1L);
        level.setLevelNo(1);
        level.setLevelName("黄金会员");
        when(memberLevelMapper.selectEnabledList()).thenReturn(Collections.singletonList(level));

        assertEquals(1, memberService.selectMemberLevelList().size());
        assertEquals("黄金会员", memberService.selectMemberLevelList().get(0).getLevelName());
    }
}
