/**
 * Branded organization identifiers.
 *
 * Every organization carries TWO distinct ID values that are both plain
 * strings at runtime but mean different things:
 *
 * - WorkOS organization id (`org_...`) -- the auth/JWT identity. Used for API
 *   requests, SSE headers, and org-scoped query keys.
 * - Supabase organization id (UUID) -- the database key. Used for
 *   `.eq('organization_id', ...)` queries and RLS scoping.
 *
 * They are not interchangeable, yet both are `string` -- so a swap compiles
 * cleanly and fails silently (zero rows on the Supabase side, cross-pollinated
 * cache keys on the API side). These brands make the two non-assignable to one
 * another, turning that silent footgun into a compile error at the sink.
 *
 * Mint a brand only through the `as*` factories below: they are the single
 * validate-and-tag boundary (compile-time brand + runtime format check). The
 * type predicates double as the cast, so no raw `as` cast is needed anywhere.
 *
 * Lives on the published `@repo/core` / `@repo/core/auth` surface so the UI,
 * the API, and the dogfooding `@repo/elevasis-*` packages can all use it.
 */

import { UuidSchema } from '../../platform/utils/validation'

declare const supabaseOrgIdBrand: unique symbol
declare const workOsOrgIdBrand: unique symbol

/** A Supabase organization id (UUID) -- the database key for RLS-scoped rows. */
export type SupabaseOrgId = string & { readonly [supabaseOrgIdBrand]: true }

/** A WorkOS organization id (`org_...`) -- the auth identity for API/SSE/query keys. */
export type WorkOsOrgId = string & { readonly [workOsOrgIdBrand]: true }

/** WorkOS organization ids are always prefixed with `org_` (incl. `org_test_...`). */
const WORKOS_ORG_ID_PREFIX = 'org_'

/** True when `value` is shaped like a Supabase organization UUID. */
export function isSupabaseOrgId(value: string): value is SupabaseOrgId {
  return UuidSchema.safeParse(value).success
}

/** True when `value` is shaped like a WorkOS organization id (`org_...`). */
export function isWorkOsOrgId(value: string): value is WorkOsOrgId {
  return value.startsWith(WORKOS_ORG_ID_PREFIX)
}

/**
 * Validate-and-brand a string as a Supabase organization id.
 *
 * @throws {Error} if the value is not a UUID (e.g. a WorkOS `org_...` id leaked in).
 */
export function asSupabaseOrgId(value: string): SupabaseOrgId {
  if (!isSupabaseOrgId(value)) {
    throw new Error(
      `Expected a Supabase organization UUID, received "${value}". ` +
        `A WorkOS org id (org_...) was likely used where the database key is required.`
    )
  }
  return value
}

/**
 * Validate-and-brand a string as a WorkOS organization id.
 *
 * @throws {Error} if the value is not `org_...` (e.g. a Supabase UUID leaked in).
 */
export function asWorkOsOrgId(value: string): WorkOsOrgId {
  if (!isWorkOsOrgId(value)) {
    throw new Error(
      `Expected a WorkOS organization id (org_...), received "${value}". ` +
        `A Supabase UUID was likely used where the auth identity is required.`
    )
  }
  return value
}

/** Nullable convenience for mint sites that read `... ?? null` from a membership. */
export function asSupabaseOrgIdOrNull(value: string | null | undefined): SupabaseOrgId | null {
  return value == null ? null : asSupabaseOrgId(value)
}

/** Nullable convenience for mint sites that read `... ?? null` from a membership. */
export function asWorkOsOrgIdOrNull(value: string | null | undefined): WorkOsOrgId | null {
  return value == null ? null : asWorkOsOrgId(value)
}

// ---------------------------------------------------------------------------
// Trusted-source casts (brand WITHOUT validating).
//
// Use these when the value is already known to be well-formed -- e.g. an
// organization id read from our own database/membership API, or a test
// fixture. They never throw, so they are safe at UI mint points (a provider
// must not white-screen on data shape) and avoid re-validating trusted DB
// UUIDs on every render. For UNTRUSTED input (route params, external ids)
// prefer the validating `as*` factories above, which throw on a bad shape.
// ---------------------------------------------------------------------------

/** Brand a trusted string as a Supabase organization id without validating. */
export function brandSupabaseOrgId(value: string): SupabaseOrgId
export function brandSupabaseOrgId(value: string | null | undefined): SupabaseOrgId | null
export function brandSupabaseOrgId(value: string | null | undefined): SupabaseOrgId | null {
  return (value ?? null) as SupabaseOrgId | null
}

/** Brand a trusted string as a WorkOS organization id without validating. */
export function brandWorkOsOrgId(value: string): WorkOsOrgId
export function brandWorkOsOrgId(value: string | null | undefined): WorkOsOrgId | null
export function brandWorkOsOrgId(value: string | null | undefined): WorkOsOrgId | null {
  return (value ?? null) as WorkOsOrgId | null
}
