/**
 * Multi-QAF variant context for the QVS Preview (QVS-P4, KAR-973,
 * architecture.md §7 P4, gap-analysis G5, ux-flow.md §4).
 *
 * G5 (Klasse C, strukturell): a Multi-QAF CONTAINER file
 * (`qaf_file.template_type = 'MULTI_QAF'`) never gets `qaf_manufacturing_step`
 * rows at ingest (app/qaf-differences/actions.ts's `kind: 'multi_qaf'` ingest
 * branch: "no G60/summary parse, no qaf_manufacturing_step/qaf_summary_metric
 * rows") — its own Fertigungskosten data is a GETEILTES Profil-Aggregat
 * (`SharedCostProfile`, flat key/value, no per-step sequence), not a mappable
 * step list. `assessManufacturingCapability` on such a file's (empty) rows
 * always returns `eligible: false` — there is nothing for QVS to import
 * FROM a container file directly, and this module makes no attempt to
 * fabricate one (bridge.ts's own `steps` omission already documents exactly
 * this absence for the comparison engine; the same absence applies here).
 *
 * The buildable case is `multi_qaf_variant_vs_standard` (comparison-mode.ts's
 * `COMPARISON_MODE_RULES`): `alt`/`baseline_file_id` is ALWAYS a real
 * Summary-shaped standard QAF (genuine `qaf_manufacturing_step` rows, maps
 * exactly like any other QVS-eligible file — nothing about the mapper
 * changes), `neu`/`comparison_file_id` is ALWAYS the Multi-QAF container
 * (`swapSupported: false` — this role assignment is structurally fixed, never
 * swapped). This module's job: given the STANDARD file's id (the one QVS is
 * actually importing from), find whether it is the `alt` side of such a
 * comparison, and if so surface an evidence-scoped variant list so the
 * Preview can offer "geteilter Fluss" (tag the standard file's own real
 * nodes with those variant keys) vs. "je Variante ein Stream" (N creates,
 * IDENTICAL nodes, one variant tag each — ux-flow.md §4: "Zykluszeiten sind
 * im QAF nicht variantenspezifisch", never fabricated per-variant step data).
 *
 * Review-Fix 1 (KAR-973 adversarial review, MAJOR — "Geteilter Fluss"
 * über-generalisiert): this module used to return `container.activeVariants`
 * UNCONDITIONALLY the moment any qualifying comparison existed — i.e. it read
 * "a Multi-QAF variant was compared against this standard file" as license to
 * claim the standard file's manufacturing flow is shared by EVERY active
 * variant in the container. Two domain facts the old code never consulted
 * make that an over-claim: (1) a container's variants may legitimately run
 * on DIFFERENT manufacturing profiles/plants
 * (`lib/qaf-differences/internal/multi-qaf/types.ts` `sharedManufacturingProfiles`,
 * `variantProfileBindings`, `SharedCostProfileKind` includes `'location'`);
 * (2) the comparison itself never checks manufacturing/process compatibility
 * at all (`variant-vs-standard.ts` `DEGRADED_MODULES` documents
 * `manufacturing_steps` as structurally unavailable for this comparison
 * mode). 00-master-prompt-multi-qaf.md §12 is explicit: "Do not assume that
 * all variants use the same manufacturing total." — and §15: "Do not compare
 * an entire Multi-QAF container with one standard QAF as if they represented
 * the same scope."
 *
 * Corrected, conservative contract (Nie-fabrizieren-Doktrin): `variants` now
 * contains ONLY (a) the variant the comparison was ACTUALLY run against
 * (`qaf_comparison.engine_version.selectedVariantId`, read here for the
 * first time — see `createVariantVsStandardComparison`,
 * app/qaf-differences/actions.ts, for how it is persisted) and (b) any OTHER
 * active variant whose OWN `variantProfileBindings` entry names the SAME
 * `profileId` as the compared variant's — i.e. provably shares the identical
 * `SharedCostProfile` object (in practice, container-assembly.ts populates
 * `variantProfileBindings` from the Summary sheet's manufacturing-cost row
 * specifically, so a shared `profileId` here IS a shared manufacturing
 * profile, not merely "same container"). When the compared variant carries
 * NO binding evidence at all (bindings missing/empty), `variants` is JUST
 * that one compared variant — never a guess about the rest. See
 * `sameProfileVariants` below and `QvsVariantContext.sharedProfileConfirmed`.
 *
 * Read-only, RLS-scoped (never lib/supabase/admin.ts, same discipline as
 * qaf-source.ts), additive: absence (no such comparison exists for this file
 * — the overwhelming majority of QVS imports) is `null`, never an error.
 * `deserializeMultiQafContainer`/`MultiQafContainer` are imported from
 * `@/lib/qaf-differences`'s public barrel only (ADR 019 golden path — no
 * deep import into that module's internal/).
 */

import type { SupabaseClient } from '@supabase/supabase-js'
import { logger } from '@/lib/logger'
import { deserializeMultiQafContainer, type MultiQafContainer, type VariantDefinition } from '@/lib/qaf-differences'

export interface MultiQafVariantSummary {
  /** `VariantDefinition.compositeCanonicalKey` (reorder/rename-stable) when
   * non-empty, else `stableInternalId` — same empty-string-sentinel guard
   * bridge.ts's `virtualVariantSummary` already documents (an empty
   * `compositeCanonicalKey` means "zero dimensions, no fallback", not a real
   * key; stamping it through would let two identity-less variants collide). */
  variantKey: string
  /** Best available human-readable label — never fabricated, falls back
   * through originalLabels[0] -> originalVariantNumber -> stableInternalId
   * (the last is always present, so this field is never empty). */
  label: string
  /** `annualVolume ?? peakVolume` — whichever the container actually
   * populated; `null` when neither is known (never a fabricated 0). */
  volume: number | null
}

export interface QvsVariantContext {
  variants: readonly MultiQafVariantSummary[]
  /** true when a qualifying comparison/container WAS found but its data
   * could not be read/deserialized (or — Review-Fix 1 — the comparison's own
   * `selectedVariantId` could not be resolved to a real, active variant in
   * the container) — distinct from "no such comparison exists" (which is a
   * plain `null` QvsVariantContext, not this shape at all). Same "advisory
   * failure must not masquerade as a clean empty result" discipline as
   * duplicates.ts's `FindExistingImportsResult`. */
  degraded: boolean
  /** Review-Fix 1: true when the entries in `variants` BEYOND the compared
   * variant itself were included because `variantProfileBindings` provably
   * ties them to the SAME `SharedCostProfile.profileId` as the compared
   * variant — i.e. the "geteilter Fertigungsfluss" claim for this list is
   * evidence-backed, not assumed. False means the compared variant carried
   * NO profile-binding evidence at all, so `variants` conservatively
   * contains ONLY that one variant (absence of binding data is not proof
   * that no other variant shares its flow, but it is equally not proof that
   * any of them do — see module header). Always `false` (meaningless) when
   * `degraded` is true. */
  sharedProfileConfirmed: boolean
}

function variantSummaryFrom(d: VariantDefinition): MultiQafVariantSummary {
  return {
    variantKey: d.compositeCanonicalKey !== '' ? d.compositeCanonicalKey : d.stableInternalId,
    label: d.originalLabels[0] ?? d.originalVariantNumber ?? d.stableInternalId,
    volume: d.annualVolume ?? d.peakVolume ?? null,
  }
}

/**
 * Review-Fix 1: the compared variant (`selected`) is ALWAYS included; any
 * OTHER active variant is included ONLY when `container.variantProfileBindings`
 * names the SAME `profileId` for it as for `selected` — see
 * `QvsVariantContext.sharedProfileConfirmed` doc. Returns the confirmed flag
 * alongside the list so the caller never has to re-derive it.
 */
function sameProfileVariants(
  container: MultiQafContainer,
  selected: VariantDefinition,
): { variants: MultiQafVariantSummary[]; sharedProfileConfirmed: boolean } {
  const bindings = container.variantProfileBindings ?? []
  const selectedProfileIds = new Set(bindings.filter((b) => b.variantId === selected.stableInternalId).map((b) => b.profileId))

  if (selectedProfileIds.size === 0) {
    // No binding evidence for the compared variant itself — cannot prove ANY
    // other variant shares its (unknown) profile. Conservative: only the
    // compared variant (module header, Nie-fabrizieren-Doktrin).
    return { variants: [variantSummaryFrom(selected)], sharedProfileConfirmed: false }
  }

  const matching = container.activeVariants.filter(
    (d) =>
      d.stableInternalId === selected.stableInternalId ||
      bindings.some((b) => b.variantId === d.stableInternalId && selectedProfileIds.has(b.profileId)),
  )
  return { variants: matching.map(variantSummaryFrom), sharedProfileConfirmed: true }
}

/**
 * `qafFileId` is the STANDARD-side file QVS is building a preview/creation
 * for. Returns `null` when it is not the `alt` side of any
 * `multi_qaf_variant_vs_standard` comparison (the common case — no Varianten-
 * Sektion to show). Only queries the `baseline_file_id` direction — see
 * module header for why `comparison_file_id` never needs checking here
 * (that role is structurally always the container, never a QVS-eligible
 * file with steps of its own).
 */
export async function loadMultiQafVariantContext(supabase: SupabaseClient, qafFileId: string): Promise<QvsVariantContext | null> {
  const { data: comparisons, error: cmpError } = await supabase
    .from('qaf_comparison')
    .select('id, comparison_file_id, engine_version, created_at')
    .eq('baseline_file_id', qafFileId)
    .eq('comparison_mode', 'multi_qaf_variant_vs_standard')
    .order('created_at', { ascending: false })
    .limit(1)

  if (cmpError) {
    logger.warn('qvs.multi_qaf_context.comparison_query_failed', { message: cmpError.message, code: cmpError.code })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }
  const comparison = (comparisons ?? [])[0] as
    | { id: string; comparison_file_id: string | null; engine_version: { selectedVariantId?: string } | null }
    | undefined
  if (!comparison || !comparison.comparison_file_id) return null

  // Review-Fix 1: the ONE variant this comparison was actually run against —
  // `createVariantVsStandardComparison` (app/qaf-differences/actions.ts)
  // persists it here, never read by this module before this fix. Missing is
  // structurally unexpected for a row matching `comparison_mode` above
  // (every writer of that mode sets it) — fail closed rather than falling
  // back to "all variants" (the exact over-claim this fix removes).
  const selectedVariantId = comparison.engine_version?.selectedVariantId
  if (!selectedVariantId) {
    logger.warn('qvs.multi_qaf_context.selected_variant_id_missing', { comparisonId: comparison.id })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }

  const { data: containerFile, error: fileError } = await supabase
    .from('qaf_file')
    .select('g60_meta')
    .eq('id', comparison.comparison_file_id)
    .maybeSingle()

  if (fileError) {
    logger.warn('qvs.multi_qaf_context.container_file_query_failed', { message: fileError.message, code: fileError.code })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }
  // NOTE: deserializeMultiQafContainer takes the WHOLE `{modelVersion,
  // container}` envelope (JSON.stringify'd), not just the inner `container`
  // — same call shape app/qaf-differences/actions.ts's own
  // loadMultiQafComparisonContainers already uses for the identical column.
  const raw = (containerFile?.g60_meta as { multiQafContainer?: unknown } | null)?.multiQafContainer
  if (!raw) {
    // A comparison row exists and points at this file, but it carries no
    // container payload — structurally unexpected given comparisonModeRule's
    // own invariants, not a normal "nothing to show" case.
    logger.warn('qvs.multi_qaf_context.container_missing', { comparisonFileId: comparison.comparison_file_id })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }

  let container: MultiQafContainer
  try {
    container = deserializeMultiQafContainer(JSON.stringify(raw))
  } catch (e) {
    logger.warn('qvs.multi_qaf_context.container_deserialize_failed', { message: e instanceof Error ? e.message : String(e) })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }

  const selectedDefinition = container.activeVariants.find((d) => d.stableInternalId === selectedVariantId)
  if (!selectedDefinition) {
    // Structurally unexpected (the container should contain the exact
    // variant this comparison was run against) — e.g. the file was
    // re-ingested/re-assembled since. Fail closed rather than silently
    // showing nothing or fabricating a placeholder entry.
    logger.warn('qvs.multi_qaf_context.selected_variant_not_found', { selectedVariantId })
    return { variants: [], degraded: true, sharedProfileConfirmed: false }
  }

  const { variants, sharedProfileConfirmed } = sameProfileVariants(container, selectedDefinition)
  return { variants, degraded: false, sharedProfileConfirmed }
}
