package com.ruoyi.web.modules.architecture.service.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.DisplayName;
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.architecture.domain.AppMedicationIncompatibilityGroupRow;
import com.ruoyi.web.modules.architecture.domain.AppMedicationDrugQueryVo;
import com.ruoyi.web.modules.architecture.domain.BizWithdrawalPeriodStandard;
import com.ruoyi.web.modules.architecture.mapper.AppMedicationDrugMapper;

@ExtendWith(MockitoExtension.class)
@DisplayName("AppMedicationDrugServiceImpl")
class AppMedicationDrugServiceImplTest
{
    @Mock
    private AppMedicationDrugMapper appMedicationDrugMapper;

    @InjectMocks
    private AppMedicationDrugServiceImpl service;

    @Test
    @DisplayName("模糊检索药物名列表")
    void drugNameOptions()
    {
        when(appMedicationDrugMapper.selectDistinctDrugNames(eq("青"), eq(50)))
                .thenReturn(Arrays.asList("青霉素", "头孢"));
        assertEquals(2, service.selectDrugNameOptions("青").size());
    }

    @Test
    @DisplayName("查询休药期与配伍禁忌")
    void querySuccess()
    {
        BizWithdrawalPeriodStandard row = new BizWithdrawalPeriodStandard();
        row.setDrugName("青霉素");
        row.setDrugType(1);
        row.setWithdrawalDays(7);
        row.setUsageGuide("指南");
        row.setDrugEffect("作用");
        when(appMedicationDrugMapper.selectWithdrawalByDrugName("青霉素")).thenReturn(row);
        when(appMedicationDrugMapper.selectIncompatibilityGroupsByMainDrugName("青霉素"))
                .thenReturn(Collections.singletonList(groupRow("链霉素,磺胺", null)));

        AppMedicationDrugQueryVo vo = service.queryByDrugName("青霉素");
        assertEquals("抗生素", vo.getDrugTypeName());
        assertEquals("链霉素,磺胺", vo.getIncompatibilityCompanions());
    }

    @Test
    @DisplayName("多配伍组展示带配伍结果")
    void queryMultipleGroups()
    {
        BizWithdrawalPeriodStandard row = new BizWithdrawalPeriodStandard();
        row.setDrugName("青霉素");
        row.setDrugType(1);
        row.setWithdrawalDays(7);
        row.setUsageGuide("指南");
        row.setDrugEffect("作用");
        when(appMedicationDrugMapper.selectWithdrawalByDrugName("青霉素")).thenReturn(row);
        when(appMedicationDrugMapper.selectIncompatibilityGroupsByMainDrugName("青霉素"))
                .thenReturn(Arrays.asList(
                        groupRow("链霉素,庆大霉素", "禁止合用"),
                        groupRow("维生素C", "降低疗效")));

        AppMedicationDrugQueryVo vo = service.queryByDrugName("青霉素");
        assertEquals("链霉素,庆大霉素（禁止合用）；维生素C（降低疗效）", vo.getIncompatibilityCompanions());
    }

    @Test
    @DisplayName("无禁配记录时配伍为空")
    void queryNoIncompatibility()
    {
        BizWithdrawalPeriodStandard row = new BizWithdrawalPeriodStandard();
        row.setDrugName("测试药");
        row.setDrugType(2);
        row.setWithdrawalDays(3);
        row.setUsageGuide("指南");
        row.setDrugEffect("作用");
        when(appMedicationDrugMapper.selectWithdrawalByDrugName("测试药")).thenReturn(row);
        when(appMedicationDrugMapper.selectIncompatibilityGroupsByMainDrugName("测试药"))
                .thenReturn(Collections.emptyList());

        AppMedicationDrugQueryVo vo = service.queryByDrugName("测试药");
        assertNull(vo.getIncompatibilityCompanions());
    }

    @Test
    @DisplayName("未找到休药期标准")
    void queryNotFound()
    {
        when(appMedicationDrugMapper.selectWithdrawalByDrugName("未知")).thenReturn(null);
        assertThrows(ServiceException.class, () -> service.queryByDrugName("未知"));
    }

    private static AppMedicationIncompatibilityGroupRow groupRow(String companions, String result)
    {
        AppMedicationIncompatibilityGroupRow row = new AppMedicationIncompatibilityGroupRow();
        row.setCompanionsCsv(companions);
        row.setCompatResult(result);
        return row;
    }
}
