import { readFileSync } from "node:fs";
import path from "node:path";
import process from "node:process";
import tls from "node:tls";

// getCACertificates / setDefaultCACertificates 仅在 Node.js >= 22.12 可用
const getCACertificates = typeof tls.getCACertificates === "function"
  ? tls.getCACertificates.bind(tls)
  : () => [];
const setDefaultCACertificates = typeof tls.setDefaultCACertificates === "function"
  ? tls.setDefaultCACertificates.bind(tls)
  : () => {};

import { createClient } from "@supabase/supabase-js";

let appliedTlsConfigCacheKey = "";

function normalizeEnvValue(value) {
  return typeof value === "string" ? value.trim() : "";
}

function normalizeMultilineEnvValue(value) {
  const normalized = normalizeEnvValue(value);
  if (!normalized) {
    return "";
  }

  return normalized.replace(/\\n/g, "\n");
}

function decodeJwtPayload(token) {
  const parts = token.split(".");
  if (parts.length < 2) {
    return null;
  }

  try {
    const normalized = parts[1].replace(/-/g, "+").replace(/_/g, "/");
    const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
    return JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
  } catch {
    return null;
  }
}

function isTruthyEnvValue(value) {
  return /^(1|true|yes|on)$/i.test(normalizeEnvValue(value));
}

function resolveCaCertPath(env, cwd = process.cwd()) {
  const rawPath = normalizeEnvValue(env.SUPABASE_TLS_CA_CERT_PATH);
  if (!rawPath) {
    return "";
  }

  return path.isAbsolute(rawPath) ? rawPath : path.resolve(cwd, rawPath);
}

function resolveCaCertValue(env, cwd = process.cwd()) {
  const inlinePem = normalizeMultilineEnvValue(env.SUPABASE_TLS_CA_CERT);
  if (inlinePem) {
    return inlinePem;
  }

  const base64Pem = normalizeEnvValue(env.SUPABASE_TLS_CA_CERT_BASE64);
  if (base64Pem) {
    return Buffer.from(base64Pem, "base64").toString("utf8").trim();
  }

  const certPath = resolveCaCertPath(env, cwd);
  if (!certPath) {
    return "";
  }

  try {
    return readFileSync(certPath, "utf8").trim();
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    throw new Error(`读取 SUPABASE_TLS_CA_CERT_PATH 失败: ${message}`);
  }
}

export function getSupabaseJwtRole(token) {
  const payload = decodeJwtPayload(token);
  return typeof payload?.role === "string" ? payload.role : "";
}

export function resolveSupabaseUrl(env = process.env) {
  return normalizeEnvValue(env.SUPABASE_URL) || normalizeEnvValue(env.VITE_SUPABASE_URL);
}

export function resolveSupabaseKey(env = process.env) {
  const seen = new Set();
  const candidates = [
    env.SUPABASE_SERVICE_ROLE_KEY,
    env.VITE_SUPABASE_SERVICE_ROLE_KEY,
    env.SUPABASE_service_key,
    env.SUPABASE_ANON_KEY,
    env.VITE_SUPABASE_ANON_KEY,
  ]
    .map(normalizeEnvValue)
    .filter((candidate) => {
      if (!candidate || seen.has(candidate)) {
        return false;
      }

      seen.add(candidate);
      return true;
    });

  const serviceRoleKey = candidates.find((candidate) => getSupabaseJwtRole(candidate) === "service_role");
  return serviceRoleKey ?? candidates[0] ?? "";
}

export function resolveSupabaseTlsConfig(env = process.env, cwd = process.cwd()) {
  const ca = resolveCaCertValue(env, cwd);
  const rejectUnauthorized = !isTruthyEnvValue(env.SUPABASE_TLS_INSECURE_SKIP_VERIFY);

  if (!ca && rejectUnauthorized) {
    return null;
  }

  return {
    ca: ca || undefined,
    rejectUnauthorized,
  };
}

function applySupabaseNodeTlsConfig(env = process.env, cwd = process.cwd()) {
  const tlsConfig = resolveSupabaseTlsConfig(env, cwd);
  const cacheKey = JSON.stringify(tlsConfig ?? null);
  if (cacheKey === appliedTlsConfigCacheKey) {
    return;
  }

  if (tlsConfig?.ca) {
    const currentCertificates = getCACertificates("default");
    const nextCertificates = currentCertificates.includes(tlsConfig.ca)
      ? currentCertificates
      : [...currentCertificates, tlsConfig.ca];
    setDefaultCACertificates(nextCertificates);
  }

  if (tlsConfig && !tlsConfig.rejectUnauthorized) {
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
  }

  appliedTlsConfigCacheKey = cacheKey;
}

export function mergeSupabaseNodeClientOptions(clientOptions = {}, env = process.env, cwd = process.cwd()) {
  applySupabaseNodeTlsConfig(env, cwd);
  return clientOptions;
}

export function createResolvedSupabaseClient(env = process.env, clientOptions = {}, cwd = process.cwd()) {
  const url = resolveSupabaseUrl(env);
  const key = resolveSupabaseKey(env);

  if (!url || !key) {
    throw new Error("缺少 SUPABASE_URL 或可用的 Supabase key，请配置 SUPABASE_SERVICE_ROLE_KEY 或 VITE_SUPABASE_SERVICE_ROLE_KEY。");
  }

  return createClient(url, key, mergeSupabaseNodeClientOptions(clientOptions, env, cwd));
}