import { createClient } from "@sanity/client";
import { makeEditorialReference, } from "../_vendor/ailf-shared/index.js";
// Belt-and-suspenders default for AILF operational documents per D0043.
// In practice this constant is never the load-bearing value in any
// production-shaped env: the cascade in `getAilfDefaultConfig()` is
// `AILF_REPORT_DATASET ?? SANITY_DATASET ?? AILF_DATASET_DEFAULT`, and
// every deployed env sets at least `SANITY_DATASET` for editorial reads.
// The constant matters only for ad-hoc runs with no env at all — where
// landing in `ailf-prod-private` is safer than polluting the editorial
// dataset with stray writes.
const AILF_DATASET_DEFAULT = "ailf-prod-private";
// Default editorial dataset that AILF cross-dataset references point at.
// Used by `buildEditorialReference()` and by Studio's CDR field config.
const EDITORIAL_DATASET_DEFAULT = "next";
/**
 * Build the default Sanity client config by reading process.env at call time.
 *
 * IMPORTANT: This is a function, not a module-level const. In ESM, static
 * imports are resolved before module-level code runs. If this were a const,
 * it would capture process.env values at import time — before dotenv has
 * loaded the .env file. By deferring to call time, we ensure env vars set
 * by dotenvConfig() in cli.ts (or migration scripts) are always picked up.
 */
function getDefaultConfig() {
    return {
        apiVersion: new Date().toISOString().split("T")[0],
        // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
        dataset: process.env.SANITY_DATASET || "next",
        // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
        projectId: process.env.SANITY_PROJECT_ID || "3do82whm",
        token: process.env.SANITY_API_TOKEN,
        useCdn: false,
    };
}
let _client = null;
/**
 * Create a Sanity client configured for a specific perspective.
 *
 * Unlike getSanityClient(), this always creates a fresh (uncached) client.
 * Used for perspective diffing — comparing published vs. perspective content.
 *
 * @param perspective - The perspective ID (e.g., "agent-c7OKTk"). Stacked
 *   on top of "published" as [perspectiveId, "published"].
 * @param source - Optional ResolvedSourceConfig for projectId/dataset overrides.
 */
export function createPerspectiveClient(perspective, source) {
    const config = {
        ...getDefaultConfig(),
        ...(source?.dataset ? { dataset: source.dataset } : {}),
        ...(source?.projectId ? { projectId: source.projectId } : {}),
        perspective: [perspective, "published"],
    };
    return createClient(config);
}
/**
 * Create a Sanity client that reads only published content (no perspectives).
 *
 * Unlike getSanityClient(), this always creates a fresh (uncached) client.
 * Used for perspective diffing — fetching the "before" state.
 *
 * @param source - Optional ResolvedSourceConfig for projectId/dataset overrides.
 */
export function createPublishedClient(source) {
    const config = {
        ...getDefaultConfig(),
        ...(source?.dataset ? { dataset: source.dataset } : {}),
        ...(source?.projectId ? { projectId: source.projectId } : {}),
        perspective: ["published"],
    };
    return createClient(config);
}
/**
 * Create or return a cached Sanity client.
 *
 * When a ResolvedSourceConfig is provided, its projectId, dataset, and perspective
 * override the defaults. For release perspectives, the perspective is
 * passed as a stacked array: [perspectiveId, "published"].
 */
export function getSanityClient(overrides, source) {
    // If a source is provided, always create a fresh client (don't cache)
    if (source) {
        const config = {
            ...getDefaultConfig(),
            ...overrides,
            ...(source.dataset ? { dataset: source.dataset } : {}),
            ...(source.projectId ? { projectId: source.projectId } : {}),
            ...(source.perspective
                ? { perspective: [source.perspective, "published"] }
                : {}),
        };
        return createClient(config);
    }
    if (_client && !overrides) {
        return _client;
    }
    const config = { ...getDefaultConfig(), ...overrides };
    _client = createClient(config);
    return _client;
}
// ---------------------------------------------------------------------------
// AILF private-dataset client (D0043)
// ---------------------------------------------------------------------------
/**
 * Build the default config for clients that read/write AILF documents
 * (ailf.report, ailf.task, ailf.job, ailf.featureArea, ailf.evalRequest).
 *
 * Dataset precedence: explicit `AILF_REPORT_DATASET` overrides; otherwise
 * fall back to `SANITY_DATASET` so existing CI workflows that pin a
 * test/staging dataset (e.g. Tier 2 with `SANITY_DATASET=ailf-test`)
 * continue to work without a new env var. The hard-coded fallback is
 * `AILF_DATASET_DEFAULT` (`ailf-prod-private`, D0043) — only reached for
 * ad-hoc runs with no env at all.
 *
 * Token resolution prefers the AILF-scoped token, falling back to
 * the shared `SANITY_API_TOKEN`.
 */
function getAilfDefaultConfig() {
    return {
        apiVersion: new Date().toISOString().split("T")[0],
        dataset: 
        // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
        process.env.AILF_REPORT_DATASET ||
            // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
            process.env.SANITY_DATASET ||
            AILF_DATASET_DEFAULT,
        projectId: 
        // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
        process.env.AILF_REPORT_PROJECT_ID ||
            // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
            process.env.SANITY_PROJECT_ID ||
            "3do82whm",
        token: process.env.AILF_REPORT_SANITY_API_TOKEN ?? process.env.SANITY_API_TOKEN,
        useCdn: false,
    };
}
let _ailfClient = null;
/**
 * Get a Sanity client targeting the AILF private dataset.
 *
 * Use this for reads and writes against `ailf.*` document types. The
 * returned client is cached when called without overrides.
 *
 * @param overrides - Per-call config overrides (e.g., explicit token, dataset).
 */
export function getAilfSanityClient(overrides) {
    if (_ailfClient && !overrides) {
        return _ailfClient;
    }
    const config = { ...getAilfDefaultConfig(), ...overrides };
    const client = createClient(config);
    if (!overrides)
        _ailfClient = client;
    return client;
}
/**
 * Reset the cached AILF client. Test-only — call from `beforeEach` when
 * mutating env vars between tests so the cached client doesn't leak.
 */
export function resetAilfSanityClientCache() {
    _ailfClient = null;
}
/**
 * Build a Cross Dataset Reference from an AILF document into editorial content,
 * with env-aware defaults for `projectId` / `dataset` so call sites can pass
 * just the `refId` in the common case.
 *
 * Use this for any reference field on an `ailf.*` document that points at an
 * editorial type (`article`, `docPage`, …). The schema-side counterpart is a
 * `crossDatasetReference` field with matching `dataset` and `weak: true`.
 *
 * @example
 *   const docRef = buildEditorialReference(articleId)
 *   // → { _type: "crossDatasetReference", _projectId: "3do82whm",
 *   //     _dataset: "next", _ref: articleId, _weak: true }
 */
export function buildEditorialReference(refId, options = {}) {
    // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
    const envProjectId = process.env.AILF_REPORT_PROJECT_ID || process.env.SANITY_PROJECT_ID;
    // Editorial dataset precedence: explicit AILF_EDITORIAL_DATASET overrides;
    // otherwise reuse SANITY_DATASET (which CI workflows already pin to the
    // correct editorial dataset); fall back to "next" only when nothing is set.
    // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back
    const envDataset = process.env.AILF_EDITORIAL_DATASET || process.env.SANITY_DATASET;
    return makeEditorialReference({
        projectId: options.projectId ?? envProjectId ?? "3do82whm",
        dataset: options.dataset ?? envDataset ?? EDITORIAL_DATASET_DEFAULT,
        refId,
        weak: options.weak,
    });
}
