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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
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.account.constant.MerchantEmployeeConstants;
import com.ruoyi.web.modules.account.mapper.MerchantEmployeeMapper;
import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
import com.ruoyi.web.modules.store.domain.BizShop;
import com.ruoyi.web.modules.store.facade.IShopGlobalConfigFacade;
import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;
import com.ruoyi.web.modules.store.mapper.BizShopMapper;

@ExtendWith(MockitoExtension.class)
class MerchantEmployeeSupportTest
{
    @Mock
    private BizMerchantAccountMapper merchantAccountMapper;

    @Mock
    private MerchantEmployeeMapper merchantEmployeeMapper;

    @Mock
    private BizShopMapper shopMapper;

    @Mock
    private IShopGlobalConfigFacade shopGlobalConfigFacade;

    @InjectMocks
    private MerchantEmployeeSupport support;

    @Test
    void requireMerchantId_rejectsNonAdmin()
    {
        when(merchantAccountMapper.selectMerchantAdminByUserId(99L)).thenReturn(null);

        ServiceException ex = assertThrows(ServiceException.class, () -> support.requireMerchantId(99L));

        assertEquals(MerchantEmployeeConstants.MSG_MERCHANT_ADMIN_ONLY, ex.getMessage());
    }

    @Test
    void assertQuotaAvailable_rejectsWhenFull()
    {
        when(merchantAccountMapper.countEmployeesByMerchantId(1L)).thenReturn(5);
        when(shopGlobalConfigFacade.getMaxSubAdmin()).thenReturn(5);

        ServiceException ex = assertThrows(ServiceException.class, () -> support.assertQuotaAvailable(1L));

        assertEquals("子管理员人数已达上限（5），请联系平台调整店铺设置", ex.getMessage());
    }

    @Test
    void assertRolesBelongToShop_rejectsEmpty()
    {
        ServiceException ex = assertThrows(ServiceException.class,
                () -> support.assertRolesBelongToShop(101L, new Long[0]));

        assertEquals(MerchantEmployeeConstants.MSG_ROLE_REQUIRED, ex.getMessage());
    }

    @Test
    void assertRolesBelongToShop_rejectsInvalid()
    {
        when(merchantEmployeeMapper.countValidShopRoles(101L, new Long[] { 201L, 301L })).thenReturn(1);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> support.assertRolesBelongToShop(101L, new Long[] { 201L, 301L }));

        assertEquals(MerchantEmployeeConstants.MSG_ROLE_INVALID, ex.getMessage());
    }

    @Test
    void assertShopBelongsToMerchant_rejectsForeignShop()
    {
        BizShop shop = new BizShop();
        shop.setShopId(101L);
        shop.setMerchantId(2L);
        shop.setDelFlag("0");
        when(shopMapper.selectById(101L)).thenReturn(shop);

        ServiceException ex = assertThrows(ServiceException.class,
                () -> support.assertShopBelongsToMerchant(1L, 101L));

        assertEquals(MerchantEmployeeConstants.MSG_SHOP_INVALID, ex.getMessage());
    }

    @Test
    void requireMerchantId_returnsMerchantId()
    {
        BizMerchantAccount admin = new BizMerchantAccount();
        admin.setMerchantId(1L);
        when(merchantAccountMapper.selectMerchantAdminByUserId(10L)).thenReturn(admin);

        assertEquals(1L, support.requireMerchantId(10L));
    }
}
