"use client";

import {
  createContext,
  useContext,
  useState,
  useCallback,
  type ReactNode,
} from "react";

const PRIMARY_HOST = "athena-db.com"; // pragma: allowlist secret
export const ATHENA_MIRRORS = [
  { label: "Primary", url: `https://${PRIMARY_HOST}` },
  { label: "Mirror 1", url: `https://mirror1.${PRIMARY_HOST}` },
  { label: "Mirror 2", url: `https://mirror2.${PRIMARY_HOST}` },
  { label: "Mirror 3", url: `https://mirror3.${PRIMARY_HOST}` },
  { label: "Local", url: "http://localhost:5052" },
];

const STORAGE_KEY_URL = "athena_base_url";
const STORAGE_KEY_API_KEY = "athena_p12_key";
const STORAGE_KEY_LOCAL_BACKUP_API_KEY = "athena_local_backup_api_key";
const STORAGE_KEY_PG_DUMP_PATH = "athena_pg_dump_path";
const STORAGE_KEY_PG_RESTORE_PATH = "athena_pg_restore_path";
const STORAGE_KEY_OPENROUTER_URL = "athena_openrouter_url";
const STORAGE_KEY_OPENROUTER_KEY = "athena_openrouter_key";
const STORAGE_KEY_OPENROUTER_MODEL = "athena_openrouter_model";
const STORAGE_KEY_OPENROUTER_SITE_URL = "athena_openrouter_site_url";
const STORAGE_KEY_OPENROUTER_APP_NAME = "athena_openrouter_app_name";
const STORAGE_KEY_OPENROUTER_SYSTEM_PROMPT = "athena_openrouter_system_prompt";
const STORAGE_KEY_OPENROUTER_TEMPERATURE = "athena_openrouter_temperature";
const STORAGE_KEY_OPENROUTER_MAX_TOKENS = "athena_openrouter_max_tokens";
export type AthenaSettings = {
  baseUrl: string;
  apiKey: string;
  localBackupApiKey: string;
  pgDumpPath: string;
  pgRestorePath: string;
  openRouterUrl: string;
  openRouterApiKey: string;
  openRouterModel: string;
  openRouterSiteUrl: string;
  openRouterAppName: string;
  openRouterSystemPrompt: string;
  openRouterTemperature: number;
  openRouterMaxTokens: number;
  setBaseUrl: (url: string) => void;
  setApiKey: (key: string) => void;
  setLocalBackupApiKey: (key: string) => void;
  setPgDumpPath: (path: string) => void;
  setPgRestorePath: (path: string) => void;
  setOpenRouterUrl: (url: string) => void;
  setOpenRouterApiKey: (key: string) => void;
  setOpenRouterModel: (model: string) => void;
  setOpenRouterSiteUrl: (url: string) => void;
  setOpenRouterAppName: (name: string) => void;
  setOpenRouterSystemPrompt: (prompt: string) => void;
  setOpenRouterTemperature: (value: number) => void;
  setOpenRouterMaxTokens: (value: number) => void;
  isLocalBuild: boolean;
  isConfigured: boolean;
};

const SettingsContext = createContext<AthenaSettings | null>(null);

function readStorage(key: string, fallback: string): string {
  if (typeof window === "undefined") return fallback;
  try {
    return localStorage.getItem(key) ?? fallback;
  } catch {
    return fallback;
  }
}

function normalizeBaseUrl(url: string): string {
  const trimmed = url.trim();
  if (!trimmed) return "";
  return trimmed.replace(/\/+$/, "");
}

function defaultBaseUrl(): string {
  if (ENV_BASE_URL) return ENV_BASE_URL;
  return ATHENA_MIRRORS[0].url;
}

function writeStorage(key: string, value: string) {
  try {
    if (value) {
      localStorage.setItem(key, value);
    } else {
      localStorage.removeItem(key);
    }
  } catch {
    // storage unavailable
  }
}

const ENV_BASE_URL = normalizeBaseUrl(
  process.env.NEXT_PUBLIC_ATHENA_BASE_URL ?? "",
);
const ENV_API_KEY = (
  process.env.NEXT_PUBLIC_ATHENA_API_KEY ??
  process.env.NEXT_PUBLIC_ATHENA_P12_KEY ??
  ""
).trim();
const ENV_LOCAL_BACKUP_API_KEY = (
  process.env.NEXT_PUBLIC_ATHENA_LOCAL_BACKUP_API_KEY ?? ""
).trim();
const ENV_PG_DUMP_PATH = (
  process.env.NEXT_PUBLIC_ATHENA_PG_DUMP_PATH ?? ""
).trim();
const ENV_PG_RESTORE_PATH = (
  process.env.NEXT_PUBLIC_ATHENA_PG_RESTORE_PATH ?? ""
).trim();
const ENV_OPENROUTER_URL = normalizeBaseUrl(
  process.env.NEXT_PUBLIC_OPENROUTER_URL ??
    "https://openrouter.ai/api/v1/chat/completions",
);
const ENV_OPENROUTER_API_KEY = (
  process.env.NEXT_PUBLIC_OPENROUTER_KEY ?? ""
).trim();
const ENV_OPENROUTER_MODEL = (
  process.env.NEXT_PUBLIC_OPENROUTER_MODEL ?? "openai/gpt-4o-mini"
).trim();
const ENV_OPENROUTER_SITE_URL = (
  process.env.NEXT_PUBLIC_OPENROUTER_SITE_URL ??
  "http://localhost:3000"
).trim();
const ENV_OPENROUTER_APP_NAME = (
  process.env.NEXT_PUBLIC_OPENROUTER_APP_NAME ?? "Athena SQL Editor"
).trim();
const ENV_OPENROUTER_SYSTEM_PROMPT = (
  process.env.NEXT_PUBLIC_OPENROUTER_SYSTEM_PROMPT ??
  "You are a SQL assistant for Athena. Return SQL in ```sql fenced code blocks when suggesting statements."
).trim();
const ENV_OPENROUTER_TEMPERATURE = Number(
  process.env.NEXT_PUBLIC_OPENROUTER_TEMPERATURE ?? "0.2",
);
const ENV_OPENROUTER_MAX_TOKENS = Number(
  process.env.NEXT_PUBLIC_OPENROUTER_MAX_TOKENS ?? "1200",
);
const IS_LOCAL_BUILD =
  process.env.NODE_ENV !== "production" || ENV_BASE_URL.includes("localhost");

export function SettingsProvider({ children }: { children: ReactNode }) {
  const [baseUrl, setBaseUrlState] = useState(() =>
    normalizeBaseUrl(readStorage(STORAGE_KEY_URL, defaultBaseUrl())),
  );
  const [apiKey, setApiKeyState] = useState(() =>
    readStorage(STORAGE_KEY_API_KEY, ENV_API_KEY),
  );
  const [localBackupApiKey, setLocalBackupApiKeyState] = useState(() =>
    readStorage(STORAGE_KEY_LOCAL_BACKUP_API_KEY, ENV_LOCAL_BACKUP_API_KEY),
  );
  const [pgDumpPath, setPgDumpPathState] = useState(() =>
    readStorage(STORAGE_KEY_PG_DUMP_PATH, ENV_PG_DUMP_PATH),
  );
  const [pgRestorePath, setPgRestorePathState] = useState(() =>
    readStorage(STORAGE_KEY_PG_RESTORE_PATH, ENV_PG_RESTORE_PATH),
  );
  const [openRouterUrl, setOpenRouterUrlState] = useState(() =>
    normalizeBaseUrl(readStorage(STORAGE_KEY_OPENROUTER_URL, ENV_OPENROUTER_URL)),
  );
  const [openRouterApiKey, setOpenRouterApiKeyState] = useState(() =>
    readStorage(STORAGE_KEY_OPENROUTER_KEY, ENV_OPENROUTER_API_KEY),
  );
  const [openRouterModel, setOpenRouterModelState] = useState(() =>
    readStorage(STORAGE_KEY_OPENROUTER_MODEL, ENV_OPENROUTER_MODEL),
  );
  const [openRouterSiteUrl, setOpenRouterSiteUrlState] = useState(() =>
    readStorage(STORAGE_KEY_OPENROUTER_SITE_URL, ENV_OPENROUTER_SITE_URL),
  );
  const [openRouterAppName, setOpenRouterAppNameState] = useState(() =>
    readStorage(STORAGE_KEY_OPENROUTER_APP_NAME, ENV_OPENROUTER_APP_NAME),
  );
  const [openRouterSystemPrompt, setOpenRouterSystemPromptState] = useState(
    () =>
      readStorage(
        STORAGE_KEY_OPENROUTER_SYSTEM_PROMPT,
        ENV_OPENROUTER_SYSTEM_PROMPT,
      ),
  );
  const [openRouterTemperature, setOpenRouterTemperatureState] = useState(() => {
    const raw = readStorage(
      STORAGE_KEY_OPENROUTER_TEMPERATURE,
      String(ENV_OPENROUTER_TEMPERATURE),
    );
    const parsed = Number(raw);
    return Number.isFinite(parsed) ? parsed : 0.2;
  });
  const [openRouterMaxTokens, setOpenRouterMaxTokensState] = useState(() => {
    const raw = readStorage(
      STORAGE_KEY_OPENROUTER_MAX_TOKENS,
      String(ENV_OPENROUTER_MAX_TOKENS),
    );
    const parsed = Number(raw);
    return Number.isFinite(parsed) ? parsed : 1200;
  });

  const setBaseUrl = useCallback((url: string) => {
    const normalized = normalizeBaseUrl(url);
    setBaseUrlState(normalized);
    writeStorage(STORAGE_KEY_URL, normalized);
  }, []);

  const setApiKey = useCallback((key: string) => {
    setApiKeyState(key);
    writeStorage(STORAGE_KEY_API_KEY, key);
  }, []);

  const setLocalBackupApiKey = useCallback((key: string) => {
    setLocalBackupApiKeyState(key);
    writeStorage(STORAGE_KEY_LOCAL_BACKUP_API_KEY, key);
  }, []);

  const setPgDumpPath = useCallback((path: string) => {
    const normalized = path.trim();
    setPgDumpPathState(normalized);
    writeStorage(STORAGE_KEY_PG_DUMP_PATH, normalized);
  }, []);

  const setPgRestorePath = useCallback((path: string) => {
    const normalized = path.trim();
    setPgRestorePathState(normalized);
    writeStorage(STORAGE_KEY_PG_RESTORE_PATH, normalized);
  }, []);

  const setOpenRouterUrl = useCallback((url: string) => {
    const normalized = normalizeBaseUrl(url);
    setOpenRouterUrlState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_URL, normalized);
  }, []);

  const setOpenRouterApiKey = useCallback((key: string) => {
    const normalized = key.trim();
    setOpenRouterApiKeyState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_KEY, normalized);
  }, []);

  const setOpenRouterModel = useCallback((model: string) => {
    const normalized = model.trim();
    setOpenRouterModelState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_MODEL, normalized);
  }, []);

  const setOpenRouterSiteUrl = useCallback((url: string) => {
    const normalized = url.trim();
    setOpenRouterSiteUrlState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_SITE_URL, normalized);
  }, []);

  const setOpenRouterAppName = useCallback((name: string) => {
    const normalized = name.trim();
    setOpenRouterAppNameState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_APP_NAME, normalized);
  }, []);

  const setOpenRouterSystemPrompt = useCallback((prompt: string) => {
    const normalized = prompt.trim();
    setOpenRouterSystemPromptState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_SYSTEM_PROMPT, normalized);
  }, []);

  const setOpenRouterTemperature = useCallback((value: number) => {
    const bounded = Math.min(2, Math.max(0, Number.isFinite(value) ? value : 0.2));
    setOpenRouterTemperatureState(bounded);
    writeStorage(STORAGE_KEY_OPENROUTER_TEMPERATURE, String(bounded));
  }, []);

  const setOpenRouterMaxTokens = useCallback((value: number) => {
    const normalized = Math.round(
      Math.min(32768, Math.max(128, Number.isFinite(value) ? value : 1200)),
    );
    setOpenRouterMaxTokensState(normalized);
    writeStorage(STORAGE_KEY_OPENROUTER_MAX_TOKENS, String(normalized));
  }, []);

  const isConfigured = Boolean(baseUrl && (apiKey || localBackupApiKey));

  return (
    <SettingsContext.Provider
      value={{
        baseUrl,
        apiKey,
        localBackupApiKey,
        pgDumpPath,
        pgRestorePath,
        openRouterUrl,
        openRouterApiKey,
        openRouterModel,
        openRouterSiteUrl,
        openRouterAppName,
        openRouterSystemPrompt,
        openRouterTemperature,
        openRouterMaxTokens,
        setBaseUrl,
        setApiKey,
        setLocalBackupApiKey,
        setPgDumpPath,
        setPgRestorePath,
        setOpenRouterUrl,
        setOpenRouterApiKey,
        setOpenRouterModel,
        setOpenRouterSiteUrl,
        setOpenRouterAppName,
        setOpenRouterSystemPrompt,
        setOpenRouterTemperature,
        setOpenRouterMaxTokens,
        isLocalBuild: IS_LOCAL_BUILD,
        isConfigured,
      }}
    >
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettings(): AthenaSettings {
  const ctx = useContext(SettingsContext);
  if (!ctx) throw new Error("useSettings must be used within SettingsProvider");
  return ctx;
}
