import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock"
import { createAnthropic } from "@ai-sdk/anthropic"
import { createDeepSeek, deepseek } from "@ai-sdk/deepseek"
import { createGateway } from "@ai-sdk/gateway"
import { createGoogleGenerativeAI } from "@ai-sdk/google"
import { createVertex } from "@ai-sdk/google-vertex"
import { createOpenAI } from "@ai-sdk/openai"
import { createAihubmix } from "@aihubmix/ai-sdk-provider"
import { createOpenRouter } from "@openrouter/ai-sdk-provider"
import { generateText } from "ai"
import { NextResponse } from "next/server"
import { createOllama } from "ollama-ai-provider-v2"
import {
    AIHUBMIX_APP_CODE,
    isAihubmixStandardBaseURL,
    normalizeMiniMaxBaseURL,
} from "@/lib/ai-providers"
import { allowPrivateUrls, isPrivateUrl } from "@/lib/ssrf-protection"
import { PROVIDER_INFO, type ProviderName } from "@/lib/types/model-config"

export const runtime = "nodejs"

interface ValidateRequest {
    provider: string
    apiKey: string
    baseUrl?: string
    modelId: string
    // AWS Bedrock specific
    awsAccessKeyId?: string
    awsSecretAccessKey?: string
    awsRegion?: string
    // Vertex AI specific
    vertexApiKey?: string // Express Mode API key
}

export async function POST(req: Request) {
    try {
        const body: ValidateRequest = await req.json()
        const {
            provider,
            apiKey,
            baseUrl,
            modelId,
            awsAccessKeyId,
            awsSecretAccessKey,
            awsRegion,
            // Note: Express Mode only needs vertexApiKey
            vertexApiKey,
        } = body

        if (!provider || !modelId) {
            return NextResponse.json(
                { valid: false, error: "Provider and model ID are required" },
                { status: 400 },
            )
        }

        // SECURITY: Block SSRF attacks via custom baseUrl
        if (baseUrl && !allowPrivateUrls() && (await isPrivateUrl(baseUrl))) {
            return NextResponse.json(
                { valid: false, error: "Invalid base URL" },
                { status: 400 },
            )
        }

        // Validate credentials based on provider
        if (provider === "bedrock") {
            if (!awsAccessKeyId || !awsSecretAccessKey || !awsRegion) {
                return NextResponse.json(
                    {
                        valid: false,
                        error: "AWS credentials (Access Key ID, Secret Access Key, Region) are required",
                    },
                    { status: 400 },
                )
            }
        } else if (provider === "vertexai") {
            if (!vertexApiKey) {
                return NextResponse.json(
                    {
                        valid: false,
                        error: "Vertex AI API key is required for Express Mode",
                    },
                    { status: 400 },
                )
            }
        } else if (provider !== "ollama" && provider !== "edgeone" && !apiKey) {
            return NextResponse.json(
                { valid: false, error: "API key is required" },
                { status: 400 },
            )
        }

        let model: any

        switch (provider) {
            case "openai": {
                const openai = createOpenAI({
                    apiKey,
                    ...(baseUrl && { baseURL: baseUrl }),
                })
                model = openai.chat(modelId)
                break
            }

            case "anthropic": {
                const anthropic = createAnthropic({
                    apiKey,
                    baseURL: baseUrl || "https://api.anthropic.com/v1",
                })
                model = anthropic(modelId)
                break
            }

            case "google": {
                const google = createGoogleGenerativeAI({
                    apiKey,
                    ...(baseUrl && { baseURL: baseUrl }),
                })
                model = google(modelId)
                break
            }

            case "vertexai": {
                const vertex = createVertex({
                    apiKey: vertexApiKey,
                    ...(baseUrl && { baseURL: baseUrl }),
                })
                model = vertex(modelId)
                break
            }

            case "azure": {
                const azure = createOpenAI({
                    apiKey,
                    baseURL: baseUrl,
                })
                model = azure.chat(modelId)
                break
            }

            case "bedrock": {
                const bedrock = createAmazonBedrock({
                    accessKeyId: awsAccessKeyId,
                    secretAccessKey: awsSecretAccessKey,
                    region: awsRegion,
                })
                model = bedrock(modelId)
                break
            }

            case "openrouter": {
                const openrouter = createOpenRouter({
                    apiKey,
                    ...(baseUrl && { baseURL: baseUrl }),
                })
                model = openrouter(modelId)
                break
            }

            case "aihubmix": {
                const defaultBaseURL = PROVIDER_INFO.aihubmix.defaultBaseUrl

                if (
                    isAihubmixStandardBaseURL(baseUrl) ||
                    baseUrl === defaultBaseURL
                ) {
                    const aihubmix = createAihubmix({
                        apiKey,
                        appCode: AIHUBMIX_APP_CODE,
                    })
                    model = aihubmix(modelId)
                } else {
                    const aihubmixCompatible = createOpenAI({
                        apiKey,
                        baseURL: baseUrl,
                    })
                    model = aihubmixCompatible.chat(modelId)
                }
                break
            }

            case "deepseek": {
                if (baseUrl || apiKey) {
                    const ds = createDeepSeek({
                        apiKey,
                        ...(baseUrl && { baseURL: baseUrl }),
                    })
                    model = ds(modelId)
                } else {
                    model = deepseek(modelId)
                }
                break
            }

            case "siliconflow": {
                const sf = createOpenAI({
                    apiKey,
                    baseURL: baseUrl || "https://api.siliconflow.cn/v1",
                })
                model = sf.chat(modelId)
                break
            }

            case "ollama": {
                // SECURITY: Mirror ai-providers.ts guard — only use server
                // OLLAMA_API_KEY when the URL is also from server config.
                const ollamaApiKey = baseUrl
                    ? apiKey || undefined
                    : apiKey || process.env.OLLAMA_API_KEY || undefined
                const ollamaProvider = createOllama({
                    baseURL:
                        baseUrl ||
                        process.env.OLLAMA_BASE_URL ||
                        "https://ollama.com/api",
                    ...(ollamaApiKey && {
                        headers: { Authorization: `Bearer ${ollamaApiKey}` },
                    }),
                })
                model = ollamaProvider(modelId)
                break
            }

            case "gateway": {
                const gw = createGateway({
                    apiKey,
                    ...(baseUrl && { baseURL: baseUrl }),
                })
                model = gw(modelId)
                break
            }

            case "edgeone": {
                // EdgeOne uses OpenAI-compatible API via Edge Functions
                // Need to pass cookies for EdgeOne Pages authentication
                const cookieHeader = req.headers.get("cookie") || ""
                const edgeone = createOpenAI({
                    apiKey: "edgeone", // EdgeOne doesn't require API key
                    baseURL: baseUrl || "/api/edgeai",
                    headers: {
                        cookie: cookieHeader,
                    },
                })
                model = edgeone.chat(modelId)
                break
            }

            case "sglang": {
                // SGLang is OpenAI-compatible
                const sglang = createOpenAI({
                    apiKey: apiKey || "not-needed",
                    baseURL: baseUrl || "http://127.0.0.1:8000/v1",
                })
                model = sglang.chat(modelId)
                break
            }

            case "doubao": {
                // ByteDance Doubao: use DeepSeek for DeepSeek/Kimi models, OpenAI for others
                const doubaoBaseUrl =
                    baseUrl || "https://ark.cn-beijing.volces.com/api/v3"
                const lowerModelId = modelId.toLowerCase()
                if (
                    lowerModelId.includes("deepseek") ||
                    lowerModelId.includes("kimi")
                ) {
                    const doubao = createDeepSeek({
                        apiKey,
                        baseURL: doubaoBaseUrl,
                    })
                    model = doubao(modelId)
                } else {
                    const doubao = createOpenAI({
                        apiKey,
                        baseURL: doubaoBaseUrl,
                    })
                    model = doubao.chat(modelId)
                }
                break
            }

            case "modelscope": {
                const baseURL =
                    baseUrl || "https://api-inference.modelscope.cn/v1"
                const startTime = Date.now()

                try {
                    // Initiate a streaming request (required for QwQ-32B and certain Qwen3 models)
                    const response = await fetch(
                        `${baseURL}/chat/completions`,
                        {
                            method: "POST",
                            headers: {
                                "Content-Type": "application/json",
                                Authorization: `Bearer ${apiKey}`,
                            },
                            body: JSON.stringify({
                                model: modelId,
                                messages: [
                                    { role: "user", content: "Say 'OK'" },
                                ],
                                max_tokens: 20,
                                stream: true,
                                enable_thinking: false,
                            }),
                        },
                    )

                    if (!response.ok) {
                        const errorText = await response.text()
                        throw new Error(
                            `ModelScope API error (${response.status}): ${errorText}`,
                        )
                    }

                    const contentType =
                        response.headers.get("content-type") || ""
                    const isValidStreamingResponse =
                        response.status === 200 &&
                        (contentType.includes("text/event-stream") ||
                            contentType.includes("application/json"))

                    if (!isValidStreamingResponse) {
                        throw new Error(
                            `Unexpected response format: ${contentType}`,
                        )
                    }

                    const responseTime = Date.now() - startTime

                    if (response.body) {
                        response.body.cancel().catch(() => {
                            /* Ignore cancellation errors */
                        })
                    }

                    return NextResponse.json({
                        valid: true,
                        responseTime,
                        note: "ModelScope model validated (using streaming API)",
                    })
                } catch (error) {
                    console.error(
                        "[validate-model] ModelScope validation failed:",
                        error,
                    )
                    throw error
                }
            }

            case "minimax": {
                const rawUrl =
                    baseUrl ||
                    PROVIDER_INFO.minimax?.defaultBaseUrl ||
                    "https://api.minimaxi.com/anthropic"
                const { baseURL: minimaxBaseUrl, isAnthropicCompatible } =
                    normalizeMiniMaxBaseURL(rawUrl)

                if (isAnthropicCompatible) {
                    const minimax = createAnthropic({
                        apiKey,
                        baseURL: minimaxBaseUrl,
                    })
                    model = minimax.chat(modelId)
                } else {
                    const minimax = createOpenAI({
                        apiKey,
                        baseURL: minimaxBaseUrl,
                    })
                    model = minimax.chat(modelId)
                }
                break
            }

            // GLM, Qwen, Kimi, Qiniu, Novita, MiMo, Atlas Cloud - OpenAI compatible
            case "glm":
            case "qwen":
            case "kimi":
            case "qiniu":
            case "novita":
            case "atlascloud":
            case "mimo": {
                const baseURL =
                    baseUrl ||
                    PROVIDER_INFO[provider as ProviderName]?.defaultBaseUrl ||
                    ""

                if (!baseURL) {
                    return NextResponse.json(
                        {
                            valid: false,
                            error: `No base URL configured for provider: ${provider}`,
                        },
                        { status: 400 },
                    )
                }

                const openai = createOpenAI({
                    apiKey,
                    baseURL,
                })
                model = openai.chat(modelId)
                break
            }

            default:
                return NextResponse.json(
                    { valid: false, error: `Unknown provider: ${provider}` },
                    { status: 400 },
                )
        }

        // Make a minimal test request
        const startTime = Date.now()
        await generateText({
            model,
            prompt: "Say 'OK'",
            maxOutputTokens: 20,
        })
        const responseTime = Date.now() - startTime

        return NextResponse.json({
            valid: true,
            responseTime,
        })
    } catch (error) {
        console.error("[validate-model] Error:", error)

        let errorMessage = "Validation failed"
        if (error instanceof Error) {
            // Extract meaningful error message
            if (
                error.message.includes("401") ||
                error.message.includes("Unauthorized")
            ) {
                errorMessage = "Invalid API key"
            } else if (
                error.message.includes("404") ||
                error.message.includes("not found")
            ) {
                errorMessage = "Model not found"
            } else if (
                error.message.includes("429") ||
                error.message.includes("rate limit")
            ) {
                errorMessage = "Rate limited - try again later"
            } else if (error.message.includes("ECONNREFUSED")) {
                errorMessage = "Cannot connect to server"
            } else {
                errorMessage = error.message.slice(0, 100)
            }
        }

        return NextResponse.json(
            { valid: false, error: errorMessage },
            { status: 200 }, // Return 200 so client can read error message
        )
    }
}
