import { createClient as createSupabaseClient } from "@supabase/supabase-js";
import { getDefaultModel } from "./catalog";
import { decryptSecret, encryptSecret, maskApiKey } from "./crypto";
import type { AIProvider, AISettingsPublic, AISettingsRecord } from "./types";

function getSupabaseAdmin() {
  return createSupabaseClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.SUPABASE_SERVICE_ROLE_KEY!
  );
}

export async function getAISettingsRecord(userId: string): Promise<AISettingsRecord | null> {
  const supabase = getSupabaseAdmin();
  const { data } = await supabase
    .from("ai_settings")
    .select("user_id, provider, model, openai_encrypted_api_key, openai_api_key_hint, anthropic_encrypted_api_key, anthropic_api_key_hint, custom_instructions")
    .eq("user_id", userId)
    .maybeSingle();

  return data;
}

export async function getAISettingsPublic(userId: string): Promise<AISettingsPublic> {
  const record = await getAISettingsRecord(userId);

  if (!record) {
    return {
      provider: "mindavio_core",
      model: getDefaultModel("mindavio_core"),
      openaiConnected: false,
      openaiApiKeyHint: null,
      anthropicConnected: false,
      anthropicApiKeyHint: null,
      customInstructions: "",
    };
  }

  return {
    provider: record.provider,
    model: record.model,
    openaiConnected: Boolean(record.openai_encrypted_api_key),
    openaiApiKeyHint: record.openai_api_key_hint,
    anthropicConnected: Boolean(record.anthropic_encrypted_api_key),
    anthropicApiKeyHint: record.anthropic_api_key_hint,
    customInstructions: record.custom_instructions || "",
  };
}

export async function saveAISettings(input: {
  userId: string;
  provider: AIProvider;
  model: string;
  openaiApiKey?: string;
  anthropicApiKey?: string;
  customInstructions?: string;
  clearOpenAIKey?: boolean;
  clearAnthropicKey?: boolean;
}) {
  const supabase = getSupabaseAdmin();
  const existing = await getAISettingsRecord(input.userId);

  const nextOpenAIEncryptedApiKey =
    input.clearOpenAIKey
      ? null
      : input.openaiApiKey?.trim()
      ? encryptSecret(input.openaiApiKey.trim())
      : existing?.openai_encrypted_api_key ?? null;

  const nextOpenAIApiKeyHint =
    input.clearOpenAIKey
      ? null
      : input.openaiApiKey?.trim()
      ? maskApiKey(input.openaiApiKey.trim())
      : existing?.openai_api_key_hint ?? null;

  const nextAnthropicEncryptedApiKey =
    input.clearAnthropicKey
      ? null
      : input.anthropicApiKey?.trim()
      ? encryptSecret(input.anthropicApiKey.trim())
      : existing?.anthropic_encrypted_api_key ?? null;

  const nextAnthropicApiKeyHint =
    input.clearAnthropicKey
      ? null
      : input.anthropicApiKey?.trim()
      ? maskApiKey(input.anthropicApiKey.trim())
      : existing?.anthropic_api_key_hint ?? null;

  const payload = {
    user_id: input.userId,
    provider: input.provider,
    model: input.model,
    openai_encrypted_api_key: nextOpenAIEncryptedApiKey,
    openai_api_key_hint: nextOpenAIApiKeyHint,
    anthropic_encrypted_api_key: nextAnthropicEncryptedApiKey,
    anthropic_api_key_hint: nextAnthropicApiKeyHint,
    custom_instructions: input.customInstructions || "",
  };

  const { error } = await supabase.from("ai_settings").upsert(payload);
  if (error) throw error;

  return getAISettingsPublic(input.userId);
}

export async function getDecryptedApiKey(userId: string) {
  const record = await getAISettingsRecord(userId);
  if (!record) return null;

  return {
    provider: record.provider,
    model: record.model,
    openaiApiKey: record.openai_encrypted_api_key
      ? decryptSecret(record.openai_encrypted_api_key)
      : null,
    anthropicApiKey: record.anthropic_encrypted_api_key
      ? decryptSecret(record.anthropic_encrypted_api_key)
      : null,
    customInstructions: record.custom_instructions || "",
  };
}
