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 { createOpenAI } from "@ai-sdk/openai"
import { createOpenRouter } from "@openrouter/ai-sdk-provider"
import { generateText } from "ai"
import { NextResponse } from "next/server"
import { createOllama } from "ollama-ai-provider-v2"

export const runtime = "nodejs"

/**
 * SECURITY: Check if URL points to private/internal network (SSRF protection)
 * Blocks: localhost, private IPs, link-local, AWS metadata service
 */
function isPrivateUrl(urlString: string): boolean {
    try {
        const url = new URL(urlString)
        const hostname = url.hostname.toLowerCase()

        // Block localhost
        if (
            hostname === "localhost" ||
            hostname === "127.0.0.1" ||
            hostname === "::1"
        ) {
            return true
        }

        // Block AWS/cloud metadata endpoints
        if (
            hostname === "169.254.169.254" ||
            hostname === "metadata.google.internal"
        ) {
            return true
        }

        // Check for private IPv4 ranges
        const ipv4Match = hostname.match(
            /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,
        )
        if (ipv4Match) {
            const [, a, b] = ipv4Match.map(Number)
            // 10.0.0.0/8
            if (a === 10) return true
            // 172.16.0.0/12
            if (a === 172 && b >= 16 && b <= 31) return true
            // 192.168.0.0/16
            if (a === 192 && b === 168) return true
            // 169.254.0.0/16 (link-local)
            if (a === 169 && b === 254) return true
            // 127.0.0.0/8 (loopback)
            if (a === 127) return true
        }

        // Block common internal hostnames
        if (
            hostname.endsWith(".local") ||
            hostname.endsWith(".internal") ||
            hostname.endsWith(".localhost")
        ) {
            return true
        }

        return false
    } catch {
        // Invalid URL - block it
        return true
    }
}

interface ValidateRequest {
    provider: string
    apiKey: string
    baseUrl?: string
    modelId: string
    // AWS Bedrock specific
    awsAccessKeyId?: string
    awsSecretAccessKey?: string
    awsRegion?: string
}

export async function POST(req: Request) {
    try {
        const body: ValidateRequest = await req.json()
        const {
            provider,
            apiKey,
            baseUrl,
            modelId,
            awsAccessKeyId,
            awsSecretAccessKey,
            awsRegion,
        } = 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 && 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 !== "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 "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 "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.com/v1",
                })
                model = sf.chat(modelId)
                break
            }

            case "ollama": {
                const ollama = createOllama({
                    baseURL: baseUrl || "http://localhost:11434",
                })
                model = ollama(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 uses DeepSeek-compatible API
                const doubao = createDeepSeek({
                    apiKey,
                    baseURL:
                        baseUrl || "https://ark.cn-beijing.volces.com/api/v3",
                })
                model = doubao(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
        )
    }
}
