package com.test.test.service.impl;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.test.common.utils.DateUtils;
import com.test.common.utils.http.HttpUtils;
import com.test.test.domain.TestGroup;
import com.test.test.domain.qo.TestApiListQO;
import com.test.test.service.ITestGroupService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import com.test.test.mapper.TestApiMapper;
import com.test.test.domain.TestApi;
import com.test.test.service.ITestApiService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 接口Service业务层处理
 *
 * @author xiaoe
 */
@Service
public class TestApiServiceImpl implements ITestApiService {
    @Resource
    private TestApiMapper testApiMapper;

    @Resource
    private ITestGroupService testGroupService;

    /**
     * 查询接口
     *
     * @param id 接口主键
     * @return 接口
     */
    @Override
    public TestApi selectTestApiById(Long id) {
        return testApiMapper.selectTestApiById(id);
    }

    /**
     * 查询接口列表
     *
     * @param qo 接口
     * @return 接口
     */
    @Override
    public List<TestApi> selectTestApiList(TestApiListQO qo) {
        return testApiMapper.selectTestApiList(qo);
    }

    /**
     * 新增接口
     *
     * @param testApi 接口
     * @return 结果
     */
    @Override
    public int insertTestApi(TestApi testApi) {
        testApi.setCreateTime(DateUtils.getNowDate());
        return testApiMapper.insertTestApi(testApi);
    }

    @Override
    @Transactional
    public int importSwaggerApi(String url) {
        AtomicInteger count = new AtomicInteger();
        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.sendGet(url));
        String title = jsonObject.getJSONObject("info").getString("title");
        Date createTime = DateUtils.getNowDate();
        // 设置顶级节点
        Long parentId = getGroupId(title, 0L);
        // 获取Schemas
        JSONObject schemas = jsonObject.getJSONObject("components").getJSONObject("schemas");
        // 获取所有接口
        jsonObject.getJSONObject("paths").forEach((uri, pathJson) -> {
            ((JSONObject) pathJson).forEach((method, v) -> {
                JSONObject json = (JSONObject) v;
                // 获取接口名
                String name = json.getString("summary");
                if (name == null) name = uri;
                // 获取接口分组
                String groupName = title;
                List<String> tags = json.getList("tags", String.class);
                if (!tags.isEmpty()) {
                    groupName = tags.get(0);
                }
                // 获取body
                String body = "";
                String contentType = "";
                if (json.getJSONObject("requestBody") != null) {
                    JSONObject bodyJson = json.getJSONObject("requestBody").getJSONObject("content");
                    if (bodyJson != null) {
                        Set<String> keys = bodyJson.keySet();
                        if (!keys.isEmpty()) {
                            contentType = keys.iterator().next();
                            JSONObject schema = bodyJson.getJSONObject(contentType).getJSONObject("schema");
                            body = JSONObject.toJSONString(parseSchema(schema, schemas));
                        }
                    }
                }
                // 获取Param
                String param = "[]";
                JSONObject parameters = json.getJSONObject("parameters");
                if (parameters != null) {
                    JSONObject paramsJson = parseParams(parameters, schemas);
                    JSONArray array = new JSONArray();
                    paramsJson.forEach((key, value) -> {
                        JSONObject object = new JSONObject();
                        object.put("key", key);
                        object.put("value", value);
                        array.add(object);
                    });
                    param = array.toJSONString();
                }
                // 获取header
                String header = "[]";

                TestApi testApi = new TestApi();
                testApi.setUri(uri);
                testApi.setMethod(method);
                testApi.setName(name);
                testApi.setGroupId(getGroupId(groupName, parentId));
                testApi.setBody(body);
                testApi.setParam(param);
                testApi.setHeader(header);
                testApi.setCreateTime(createTime);

                count.addAndGet(testApiMapper.insertTestApi(testApi));
            });
        });
        return count.get();
    }

    private static JSONObject parseSchema(JSONObject schema, JSONObject schemas) {
        JSONObject result = new JSONObject();

        // 如果 schema 包含 $ref，则解析引用
        if (schema.containsKey("$ref")) {
            String ref = schema.getString("$ref");
            // 去掉 #/components/schemas/ 前缀，获取引用的 schema 名称
            String schemaName = ref.replace("#/components/schemas/", "");
            JSONObject referencedSchema = schemas.getJSONObject(schemaName);
            // 递归解析引用的 schema
            return parseSchema(referencedSchema, schemas);
        }

        // 如果 schema 包含 type，则直接根据类型构建结果
        if (schema.containsKey("type")) {
            String type = schema.getString("type");
            switch (type) {
                case "integer":
                    result.put("value", 0);
                    break;
                case "string":
                    result.put("value", "string");
                    break;
                case "boolean":
                    result.put("value", false);
                    break;
                default:
                    result.put("value", type);
            }
        }

        // 如果 schema 有 properties，则遍历 properties 并递归解析
        if (schema.containsKey("properties")) {
            JSONObject properties = schema.getJSONObject("properties");
            for (Map.Entry<String, Object> entry : properties.entrySet()) {
                String key = entry.getKey();
                JSONObject propertySchema = (JSONObject) entry.getValue();
                JSONObject propertyResult = parseSchema(propertySchema, schemas);  // 递归解析每个字段
                result.put(key, propertyResult.get("value"));  // 获取解析结果的值
            }
        }

        return result;
    }

    private static JSONObject parseParams(JSONObject params, JSONObject schemas) {
        JSONObject result = new JSONObject();

        // 遍历 params 中的每个参数
        for (String key : params.keySet()) {
            // 获取当前参数的 schema 定义
            Object value = params.get(key);

            // 获取 schema
            JSONObject schema = schemas.getJSONObject(key);

            // 如果 schema 是基础类型，则直接赋值
            if (schema != null && schema.containsKey("type")) {
                String type = schema.getString("type");
                if ("string".equals(type)) {
                    result.put(key, value != null ? value : "string");  // 默认值为 "string"
                } else if ("integer".equals(type)) {
                    result.put(key, value != null ? value : 0);  // 默认值为 0
                } else if ("boolean".equals(type)) {
                    result.put(key, value != null ? value : false);  // 默认值为 false
                }
            }
            // 如果 schema 是引用类型，则递归解析该引用
            else if (schema != null && schema.containsKey("$ref")) {
                String ref = schema.getString("$ref");
                String schemaName = ref.replace("#/components/schemas/", "");
                JSONObject referencedSchema = schemas.getJSONObject(schemaName);

                // 如果引用的 schema 存在，递归解析该 schema
                if (referencedSchema != null) {
                    // 递归调用，解析引用的 schema
                    JSONObject nestedResult = parseParams(new JSONObject(), schemas);
                    result.putAll(nestedResult);
                }
            }
        }

        return result;
    }

    private Long getGroupId(String groupName, Long parentId) {
        TestGroup group = testGroupService.selectGroup(groupName, parentId, "api");
        if (group == null) {
            group = new TestGroup();
            group.setParentId(parentId);
            group.setName(groupName);
            group.setType("api");
            group.setCreateTime(DateUtils.getNowDate());
            testGroupService.insertTestGroup(group);
        }
        return group.getId();
    }

    /**
     * 修改接口
     *
     * @param testApi 接口
     * @return 结果
     */
    @Override
    public int updateTestApi(TestApi testApi) {
        testApi.setUpdateTime(DateUtils.getNowDate());
        return testApiMapper.updateTestApi(testApi);
    }

    @Override
    public int deleteTestApiByGroups(List<Long> groupIds) {
        return testApiMapper.deleteTestApiByGroups(groupIds);
    }

    /**
     * 删除接口信息
     *
     * @param id 接口主键
     * @return 结果
     */
    @Override
    public int deleteTestApiById(Long id) {
        return testApiMapper.deleteTestApiById(id);
    }
}
