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 java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
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.BizSubsidyGrantRecord;
import com.ruoyi.web.modules.industrypolicy.mapper.BizSubsidyGrantRecordMapper;

@ExtendWith(MockitoExtension.class)
@DisplayName("BizSubsidyGrantRecordServiceImpl")
class BizSubsidyGrantRecordServiceImplTest
{
    @Mock
    private BizSubsidyGrantRecordMapper mapper;

    @InjectMocks
    private BizSubsidyGrantRecordServiceImpl service;

    @Test
    @DisplayName("ZCZX-BTJL-UT-010 新增落库")
    void ut010_insert()
    {
        when(mapper.insertBizSubsidyGrantRecord(any())).thenAnswer(inv -> {
            BizSubsidyGrantRecord r = inv.getArgument(0);
            r.setId(1L);
            return 1;
        });
        BizSubsidyGrantRecord row = sampleRow();
        assertEquals(1, service.insertBizSubsidyGrantRecord(row));
        verify(mapper).insertBizSubsidyGrantRecord(any());
    }

    @Test
    @DisplayName("ZCZX-BTJL-UT-011 修改全字段")
    void ut011_update()
    {
        BizSubsidyGrantRecord db = sampleRow();
        db.setId(2L);
        when(mapper.selectBizSubsidyGrantRecordById(2L)).thenReturn(db);
        when(mapper.updateBizSubsidyGrantRecord(any())).thenReturn(1);
        BizSubsidyGrantRecord in = sampleRow();
        in.setId(2L);
        in.setSubsidyAmount(new BigDecimal("2000.50"));
        assertEquals(1, service.updateBizSubsidyGrantRecord(in));
        verify(mapper).updateBizSubsidyGrantRecord(any());
    }

    @Test
    @DisplayName("ZCZX-BTJL-UT-012 删除记录")
    void ut012_delete()
    {
        when(mapper.deleteBizSubsidyGrantRecordByIds(any())).thenReturn(1);
        assertEquals(1, service.deleteBizSubsidyGrantRecordByIds(new Long[] { 5L, 6L }));
        verify(mapper).deleteBizSubsidyGrantRecordByIds(any());
    }

    @Test
    @DisplayName("列表日期区间非法")
    void listInvalidDateRange()
    {
        BizSubsidyGrantRecord query = new BizSubsidyGrantRecord();
        query.setStartDate("2025-12-01");
        query.setEndDate("2025-01-01");
        assertThrows(ServiceException.class, () -> service.selectBizSubsidyGrantRecordList(query));
        verify(mapper, never()).selectBizSubsidyGrantRecordList(any());
    }

    @Test
    @DisplayName("修改时脱敏身份证合并原值")
    void updateWithMaskedIdCard()
    {
        BizSubsidyGrantRecord db = sampleRow();
        db.setId(3L);
        when(mapper.selectBizSubsidyGrantRecordById(3L)).thenReturn(db);
        when(mapper.updateBizSubsidyGrantRecord(any())).thenReturn(1);
        BizSubsidyGrantRecord in = sampleRow();
        in.setId(3L);
        in.setIdCard("1101**********002X");
        in.setContactPhone("138****8000");
        in.setBankAccount("************7890");
        assertEquals(1, service.updateBizSubsidyGrantRecord(in));
        verify(mapper).updateBizSubsidyGrantRecord(argThat(r ->
                "11010519491231002X".equals(r.getIdCard())
                        && "13800138000".equals(r.getContactPhone())
                        && "6222021234567890".equals(r.getBankAccount())));
    }

    @Test
    @DisplayName("修改不存在记录")
    void updateMissing()
    {
        when(mapper.selectBizSubsidyGrantRecordById(99L)).thenReturn(null);
        BizSubsidyGrantRecord in = sampleRow();
        in.setId(99L);
        assertThrows(ServiceException.class, () -> service.updateBizSubsidyGrantRecord(in));
    }

    private static BizSubsidyGrantRecord sampleRow()
    {
        BizSubsidyGrantRecord r = new BizSubsidyGrantRecord();
        r.setSubsidyProjectName("农业补贴");
        r.setSubsidyType(1);
        r.setRecipientName("张三");
        r.setIdCard("11010519491231002X");
        r.setContactPhone("13800138000");
        r.setBankAccount("6222021234567890");
        r.setSubsidyAmount(new BigDecimal("1000.00"));
        r.setGrantDate(new Date());
        return r;
    }
}
