package com.njcn.gather.device.types.service.impl;

import com.njcn.gather.device.types.mapper.CsDevTypeMapper;
import com.njcn.gather.device.types.pojo.param.DeviceTypeParam;
import com.njcn.gather.device.types.pojo.po.CsDevTypePO;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import java.util.Collections;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class DeviceTypeServiceImplTest {

    private final CsDevTypeMapper csDevTypeMapper = mock(CsDevTypeMapper.class);
    private final DeviceTypeServiceImpl service = new DeviceTypeServiceImpl(csDevTypeMapper);

    @Test
    void listDeviceTypesShouldTrimKeywordBeforeQuery() {
        service.listDeviceTypes("  PQ装置  ");

        verify(csDevTypeMapper).selectDeviceTypeCheckList(eq("PQ装置"));
    }

    @Test
    void addDeviceTypeShouldInsertEnabledRecord() {
        DeviceTypeParam param = buildParam("设备类型A");
        when(csDevTypeMapper.insert(any(CsDevTypePO.class))).thenReturn(1);

        boolean result = service.addDeviceType(param);

        ArgumentCaptor<CsDevTypePO> captor = ArgumentCaptor.forClass(CsDevTypePO.class);
        verify(csDevTypeMapper).insert(captor.capture());
        Assertions.assertTrue(result);
        Assertions.assertEquals("10", captor.getValue().getPower());
        Assertions.assertEquals("设备类型A", captor.getValue().getName());
        Assertions.assertEquals(1, captor.getValue().getState());
        Assertions.assertNotNull(captor.getValue().getId());
        Assertions.assertNotNull(captor.getValue().getCreateTime());
    }

    @Test
    void updateDeviceTypeShouldRejectDeletedRecord() {
        DeviceTypeParam.UpdateParam param = new DeviceTypeParam.UpdateParam();
        param.setId("dev-type-001");
        param.setName("设备类型A");

        CsDevTypePO deleted = new CsDevTypePO();
        deleted.setId("dev-type-001");
        deleted.setState(0);
        when(csDevTypeMapper.selectById(eq("dev-type-001"))).thenReturn(deleted);

        IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class,
                () -> service.updateDeviceType(param));

        Assertions.assertEquals("设备类型不存在或已删除", exception.getMessage());
    }

    @Test
    void deleteDeviceTypeShouldMarkRecordDeleted() {
        when(csDevTypeMapper.update(any(CsDevTypePO.class), any())).thenReturn(1);

        boolean result = service.deleteDeviceType(Collections.singletonList("dev-type-001"));

        ArgumentCaptor<CsDevTypePO> captor = ArgumentCaptor.forClass(CsDevTypePO.class);
        verify(csDevTypeMapper).update(captor.capture(), any());
        Assertions.assertTrue(result);
        Assertions.assertEquals(0, captor.getValue().getState());
        Assertions.assertNotNull(captor.getValue().getUpdateTime());
    }

    private DeviceTypeParam buildParam(String name) {
        DeviceTypeParam param = new DeviceTypeParam();
        param.setName(name);
        param.setIcd("icd-001");
        param.setPower("10");
        param.setDevVolt(10.0F);
        param.setDevCurr(5.0F);
        param.setDevChns(4);
        param.setWaveCmd("cmd");
        param.setReportName("report");
        return param;
    }
}
