import { Alert, AlertDescription } from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
import { CodeEditor } from "@/components/ui/codeEditor";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useCopyToClipboard } from "@/hooks/useCopyToClipboard";
import { getExampleBaseUrl } from "@/lib/utils/port";
import { AlertTriangle, Copy } from "lucide-react";
import { useMemo, useState } from "react";

type Provider = "openai" | "anthropic" | "genai" | "litellm" | "langchain";
type Language = "python" | "typescript";

type Examples = {
	curl: string;
	sdk: {
		[P in Provider]: {
			[L in Language]: string;
		};
	};
};

// Common editor options to reduce duplication
const EditorOptions = {
	scrollBeyondLastLine: false,
	minimap: { enabled: false },
	lineNumbers: "off",
	folding: false,
	lineDecorationsWidth: 0,
	lineNumbersMinChars: 0,
	glyphMargin: false,
} as const;

interface CodeBlockProps {
	code: string;
	language: string;
	onLanguageChange?: (language: string) => void;
	showLanguageSelect?: boolean;
	readonly?: boolean;
}

function CodeBlock({ code, language, onLanguageChange, showLanguageSelect = false, readonly = true }: CodeBlockProps) {
	const { copy: copyToClipboard } = useCopyToClipboard();

	return (
		<div className="relative">
			<div className="absolute top-4 right-4 z-10 flex items-center gap-2">
				{showLanguageSelect && onLanguageChange && (
					<Select value={language} onValueChange={onLanguageChange}>
						<SelectTrigger className="h-8 w-fit text-xs">
							<SelectValue />
						</SelectTrigger>
						<SelectContent>
							<SelectItem className="text-xs" value="python">
								Python
							</SelectItem>
							<SelectItem className="text-xs" value="typescript">
								TypeScript
							</SelectItem>
						</SelectContent>
					</Select>
				)}
				<Button variant="ghost" size="icon" onClick={() => copyToClipboard(code)}>
					<Copy className="size-4" />
				</Button>
			</div>
			<CodeEditor className="w-full" code={code} lang={language} readonly={readonly} height={300} fontSize={14} options={EditorOptions} />
		</div>
	);
}

interface EmptyStateProps {
	error: string | null;
}

export function EmptyState({ error }: EmptyStateProps) {
	const [language, setLanguage] = useState<Language>("python");

	// Generate examples dynamically using the port utility
	const examples: Examples = useMemo(() => {
		const baseUrl = getExampleBaseUrl();

		return {
			curl: `curl -X POST ${baseUrl}/v1/chat/completions \\
  -H "Content-Type: application/json" \\
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [
      {"role": "user", "content": "Hello!"}
    ]
  }'`,
			sdk: {
				openai: {
					python: `import openai

client = openai.OpenAI(
    base_url="${baseUrl}/openai",
    api_key="dummy-api-key" # Handled by Bifrost
)

response = client.chat.completions.create(
    model="gpt-4o-mini", # or "provider/model" for other providers (anthropic/claude-3-sonnet)
    messages=[{"role": "user", "content": "Hello!"}]
)`,
					typescript: `import OpenAI from "openai";

const openai = new OpenAI({
  baseURL: "${baseUrl}/openai",
  apiKey: "dummy-api-key", // Handled by Bifrost
});

const response = await openai.chat.completions.create({
  model: "gpt-4o-mini", // or "provider/model" for other providers (anthropic/claude-3-sonnet)
  messages: [{ role: "user", content: "Hello!" }],
});`,
				},
				anthropic: {
					python: `import anthropic

client = anthropic.Anthropic(
    base_url="${baseUrl}/anthropic",
    api_key="dummy-api-key" # Handled by Bifrost
)

response = client.messages.create(
    model="claude-3-sonnet-20240229", # or "provider/model" for other providers (openai/gpt-4o-mini)
    max_tokens=1000,
    messages=[{"role": "user", "content": "Hello!"}]
)`,
					typescript: `import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic({
  baseURL: "${baseUrl}/anthropic",
  apiKey: "dummy-api-key", // Handled by Bifrost
});

const response = await anthropic.messages.create({
  model: "claude-3-sonnet-20240229", // or "provider/model" for other providers (openai/gpt-4o-mini)
  max_tokens: 1000,
  messages: [{ role: "user", content: "Hello!" }],
});`,
				},
				genai: {
					python: `from google import genai
from google.genai.types import HttpOptions

client = genai.Client(
    api_key="dummy-api-key", # Handled by Bifrost
    http_options=HttpOptions(base_url="${baseUrl}/genai")
)

response = client.models.generate_content(
    model="gemini-2.5-pro", # or "provider/model" for other providers (openai/gpt-4o-mini)
    contents="Hello!"
)`,
					typescript: `import { GoogleGenerativeAI } from "@google/generative-ai";

const genAI = new GoogleGenerativeAI("dummy-api-key", { // Handled by Bifrost
  baseUrl: "${baseUrl}/genai",
});

const model = genAI.getGenerativeModel({ model: "gemini-2.5-pro" }); // or "provider/model" for other providers (openai/gpt-4o-mini)
const response = await model.generateContent("Hello!");`,
				},
				litellm: {
					python: `import litellm

litellm.api_base = "${baseUrl}/litellm"

response = litellm.completion(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}]
)`,
					typescript: `import { completion } from "litellm";

const response = await completion({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Hello!" }],
  api_base: "${baseUrl}/litellm",
});`,
				},
				langchain: {
					python: `from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# Initialize ChatOpenAI with Bifrost
llm = ChatOpenAI(
    model="gpt-4o-mini",
    api_key="dummy-api-key",  # Handled by Bifrost
    base_url="${baseUrl}/langchain",
    max_tokens=100,
)

# Simple message
messages = [HumanMessage(content="Hello from LangChain!")]
response = llm.invoke(messages)

# Chain with prompt template
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("human", "{input}")
])

chain = prompt | llm | StrOutputParser()
result = chain.invoke({"input": "What is LangChain?"})`,
					typescript: `import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";

// Initialize ChatOpenAI with Bifrost
const llm = new ChatOpenAI({
  model: "gpt-4o-mini",
  openAIApiKey: "dummy-api-key", // Handled by Bifrost
  clientOptions: {
    baseURL: "${baseUrl}/langchain",
  },
  maxTokens: 100,
});

// Simple message
const messages = [new HumanMessage("Hello from LangChain!")];
const response = await llm.invoke(messages);

// Chain with prompt template
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "You are a helpful assistant."],
  ["human", "{input}"],
]);

const chain = prompt.pipe(llm).pipe(new StringOutputParser());
const result = await chain.invoke({ input: "What is LangChain?" });`,
				},
			},
		};
	}, []);

	const isUnexpectedError = error && error.includes("An unexpected error occurred");

	return (
		<div className="dark:bg-card flex w-full flex-col items-center justify-center space-y-8 bg-white">
			{error && (
				<Alert>
					<AlertTriangle className="h-4 w-4" />
					<AlertDescription>
						{isUnexpectedError ? "Looks like you haven't configured the log store in your config file." : error}
					</AlertDescription>
				</Alert>
			)}

			<div className="w-full space-y-6 p-4">
				<div className="flex flex-row items-center gap-2">
					<div>
						<h3 className="text-lg font-semibold">Integrate under 60 seconds</h3>
						<p className="text-muted-foreground text-sm">Send your first request to get started</p>
					</div>
				</div>

				<Tabs defaultValue="curl" className="w-full rounded-lg border">
					<TabsList className="grid h-10 w-full grid-cols-6 rounded-t-lg rounded-b-none">
						<TabsTrigger value="curl">cURL</TabsTrigger>
						<TabsTrigger value="openai">OpenAI SDK</TabsTrigger>
						<TabsTrigger value="anthropic">Anthropic SDK</TabsTrigger>
						<TabsTrigger value="genai">Google GenAI SDK</TabsTrigger>
						<TabsTrigger value="litellm">LiteLLM SDK</TabsTrigger>
						<TabsTrigger value="langchain">LangChain SDK</TabsTrigger>
					</TabsList>

					<TabsContent value="curl" className="px-4">
						<CodeBlock code={examples.curl} language="bash" readonly={false} />
					</TabsContent>

					<TabsContent value="openai" className="px-4">
						<CodeBlock
							code={examples.sdk.openai[language]}
							language={language}
							onLanguageChange={(newLang) => setLanguage(newLang as Language)}
							showLanguageSelect
						/>
					</TabsContent>

					<TabsContent value="anthropic" className="px-4">
						<CodeBlock
							code={examples.sdk.anthropic[language]}
							language={language}
							onLanguageChange={(newLang) => setLanguage(newLang as Language)}
							showLanguageSelect
						/>
					</TabsContent>

					<TabsContent value="genai" className="px-4">
						<CodeBlock
							code={examples.sdk.genai[language]}
							language={language}
							onLanguageChange={(newLang) => setLanguage(newLang as Language)}
							showLanguageSelect
						/>
					</TabsContent>

					<TabsContent value="litellm" className="px-4">
						<CodeBlock
							code={examples.sdk.litellm[language]}
							language={language}
							onLanguageChange={(newLang) => setLanguage(newLang as Language)}
							showLanguageSelect
						/>
					</TabsContent>

					<TabsContent value="langchain" className="px-4">
						<CodeBlock
							code={examples.sdk.langchain[language]}
							language={language}
							onLanguageChange={(newLang) => setLanguage(newLang as Language)}
							showLanguageSelect
						/>
					</TabsContent>
				</Tabs>
			</div>
		</div>
	);
}