package com.ruoyi.loanpricing.service;

import com.ruoyi.loanpricing.domain.dto.ModelInvokeDTO;
import com.ruoyi.loanpricing.domain.dto.PersonalLoanPricingCreateDTO;
import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow;
import com.ruoyi.loanpricing.domain.entity.ModelRetailOutputFields;
import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper;
import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper;
import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper;
import com.ruoyi.loanpricing.util.LoanPricingConverter;
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 java.util.Objects;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
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.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class LoanPricingModelServicePersonalParamsTest {

    @Mock
    private ModelService modelService;

    @Mock
    private LoanPricingWorkflowMapper loanPricingWorkflowMapper;

    @Mock
    private ModelRetailOutputFieldsMapper modelRetailOutputFieldsMapper;

    @Mock
    private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper;

    @InjectMocks
    private LoanPricingModelService loanPricingModelService;

    @Test
    void shouldRemoveLoanPurposeAndKeepLoanTermInPersonalCreateDto() throws NoSuchFieldException {
        assertThrows(NoSuchFieldException.class,
                () -> PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
        assertThrows(NoSuchFieldException.class,
                () -> PersonalLoanPricingCreateDTO.class.getDeclaredField("bizProof"));
        assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanTerm"));
    }

    @Test
    void shouldNotMapLoanPurposeAndBizProofFromPersonalDto() {
        PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
        dto.setCustIsn("CUST001");
        dto.setCustName("张三");
        dto.setGuarType("信用");
        dto.setApplyAmt("100000");
        dto.setBusinessType("新增");
        dto.setLoanTerm("3");

        LoanPricingWorkflow workflow = LoanPricingConverter.toEntity(dto);

        assertNull(workflow.getLoanPurpose());
        assertNull(workflow.getBizProof());
        assertEquals("3", workflow.getLoanTerm());
    }

    @Test
    void shouldContainLoanTermAndLoanLoopInModelInvokeDto() throws NoSuchFieldException {
        assertNotNull(ModelInvokeDTO.class.getDeclaredField("loanTerm"));
        assertNotNull(ModelInvokeDTO.class.getDeclaredField("loanLoop"));
    }

    @Test
    void shouldInvokePersonalModelWithExpectedParams() {
        LoanPricingWorkflow workflow = new LoanPricingWorkflow();
        workflow.setId(1L);
        workflow.setSerialNum("202604090001");
        workflow.setOrgCode("892000");
        workflow.setRunType("1");
        workflow.setCustIsn("CUST001");
        workflow.setCustType("个人");
        workflow.setCustName("张三");
        workflow.setIdType("身份证");
        workflow.setIdNum("110101199001011234");
        workflow.setGuarType("信用");
        workflow.setApplyAmt("100000");
        workflow.setLoanTerm("3");
        workflow.setLoanLoop("false");
        workflow.setCollThirdParty("true");
        workflow.setCollType("一类");

        ModelRetailOutputFields response = new ModelRetailOutputFields();
        response.setCalculateRate("6.15");

        when(loanPricingWorkflowMapper.selectById(1L)).thenReturn(workflow);
        when(modelService.invokePersonalModel(any())).thenReturn(response);

        loanPricingModelService.invokeModelAsync(1L);

        verify(modelService).invokePersonalModel(argThat((ModelInvokeDTO dto) ->
                Objects.equals("202604090001", dto.getSerialNum())
                        && Objects.equals("892000", dto.getOrgCode())
                        && Objects.equals("1", dto.getRunType())
                        && Objects.equals("CUST001", dto.getCustIsn())
                        && Objects.equals("个人", dto.getCustType())
                        && Objects.equals("张三", dto.getCustName())
                        && Objects.equals("身份证", dto.getIdType())
                        && Objects.equals("110101199001011234", dto.getIdNum())
                        && Objects.equals("信用", dto.getGuarType())
                        && Objects.equals("100000", dto.getApplyAmt())
                        && Objects.equals("3", dto.getLoanTerm())
                        && Objects.equals("0", dto.getLoanLoop())
                        && Objects.equals("1", dto.getCollThirdParty())
                        && Objects.equals("一类", dto.getCollType())));
    }
}
