import fs from "node:fs/promises";
import path from "node:path";

export type DatabaseConfig = {
  host?: string;
  port?: number;
  database?: string;
  user?: string;
  password?: string;
  schema?: string;
};

export type SupabaseConfigFile = {
  supabaseUrl?: string;
  url?: string;
  supabaseAnonKey?: string;
  anonKey?: string;
  database?: DatabaseConfig;
};

export type SupabaseCredentials = {
  url: string;
  anonKey: string;
};

export type ResolvedSupabaseConfig = SupabaseCredentials & {
  databaseConfig?: DatabaseConfig;
};

export const readJsonFile = async <T>(filePath: string): Promise<T> => {
  const resolvedPath = path.resolve(filePath);
  const contents = await fs.readFile(resolvedPath, "utf-8");
  return JSON.parse(contents) as T;
};

export const loadSupabaseConfigFile = async (
  filePath: string,
): Promise<SupabaseConfigFile> => {
  try {
    return await readJsonFile<SupabaseConfigFile>(filePath);
  } catch (error) {
    throw new Error(`Unable to read Supabase config ${filePath}: ${error}`);
  }
};

const normalizeSupabaseUrl = (config?: SupabaseConfigFile) =>
  config?.supabaseUrl ?? config?.url ?? (config as any)?.supabase_url;

const normalizeSupabaseKey = (config?: SupabaseConfigFile) =>
  config?.supabaseAnonKey ??
  config?.anonKey ??
  (config as any)?.supabase_anon_key;

export const resolveSupabaseConfig = async (
  args: Partial<SupabaseConfigFile> & {
    supabaseUrl?: string;
    supabaseKey?: string;
    supabaseConfigPath?: string;
  },
): Promise<ResolvedSupabaseConfig> => {
  const envUrl =
    process.env.ATHENA_SUPABASE_URL ?? process.env.SUPABASE_URL ?? undefined;
  const envKey =
    process.env.ATHENA_SUPABASE_ANON_KEY ??
    process.env.SUPABASE_ANON_KEY ??
    undefined;
  let fileConfig: SupabaseConfigFile | undefined;
  if (args.supabaseConfigPath) {
    fileConfig = await loadSupabaseConfigFile(args.supabaseConfigPath);
  }
  const url =
    args.supabaseUrl ??
    normalizeSupabaseUrl(fileConfig) ??
    envUrl ??
    "https://cpaksmmlpaxeqdtztfor.supabase.co";
  const anonKey =
    args.supabaseKey ??
    normalizeSupabaseKey(fileConfig) ??
    envKey ??
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNwYWtzbW1scGF4ZXFkdHp0Zm9yIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzkyMTIwNDcsImV4cCI6MjA1NDc4ODA0N30.oavIgeySDTaMraCxRGWUqJUmTKXhSIdZLiUZJn7yEhY";
  if (!url || !anonKey) {
    throw new Error("supabase url/key missing, set via env/config/flags");
  }
  return {
    url,
    anonKey,
    databaseConfig: fileConfig?.database,
  };
};

export const writeDatabaseConfig = async (
  outputPath: string,
  databaseConfig: DatabaseConfig,
): Promise<void> => {
  await fs.writeFile(
    path.resolve(outputPath),
    JSON.stringify(databaseConfig, null, 2),
    { encoding: "utf-8" },
  );
  console.log(`Wrote database config to ${outputPath}`);
};
