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

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.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

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.industrypolicy.domain.BizSubsidyMatter;
import com.ruoyi.web.modules.industrypolicy.mapper.BizSubsidyMatterMapper;
import com.ruoyi.web.modules.industrypolicy.support.SubsidyMatterRules;

@ExtendWith(MockitoExtension.class)
@DisplayName("BizSubsidyMatterServiceImpl")
class BizSubsidyMatterServiceImplTest
{
    @Mock
    private BizSubsidyMatterMapper mapper;

    @InjectMocks
    private BizSubsidyMatterServiceImpl service;

    @Test
    @DisplayName("ZCZX-BTSX-UT-009 新增落库")
    void ut009_insert()
    {
        when(mapper.insertBizSubsidyMatter(any())).thenAnswer(inv -> {
            BizSubsidyMatter r = inv.getArgument(0);
            r.setId(1L);
            return 1;
        });
        BizSubsidyMatter row = sampleRow();
        row.setGrantStatus(null);
        assertEquals(1, service.insertBizSubsidyMatter(row));
        verify(mapper).insertBizSubsidyMatter(argThat(r ->
                r.getGrantStatus() == SubsidyMatterRules.GRANT_APPLYING && r.getPublishStatus() == 0));
    }

    @Test
    @DisplayName("ZCZX-BTSX-UT-010 修改全字段")
    void ut010_update()
    {
        BizSubsidyMatter db = sampleRow();
        db.setId(2L);
        db.setPublishStatus(0);
        when(mapper.selectBizSubsidyMatterById(2L)).thenReturn(db);
        when(mapper.updateBizSubsidyMatter(any())).thenReturn(1);
        BizSubsidyMatter in = sampleRow();
        in.setId(2L);
        in.setSubsidyName("新名称");
        in.setIntroduction("简介");
        assertEquals(1, service.updateBizSubsidyMatter(in));
    }

    @Test
    @DisplayName("ZCZX-BTSX-UT-011 状态双向变更")
    void ut011_grantStatusChange()
    {
        BizSubsidyMatter db = sampleRow();
        db.setId(3L);
        db.setGrantStatus(SubsidyMatterRules.GRANT_GRANTED);
        db.setPublishStatus(0);
        when(mapper.selectBizSubsidyMatterById(3L)).thenReturn(db);
        when(mapper.updateBizSubsidyMatter(any())).thenReturn(1);
        BizSubsidyMatter in = sampleRow();
        in.setId(3L);
        in.setGrantStatus(SubsidyMatterRules.GRANT_APPLYING);
        assertEquals(1, service.updateBizSubsidyMatter(in));
        verify(mapper).updateBizSubsidyMatter(argThat(r -> r.getGrantStatus() == SubsidyMatterRules.GRANT_APPLYING));
    }

    @Test
    @DisplayName("ZCZX-BTSX-UT-012 修改缺明细拒绝")
    void ut012_updateMissingDetail()
    {
        BizSubsidyMatter in = sampleRow();
        in.setId(4L);
        in.setDetailFileUrl(null);
        in.setDetailFilePath(null);
        in.setDetailFileName(null);
        assertThrows(ServiceException.class, () -> service.updateBizSubsidyMatter(in));
        verify(mapper, never()).updateBizSubsidyMatter(any());
        verify(mapper, never()).selectBizSubsidyMatterById(any());
    }

    @Test
    @DisplayName("已发布禁止修改")
    void updatePublished()
    {
        BizSubsidyMatter db = sampleRow();
        db.setId(9L);
        db.setPublishStatus(1);
        when(mapper.selectBizSubsidyMatterById(9L)).thenReturn(db);
        BizSubsidyMatter in = sampleRow();
        in.setId(9L);
        assertThrows(ServiceException.class, () -> service.updateBizSubsidyMatter(in));
    }

    @Test
    @DisplayName("ZCZX-BTSX-UT-015 删除")
    void ut015_delete()
    {
        BizSubsidyMatter db = sampleRow();
        db.setId(5L);
        db.setPublishStatus(0);
        when(mapper.selectBizSubsidyMatterById(5L)).thenReturn(db);
        when(mapper.deleteBizSubsidyMatterByIds(any())).thenReturn(1);
        assertEquals(1, service.deleteBizSubsidyMatterByIds(new Long[] { 5L }));
    }

    @Test
    @DisplayName("发布成功")
    void publish()
    {
        BizSubsidyMatter db = sampleRow();
        db.setId(3L);
        db.setPublishStatus(0);
        when(mapper.selectBizSubsidyMatterById(3L)).thenReturn(db);
        when(mapper.updateBizSubsidyMatter(any())).thenReturn(1);
        assertEquals(1, service.publish(3L));
        verify(mapper).updateBizSubsidyMatter(argThat(r -> r.getPublishStatus() == 1 && r.getPublishTime() != null));
    }

    private static BizSubsidyMatter sampleRow()
    {
        BizSubsidyMatter r = new BizSubsidyMatter();
        r.setSubsidyName("农业补贴");
        r.setGrantStatus(SubsidyMatterRules.GRANT_APPLYING);
        r.setDetailFileUrl("http://localhost/a.pdf");
        r.setDetailFilePath("/profile/upload/a.pdf");
        r.setDetailFileName("a.pdf");
        return r;
    }
}
