/**
 * 集成测试 MCP 服务器工具函数
 */
import os from 'os';
import axios, { AxiosInstance } from 'axios';
import puppeteer from 'puppeteer-core';

// 全局配置类型定义
interface Config {
    loginUrl: string;
    api: {
        baseUrl: string;
        featureList: string;
        submitTest: string;
        pipelineBranches: string;
        pipelineIntegrate: string;
        headers: {
            'content-type': string;
            'group-id': string;
            [key: string]: string;
        };
        pipeline: {
            taskId: string;
            pipelineId: string;
            stageId: string;
        };
    };
    credentials: {
        selectors: {
            usernameInput: string;
            passwordInput: string;
            submitButton: string;
        };
    };
    cookieFields: string[];
    loginSuccessCondition: {
        urlIncludes?: string;
        elementExists?: string;
    };
}

// 响应类型定义
export interface ApiResponse<T = any> {
    code: number;
    msg: string;
    data: T;
}

export interface FeatureItem {
    id: string;
    name: string;
    branch_name: string;
    status: string;
    [key: string]: any;
}

export interface FeatureListResponse {
    items: FeatureItem[];
    total: number;
    [key: string]: any;
}

export interface PipelineBranch {
    id: string;
    name: string;
    status: string;
    [key: string]: any;
}

export interface PipelineBranchesResponse {
    items: PipelineBranch[];
    total: number;
    [key: string]: any;
}

export interface IntegrationTestResult {
    success: boolean;
    branch?: string;
    feature?: {
        id: string;
        name: string;
        branch_name: string;
        status: string;
    };
    submit?: {
        code: number;
        msg: string;
        success: any;
    };
    pipeline?: {
        id: string;
        name: string;
        status: string;
    };
    integrate?: {
        code: number;
        msg: string;
        success: any;
    };
    error?: string;
}

// 全局配置
export const CONFIG: Config = {
    // 登录页面URL
    loginUrl: process.env.MCP_API_BASE_URL || '',

    // API配置
    api: {
        baseUrl: process.env.MCP_API_BASE_URL || '',
        featureList: "/brapi/feature/list",
        submitTest: "/brapi/feature/submit_test",
        pipelineBranches: "/plapi/branch/get_feature_list",
        pipelineIntegrate: "/plapi/stage/integrate",
        headers: {
            "content-type": "application/json",
            "group-id": "3a079c60-d2ec-9e36-0135-6112ed2fe6ed",
        },
        pipeline: {
            taskId: "3a1277fd-8c79-6c90-b9a7-ae75a80b472a",
            pipelineId: "3a1277f8-a6c1-1c75-7428-4ecd9f1617e7",
            stageId: "3a1277fd-8c5f-3fca-12f1-81799faf345d",
        },
    },

    // 登录凭证
    credentials: {
        selectors: {
            usernameInput: ".login-user",
            passwordInput: ".login-pwd",
            submitButton: ".login-button",
        },
    },

    // 需要获取的cookie字段
    cookieFields: ["token"],

    // 登录成功后的判断条件
    loginSuccessCondition: {
        urlIncludes: "/feature",
        elementExists: ".ant-avatar",
    },
};

/**
 * 获取登录凭证
 * @returns 返回用户名和密码
 * @throws 如果环境变量未设置则抛出错误
 */
export function getCredentials(): { username: string; password: string } {
    const username = process.env.MCP_USERNAME;
    const password = process.env.MCP_PASSWORD;
    const baseUrl = process.env.MCP_API_BASE_URL;

    if (!username || !password) {
        throw new Error('环境变量 MCP_USERNAME 或 MCP_PASSWORD 未设置，请先设置环境变量');
    }

    if (!baseUrl) {
        throw new Error('环境变量 MCP_API_BASE_URL 未设置，请先设置环境变量');
    }

    return { username, password };
}

export function createApiClient(token: string): AxiosInstance {
    const client = axios.create({
        baseURL: CONFIG.api.baseUrl,
        headers: {
            ...CONFIG.api.headers,
            Cookie: `token=${token}`,
        },
    });

    client.interceptors.response.use(
        (response) => response.data,
        (error) => {
            throw new Error(
                `API请求失败: ${error.response?.data?.msg || error.message}`
            );
        }
    );

    return client;
}

export async function getFeatureList(apiClient: AxiosInstance, branchName: string): Promise<ApiResponse<FeatureListResponse>> {
    const params = {
        page_size: 100,
        page: 1,
        show_myself: 1,
        name: branchName,
    };

    const response = await apiClient.get<any, ApiResponse<FeatureListResponse>>(CONFIG.api.featureList, { params });

    if (response.code !== 0) {
        throw new Error(response.msg || "获取特性列表失败");
    }

    if (!response.data.items?.length) {
        throw new Error(`未找到分支 ${branchName} 对应的特性数据`);
    }

    return response;
}

export async function submitFeatureToTest(apiClient: AxiosInstance, featureId: string): Promise<ApiResponse<any>> {
    const data = {
        id: featureId,
        action: "submit_test",
        info: "1",
    };

    const response = await apiClient.post<any, ApiResponse<any>>(CONFIG.api.submitTest, data);

    if (response.code === 10000) {
        throw new Error(response.msg || "提测失败");
    }

    if (response.code !== 0) {
        throw new Error(response.msg || "提交特性到测试失败");
    }

    return response;
}

export async function getPipelineBranches(apiClient: AxiosInstance, branchName: string): Promise<ApiResponse<PipelineBranchesResponse>> {
    const params = {
        task_id: CONFIG.api.pipeline.taskId,
        pipeline_id: CONFIG.api.pipeline.pipelineId,
        page: 1,
        page_size: 10,
        name: branchName,
    };

    const response = await apiClient.get<any, ApiResponse<PipelineBranchesResponse>>(CONFIG.api.pipelineBranches, {
        params,
    });

    if (response.code !== 0) {
        throw new Error(response.msg || "获取流水线分支列表失败");
    }

    if (!response.data.items?.length) {
        throw new Error(`未找到分支 ${branchName} 对应的流水线数据`);
    }

    return response;
}

export async function integratePipeline(apiClient: AxiosInstance, featureId: string): Promise<ApiResponse<any>> {
    const data = {
        pipeline_id: CONFIG.api.pipeline.pipelineId,
        stage_id: CONFIG.api.pipeline.stageId,
        task_id: CONFIG.api.pipeline.taskId,
        feature_ids: featureId,
    };

    const response = await apiClient.post<any, ApiResponse<any>>(CONFIG.api.pipelineIntegrate, data);

    if (response.code !== 0) {
        throw new Error(response.msg || "执行流水线集成失败");
    }

    return response;
}

export function getEdgePath(): string {
    const platform = os.platform();
    switch (platform) {
        case "win32":
            return "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
        case "darwin":
            return "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge";
        case "linux":
            return "/usr/bin/microsoft-edge";
        default:
            throw new Error(`不支持的操作系统: ${platform}`);
    }
}

export async function loginAndGetCookies(): Promise<Record<string, string>> {
    let browserInstance = null;
    try {
        const launchOptions = {
            headless: true,
            defaultViewport: {
                width: 1920,
                height: 1080,
            },
            args: [
                "--disable-gpu",
                "--disable-dev-shm-usage",
                "--disable-setuid-sandbox",
                "--no-sandbox",
            ],
            executablePath: getEdgePath(),
        };

        // 获取登录凭证
        const { username, password } = getCredentials();

        browserInstance = await puppeteer.launch(launchOptions);
        const page = await browserInstance.newPage();

        await page.goto(CONFIG.loginUrl, { waitUntil: "networkidle2" });

        await page.type(
            CONFIG.credentials.selectors.usernameInput,
            username
        );
        await page.type(
            CONFIG.credentials.selectors.passwordInput,
            password
        );

        await page.click(CONFIG.credentials.selectors.submitButton);

        if (CONFIG.loginSuccessCondition.urlIncludes) {
            await page.waitForFunction(
                (expectedUrl: string) => window.location.href.includes(expectedUrl),
                {},
                CONFIG.loginSuccessCondition.urlIncludes
            );
        }

        if (CONFIG.loginSuccessCondition.elementExists) {
            await page.waitForSelector(CONFIG.loginSuccessCondition.elementExists);
        }

        const cookies = await page.cookies();
        const result: Record<string, string> = {};
        for (const cookie of cookies) {
            if (CONFIG.cookieFields.includes(cookie.name)) {
                result[cookie.name] = cookie.value;
            }
        }

        return result;
    } catch (error) {
        throw new Error(`登录过程中发生错误: ${(error as Error).message}`);
    } finally {
        if (browserInstance) {
            try {
                await browserInstance.close();
            } catch (closeError) {
                console.error("关闭浏览器时发生错误:", (closeError as Error).message);
            }
        }
    }
}

// 主要业务逻辑
export async function runIntegrationTest(branchName: string): Promise<IntegrationTestResult> {
    try {
        const cookies = await loginAndGetCookies();

        const apiClient = createApiClient(cookies.token);

        const featureList = await getFeatureList(apiClient, branchName);
        const feature = featureList.data.items[0];

        const submitResult = await submitFeatureToTest(apiClient, feature.id);

        const pipelineBranches = await getPipelineBranches(apiClient, branchName);
        const branch = pipelineBranches.data.items[0];

        const integrateResult = await integratePipeline(apiClient, branch.id);

        return {
            success: true,
            branch: branchName,
            feature: {
                id: feature.id,
                name: feature.name,
                branch_name: feature.branch_name,
                status: feature.status,
            },
            submit: {
                code: submitResult.code,
                msg: submitResult.msg,
                success: submitResult.data,
            },
            pipeline: {
                id: branch.id,
                name: branch.name,
                status: branch.status,
            },
            integrate: {
                code: integrateResult.code,
                msg: integrateResult.msg,
                success: integrateResult.data,
            },
        };
    } catch (error) {
        return {
            success: false,
            error: (error as Error).message,
        };
    }
} 