package com.pangu.application.service;

import com.pangu.application.domain.dto.ApplicationDTO;
import com.pangu.application.domain.entity.ApiDict;
import com.pangu.application.domain.vo.ApplicationVO;
import com.pangu.common.core.page.TableDataInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
 * 应用服务测试类
 * @author 湖北新华业务中台研发团队
 */
@SpringBootTest
@Transactional // 测试完成后回滚
public class ApplicationServiceTest {

    @Autowired
    private IApplicationService applicationService;

    /**
     * 测试新增应用
     */
    @Test
    public void testInsertApplication() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("测试应用");
        dto.setContactPerson("测试联系人");
        dto.setContactPhone("13800138000");
        dto.setRemark("测试应用备注");
        dto.setApiIds(Arrays.asList(1L, 2L, 3L));

        ApplicationVO result = applicationService.insertApplication(dto);

        assertNotNull(result);
        assertNotNull(result.getAppId());
        assertNotNull(result.getAppCode());
        assertNotNull(result.getAppSecret());
        assertEquals("测试应用", result.getAppName());
        assertTrue(result.getAppCode().startsWith("YY"));
        assertEquals(32, result.getAppSecret().length());
    }

    /**
     * 测试查询应用列表
     */
    @Test
    public void testSelectApplicationList() {
        ApplicationDTO query = new ApplicationDTO();
        query.setPageNum(1);
        query.setPageSize(10);

        TableDataInfo result = applicationService.selectApplicationList(query);

        assertNotNull(result);
        assertNotNull(result.getRows());
        assertTrue(result.getTotal() >= 0);
    }

    /**
     * 测试根据应用名称查询
     */
    @Test
    public void testSelectApplicationListByName() {
        ApplicationDTO query = new ApplicationDTO();
        query.setPageNum(1);
        query.setPageSize(10);
        query.setAppName("AI智慧平台");

        TableDataInfo result = applicationService.selectApplicationList(query);

        assertNotNull(result);
        assertTrue(result.getTotal() > 0);
    }

    /**
     * 测试根据ID查询应用
     */
    @Test
    public void testGetApplicationById() {
        ApplicationVO app = applicationService.getApplicationById(1L);

        assertNotNull(app);
        assertEquals(1L, app.getAppId());
        assertEquals("AI智慧平台", app.getAppName());
        assertNotNull(app.getAppCode());
        assertNotNull(app.getAppSecret());
    }

    /**
     * 测试修改应用
     */
    @Test
    public void testUpdateApplication() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppId(1L);
        dto.setAppName("AI智慧平台（更新）");
        dto.setContactPerson("新联系人");
        dto.setContactPhone("13900139000");
        dto.setApiIds(Arrays.asList(1L, 2L));

        int result = applicationService.updateApplication(dto);

        assertEquals(1, result);

        // 验证修改结果
        ApplicationVO app = applicationService.getApplicationById(1L);
        assertEquals("AI智慧平台（更新）", app.getAppName());
        assertEquals("新联系人", app.getContactPerson());
    }

    /**
     * 测试删除应用
     */
    @Test
    public void testDeleteApplication() {
        // 先新增一个应用用于删除
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("待删除应用");
        dto.setContactPerson("联系人");
        dto.setContactPhone("13800000000");

        ApplicationVO created = applicationService.insertApplication(dto);
        assertNotNull(created);

        // 删除应用
        int result = applicationService.deleteApplication(created.getAppId());
        assertEquals(1, result);

        // 验证已删除（软删除后查询不到）
        ApplicationVO deleted = applicationService.getApplicationById(created.getAppId());
        assertNull(deleted);
    }

    /**
     * 测试重置应用密钥
     */
    @Test
    public void testResetSecret() {
        // 获取原始密钥
        ApplicationVO app = applicationService.getApplicationById(1L);
        String oldSecret = app.getAppSecret();

        // 重置密钥
        String newSecret = applicationService.resetSecret(1L);

        assertNotNull(newSecret);
        assertEquals(32, newSecret.length());
        assertNotEquals(oldSecret, newSecret);

        // 验证密钥已更新
        ApplicationVO updated = applicationService.getApplicationById(1L);
        assertEquals(newSecret, updated.getAppSecret());
    }

    /**
     * 测试获取API接口列表
     */
    @Test
    public void testGetApiList() {
        List<ApiDict> apiList = applicationService.getApiList();

        assertNotNull(apiList);
        assertTrue(apiList.size() > 0);

        // 验证API字典数据
        ApiDict api = apiList.get(0);
        assertNotNull(api.getApiId());
        assertNotNull(api.getApiCode());
        assertNotNull(api.getApiName());
        assertNotNull(api.getApiPath());
    }

    /**
     * 测试应用编码唯一性检查
     */
    @Test
    public void testCheckAppCodeUnique() {
        // 检查已存在的编码
        boolean unique = applicationService.checkAppCodeUnique("YY000001", null);
        assertFalse(unique);

        // 检查不存在的编码
        unique = applicationService.checkAppCodeUnique("YY999999", null);
        assertTrue(unique);

        // 检查已存在的编码但排除自己（编辑场景）
        unique = applicationService.checkAppCodeUnique("YY000001", 1L);
        assertTrue(unique);
    }

    /**
     * 测试应用编码生成格式
     */
    @Test
    public void testAppCodeGeneration() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("编码测试应用");
        dto.setContactPerson("测试");
        dto.setContactPhone("13800000001");

        ApplicationVO result = applicationService.insertApplication(dto);

        assertNotNull(result.getAppCode());
        // 验证编码格式：YY + 6位数字
        assertTrue(result.getAppCode().matches("YY\\d{6}"));
    }

    /**
     * 测试应用密钥生成
     */
    @Test
    public void testAppSecretGeneration() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("密钥测试应用");
        dto.setContactPerson("测试");
        dto.setContactPhone("13800000002");

        ApplicationVO result1 = applicationService.insertApplication(dto);

        dto.setAppName("密钥测试应用2");
        dto.setContactPhone("13800000003");
        ApplicationVO result2 = applicationService.insertApplication(dto);

        // 验证密钥长度
        assertEquals(32, result1.getAppSecret().length());
        assertEquals(32, result2.getAppSecret().length());

        // 验证密钥唯一
        assertNotEquals(result1.getAppSecret(), result2.getAppSecret());
    }

    /**
     * 测试接口授权保存
     */
    @Test
    public void testSaveAppApis() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("授权测试应用");
        dto.setContactPerson("测试");
        dto.setContactPhone("13800000004");
        dto.setApiIds(Arrays.asList(1L, 3L, 5L)); // 授权部分接口

        ApplicationVO result = applicationService.insertApplication(dto);

        // 查询应用详情，验证授权接口
        ApplicationVO app = applicationService.getApplicationById(result.getAppId());
        assertNotNull(app.getApiList());
        assertEquals(3, app.getApiList().size());
    }

    /**
     * 测试修改接口授权
     */
    @Test
    public void testUpdateAppApis() {
        // 先新增应用
        ApplicationDTO createDto = new ApplicationDTO();
        createDto.setAppName("更新授权测试");
        createDto.setContactPerson("测试");
        createDto.setContactPhone("13800000005");
        createDto.setApiIds(Arrays.asList(1L, 2L));

        ApplicationVO created = applicationService.insertApplication(createDto);

        // 修改授权
        ApplicationDTO updateDto = new ApplicationDTO();
        updateDto.setAppId(created.getAppId());
        updateDto.setAppName("更新授权测试");
        updateDto.setContactPerson("测试");
        updateDto.setContactPhone("13800000005");
        updateDto.setApiIds(Arrays.asList(3L, 4L, 5L, 6L)); // 修改为其他接口

        applicationService.updateApplication(updateDto);

        // 验证授权已更新
        ApplicationVO app = applicationService.getApplicationById(created.getAppId());
        assertEquals(4, app.getApiList().size());
    }

    /**
     * 测试无接口授权的应用
     */
    @Test
    public void testApplicationWithoutApis() {
        ApplicationDTO dto = new ApplicationDTO();
        dto.setAppName("无授权测试应用");
        dto.setContactPerson("测试");
        dto.setContactPhone("13800000006");
        // 不设置apiIds

        ApplicationVO result = applicationService.insertApplication(dto);
        assertNotNull(result);

        // 查询应用详情
        ApplicationVO app = applicationService.getApplicationById(result.getAppId());
        assertNotNull(app);
        // 接口列表为空或null
        assertTrue(app.getApiList() == null || app.getApiList().isEmpty());
    }
}
