package com.ruoyi.asset.service.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.ruoyi.asset.domain.AmsWarehouse;
import com.ruoyi.asset.mapper.AmsWarehouseMapper;
import com.ruoyi.common.exception.ServiceException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class AmsWarehouseServiceImplTest
{
    @Mock
    private AmsWarehouseMapper amsWarehouseMapper;

    @InjectMocks
    private AmsWarehouseServiceImpl service;

    @Test
    void insertAmsWarehouseShouldSetAssetDefaults()
    {
        AmsWarehouse warehouse = new AmsWarehouse();
        warehouse.setWarehouseCode("WH001");
        warehouse.setWarehouseName("主仓");
        when(amsWarehouseMapper.insertAmsWarehouse(any(AmsWarehouse.class))).thenReturn(1);

        int rows = service.insertAmsWarehouse(warehouse);

        ArgumentCaptor<AmsWarehouse> captor = ArgumentCaptor.forClass(AmsWarehouse.class);
        verify(amsWarehouseMapper).insertAmsWarehouse(captor.capture());
        assertEquals(1, rows);
        assertEquals("Y", captor.getValue().getEnabled());
        assertEquals("0", captor.getValue().getDelFlag());
        assertNotNull(captor.getValue().getCreateTime());
    }

    @Test
    void deleteAmsWarehouseByWarehouseIdsShouldRejectReferencedWarehouse()
    {
        AmsWarehouse warehouse = new AmsWarehouse();
        warehouse.setWarehouseId(10L);
        warehouse.setWarehouseName("主仓");
        when(amsWarehouseMapper.selectAmsWarehouseByWarehouseId(10L)).thenReturn(warehouse);
        when(amsWarehouseMapper.countWarehouseReferences(10L)).thenReturn(1);

        ServiceException exception = assertThrows(ServiceException.class,
                () -> service.deleteAmsWarehouseByWarehouseIds("10"));

        assertTrue(exception.getMessage().contains("主仓"));
        assertTrue(exception.getMessage().contains("不允许删除"));
        verify(amsWarehouseMapper, never()).deleteAmsWarehouseByWarehouseIds(any());
    }

    @Test
    void deleteAmsWarehouseByWarehouseIdShouldRejectReferencedWarehouse()
    {
        AmsWarehouse warehouse = new AmsWarehouse();
        warehouse.setWarehouseId(10L);
        warehouse.setWarehouseName("主仓");
        when(amsWarehouseMapper.selectAmsWarehouseByWarehouseId(10L)).thenReturn(warehouse);
        when(amsWarehouseMapper.countWarehouseReferences(10L)).thenReturn(1);

        ServiceException exception = assertThrows(ServiceException.class,
                () -> service.deleteAmsWarehouseByWarehouseId(10L));

        assertTrue(exception.getMessage().contains("主仓"));
        assertTrue(exception.getMessage().contains("不允许删除"));
        verify(amsWarehouseMapper, never()).deleteAmsWarehouseByWarehouseId(10L);
    }

    @Test
    void checkWarehouseCodeUniqueShouldIgnoreCurrentWarehouse()
    {
        AmsWarehouse existing = new AmsWarehouse();
        existing.setWarehouseId(10L);
        existing.setWarehouseCode("WH001");
        when(amsWarehouseMapper.checkWarehouseCodeUnique("WH001")).thenReturn(existing);

        AmsWarehouse current = new AmsWarehouse();
        current.setWarehouseId(10L);
        current.setWarehouseCode("WH001");

        AmsWarehouse other = new AmsWarehouse();
        other.setWarehouseId(11L);
        other.setWarehouseCode("WH001");

        assertTrue(service.checkWarehouseCodeUnique(current));
        assertFalse(service.checkWarehouseCodeUnique(other));
    }
}
