// Teilbare Verweise auf einen Befund (Spezifikation Kap. 25, Invariante U-07).
//
// Jeder Befund muss als Link teilbar sein — in eine Besprechung, in ein Ticket,
// in ein Schreiben an den Lieferanten. Ein Bericht, aus dem man nur „Sektion
// Werkzeuge, irgendwo unten" zitieren kann, wird in der Praxis nicht zitiert.
//
// Pure Funktionen, keine I/O.

/** Die sieben Sektionen aus Kap. 21, in Anzeigereihenfolge. */
export const VIEW_SECTIONS = [
  'uebersicht',
  'praemissen',
  'material',
  'fertigung',
  'werkzeuge',
  'datenqualitaet',
  'massnahmen',
] as const

export type ViewSection = (typeof VIEW_SECTIONS)[number]

export interface DeepLinkTarget {
  comparisonId: string
  section: ViewSection
  /** Kennung im Differenzkatalog, auf die der Link zeigt. */
  differenceId?: string
  /** Kennung eines Datenqualitäts-Befunds. */
  findingId?: string
}

const DIFFERENCE_PATTERN = /^D-(IDT|SUM|MAT|MFG|SBM)-\d{3,}$/
const FINDING_PATTERN = /^DQ-(A|B|AB)-\d{3,}$/

export function isViewSection(value: string): value is ViewSection {
  return (VIEW_SECTIONS as readonly string[]).includes(value)
}

/**
 * Verweis bauen.
 *
 * Die Kennung wandert in die Fragment-Kennung und nicht in die Abfrage: So
 * springt die geöffnete Ansicht ohne erneutes Laden an die Zeile, und ein
 * Kopieren aus der Adresszeile trägt den Befund mit.
 */
export function buildDeepLink(target: DeepLinkTarget, basePath = '/qaf-differences'): string {
  const anchor = target.differenceId ?? target.findingId
  const query = new URLSearchParams({ comparison: target.comparisonId, section: target.section })
  return `${basePath}?${query.toString()}${anchor === undefined ? '' : `#${anchor}`}`
}

/**
 * Verweis lesen.
 *
 * `null` bei allem, was nicht passt — eine unbekannte Sektion oder eine
 * Kennung in fremdem Format stillschweigend auf die Übersicht zu leiten wäre
 * schlechter als eine ehrliche Fehlanzeige: Der Empfänger glaubt sonst, er sehe
 * den zitierten Befund.
 */
export function parseDeepLink(url: string): DeepLinkTarget | null {
  const [pfadUndAbfrage, fragment] = url.split('#')
  const fragezeichen = pfadUndAbfrage.indexOf('?')
  if (fragezeichen === -1) return null

  const params = new URLSearchParams(pfadUndAbfrage.slice(fragezeichen + 1))
  const comparisonId = params.get('comparison')
  const section = params.get('section')
  if (comparisonId === null || comparisonId === '' || section === null || !isViewSection(section)) return null

  const target: DeepLinkTarget = { comparisonId, section }
  if (fragment !== undefined && fragment !== '') {
    if (DIFFERENCE_PATTERN.test(fragment)) target.differenceId = fragment
    else if (FINDING_PATTERN.test(fragment)) target.findingId = fragment
    else return null
  }
  return target
}

/**
 * Die Sektion, in der eine Differenz zu Hause ist.
 *
 * Ohne diese Abbildung müsste jeder Verweis die Sektion mitschleppen, und ein
 * von Hand zusammengesetzter Link zeigte auf die falsche.
 */
export function sectionForDifference(differenceId: string): ViewSection | null {
  const m = /^D-(IDT|SUM|MAT|MFG|SBM)-/.exec(differenceId)
  if (m === null) return null
  switch (m[1]) {
    case 'IDT':
      return 'praemissen'
    case 'SUM':
      return 'uebersicht'
    case 'MAT':
      return 'material'
    case 'MFG':
      return 'fertigung'
    default:
      return 'werkzeuge'
  }
}
