package com.hotwj.platform.integration.ocr.baidu;

import com.hotwj.platform.config.vehicleType.mapper.HotVehicleTypeMapper;
import com.hotwj.platform.integration.ocr.baidu.domain.bo.HandwritingRecognizeBo;
import com.hotwj.platform.integration.ocr.baidu.domain.vo.HandwritingOcrVo;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.DictService;
import org.dromara.system.service.ISysOssService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class BaiduOcrServiceImplTest {

    @Mock
    private ISysOssService ossService;
    @Mock
    private DictService dictService;
    @Mock
    private HotVehicleTypeMapper vehicleTypeMapper;
    @Mock
    private BaiduOcrHttpClient httpClient;

    private BaiduOcrServiceImpl service;
    private BaiduOcrProperties properties;

    @BeforeEach
    void setUp() {
        properties = new BaiduOcrProperties();
        properties.setApiKey("ak");
        properties.setSecretKey("sk");
        properties.setTokenUrl("https://token");
        properties.setHandwritingUrl("https://handwriting");
        properties.setRetryTimes(2);
        properties.setTokenTimeoutMs(2000);
        properties.setHandwritingTimeoutMs(5000);
        service = new BaiduOcrServiceImpl(properties, ossService, dictService, vehicleTypeMapper, httpClient);
    }

    @Test
    void recognizeHandwriting_containsMatch_shouldSuccess() {
        when(httpClient.postForm(eq("https://token"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(200, "{\"access_token\":\"token-1\",\"expires_in\":1800}"));
        when(httpClient.postForm(startsWith("https://handwriting"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(200, "{\"words_result_num\":2,\"words_result\":[{\"words\":\"张三\"},{\"words\":\"签名\"}]}"));
        HandwritingRecognizeBo bo = new HandwritingRecognizeBo();
        bo.setImage("data:image/png;base64,aGVsbG8=");
        bo.setTargetName("张三");
        bo.setMatchMode("contains");
        bo.setSaveImage(false);
        HandwritingOcrVo vo = service.recognizeHandwriting(bo);
        assertEquals(2, vo.getWordsResultNum());
        assertEquals("张三签名", vo.getWords());
        assertEquals(true, vo.getMatched());
        assertEquals("匹配成功", vo.getReason());
    }

    @Test
    void recognizeHandwriting_serverError_shouldRetryThenSuccess() {
        when(httpClient.postForm(eq("https://token"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(200, "{\"access_token\":\"token-2\",\"expires_in\":1800}"));
        when(httpClient.postForm(contains("https://handwriting"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(500, "server error"))
                .thenReturn(new BaiduOcrHttpResponse(500, "server error"))
                .thenReturn(new BaiduOcrHttpResponse(200, "{\"words_result_num\":1,\"words_result\":[{\"words\":\"李四\"}]}"));
        HandwritingRecognizeBo bo = new HandwritingRecognizeBo();
        bo.setImage("aGVsbG8=");
        bo.setTargetName("李四");
        bo.setMatchMode("strict");
        bo.setSaveImage(false);
        HandwritingOcrVo vo = service.recognizeHandwriting(bo);
        assertTrue(Boolean.TRUE.equals(vo.getMatched()));
        verify(httpClient, times(3)).postForm(contains("https://handwriting"), anyString(), anyInt());
    }

    @Test
    void recognizeHandwriting_clientError_shouldFailWithoutRetry() {
        when(httpClient.postForm(eq("https://token"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(200, "{\"access_token\":\"token-3\",\"expires_in\":1800}"));
        when(httpClient.postForm(contains("https://handwriting"), anyString(), anyInt()))
                .thenReturn(new BaiduOcrHttpResponse(401, "unauthorized"));
        HandwritingRecognizeBo bo = new HandwritingRecognizeBo();
        bo.setImage("aGVsbG8=");
        ServiceException ex = assertThrows(ServiceException.class, () -> service.recognizeHandwriting(bo));
        assertTrue(ex.getMessage().contains("第三方调用失败"));
        verify(httpClient, times(1)).postForm(contains("https://handwriting"), anyString(), anyInt());
    }
}
