import { NextRequest, NextResponse } from "next/server";

/**
 * AI Chat API Route
 *
 * Supports multiple providers: OpenAI, Anthropic (Claude), Ollama (local).
 * Provider and API key configured via environment variables:
 *
 * - AI_PROVIDER: 'openai' | 'anthropic' | 'ollama' (default: 'demo')
 * - AI_API_KEY: API key for OpenAI or Anthropic
 * - AI_MODEL: Model name (default: per provider)
 * - AI_BASE_URL: Custom base URL (required for Ollama, optional for others)
 * - AI_MAX_TOKENS: Max response tokens (default: 2048)
 */

interface ChatRequestBody {
  messages: Array<{
    role: "user" | "assistant" | "system";
    content: string;
  }>;
  systemPrompt?: string;
  maxTokens?: number;
}

function getConfig() {
  return {
    provider: (process.env.AI_PROVIDER ?? "demo") as string,
    apiKey: process.env.AI_API_KEY ?? "",
    model: process.env.AI_MODEL ?? "",
    baseUrl: process.env.AI_BASE_URL ?? "",
    maxTokens: parseInt(process.env.AI_MAX_TOKENS ?? "2048", 10),
  };
}

const DEFAULT_SYSTEM_PROMPT = `Ești un asistent AI pentru un birou de arhitectură. Răspunzi în limba română.
Ești specializat în:
- Arhitectură și proiectare
- Urbanism și PUZ/PUG/PUD
- Legislația construcțiilor din România (Legea 50/1991, Legea 350/2001)
- Certificat de Urbanism, Autorizație de Construire
- Norme tehnice (P118, normative de proiectare)
- Documentație tehnică (DTAC, PT, memorii)
Răspunde clar, concis și profesional.`;

async function callOpenAI(
  messages: ChatRequestBody["messages"],
  systemPrompt: string,
  config: ReturnType<typeof getConfig>,
): Promise<string> {
  const baseUrl = config.baseUrl || "https://api.openai.com/v1";
  const model = config.model || "gpt-4o-mini";

  const response = await fetch(`${baseUrl}/chat/completions`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${config.apiKey}`,
    },
    body: JSON.stringify({
      model,
      messages: [{ role: "system", content: systemPrompt }, ...messages],
      max_tokens: config.maxTokens,
      temperature: 0.7,
    }),
  });

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

  const data = (await response.json()) as {
    choices: Array<{ message: { content: string } }>;
  };
  return data.choices[0]?.message?.content ?? "";
}

async function callAnthropic(
  messages: ChatRequestBody["messages"],
  systemPrompt: string,
  config: ReturnType<typeof getConfig>,
): Promise<string> {
  const model = config.model || "claude-sonnet-4-20250514";

  const response = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": config.apiKey,
      "anthropic-version": "2023-06-01",
    },
    body: JSON.stringify({
      model,
      max_tokens: config.maxTokens,
      system: systemPrompt,
      messages: messages.map((m) => ({
        role: m.role === "system" ? "user" : m.role,
        content: m.content,
      })),
    }),
  });

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

  const data = (await response.json()) as {
    content: Array<{ type: string; text: string }>;
  };
  return data.content
    .filter((c) => c.type === "text")
    .map((c) => c.text)
    .join("");
}

async function callOllama(
  messages: ChatRequestBody["messages"],
  systemPrompt: string,
  config: ReturnType<typeof getConfig>,
): Promise<string> {
  const baseUrl = config.baseUrl || "http://localhost:11434";
  const model = config.model || "llama3.2";

  const response = await fetch(`${baseUrl}/api/chat`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      model,
      messages: [{ role: "system", content: systemPrompt }, ...messages],
      stream: false,
    }),
  });

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

  const data = (await response.json()) as {
    message: { content: string };
  };
  return data.message?.content ?? "";
}

function getDemoResponse(): string {
  const responses = [
    "Modulul AI Chat funcționează în mod demonstrativ. Pentru a activa răspunsuri reale, configurați variabilele de mediu:\n\n" +
      "- `AI_PROVIDER`: openai / anthropic / ollama\n" +
      "- `AI_API_KEY`: cheia API\n" +
      "- `AI_MODEL`: modelul dorit (opțional)\n\n" +
      "Consultați documentația pentru detalii.",
    "Aceasta este o conversație demonstrativă. Mesajele sunt salvate, dar răspunsurile AI nu sunt generate fără o conexiune API configurată.",
  ];
  return (
    responses[Math.floor(Math.random() * responses.length)] ?? responses[0]!
  );
}

/**
 * GET /api/ai-chat — Return provider config (without API key)
 */
export async function GET() {
  const config = getConfig();
  return NextResponse.json({
    provider: config.provider,
    model: config.model || "(default)",
    baseUrl: config.baseUrl || "(default)",
    maxTokens: config.maxTokens,
    isConfigured:
      config.provider !== "demo" &&
      (config.provider === "ollama" || !!config.apiKey),
  });
}

/**
 * POST /api/ai-chat — Send messages and get AI response
 */
export async function POST(request: NextRequest) {
  const config = getConfig();

  let body: ChatRequestBody;
  try {
    body = (await request.json()) as ChatRequestBody;
  } catch {
    return NextResponse.json({ error: "invalid_json" }, { status: 400 });
  }

  if (!body.messages || body.messages.length === 0) {
    return NextResponse.json({ error: "no_messages" }, { status: 400 });
  }

  const systemPrompt = body.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;

  try {
    let responseText: string;

    switch (config.provider) {
      case "openai":
        if (!config.apiKey) {
          return NextResponse.json(
            {
              error: "missing_api_key",
              message: "AI_API_KEY nu este configurat.",
            },
            { status: 500 },
          );
        }
        responseText = await callOpenAI(body.messages, systemPrompt, config);
        break;

      case "anthropic":
        if (!config.apiKey) {
          return NextResponse.json(
            {
              error: "missing_api_key",
              message: "AI_API_KEY nu este configurat.",
            },
            { status: 500 },
          );
        }
        responseText = await callAnthropic(body.messages, systemPrompt, config);
        break;

      case "ollama":
        responseText = await callOllama(body.messages, systemPrompt, config);
        break;

      default:
        // Demo mode
        responseText = getDemoResponse();
        break;
    }

    return NextResponse.json({
      content: responseText,
      provider: config.provider,
      model: config.model || "(default)",
      timestamp: new Date().toISOString(),
    });
  } catch (error) {
    return NextResponse.json(
      {
        error: "api_error",
        message:
          error instanceof Error
            ? error.message
            : "Eroare necunoscută la apelul API AI.",
        provider: config.provider,
      },
      { status: 502 },
    );
  }
}
