/**
 * Server-side message catalogue — German (default) and English.
 *
 * Everything the API can put in front of a visitor lives here: validation errors, the
 * neutral submit/confirm responses, the registration type labels and the wording of the
 * three outgoing mails.
 *
 * WHICH LANGUAGE IS USED WHERE
 *   · HTTP responses  → the `lang` field of the request body (the language on screen).
 *   · Outgoing mails  → the language STORED ON THE REGISTRATION ROW, i.e. the one the
 *     visitor actually registered in. A confirmation link opened months later in another
 *     browser must not change the language of a mail they already expect in English.
 *   · Internal operations mail (NUXT_NOTIFY_EMAIL) stays German on purpose — it is not a
 *     visitor-facing text, it goes to the operator.
 *
 * German is the fallback for anything unrecognised, so a missing or bogus `lang` can only
 * ever produce German, never an empty string.
 */
import { normaliseType } from './registrationTypes'

export type ApiLang = 'de' | 'en'

export const DEFAULT_API_LANG: ApiLang = 'de'

/** Normalises anything (query value, body field, DB column) to a supported language. */
export const asLang = (value: unknown): ApiLang => {
  const v = String(value ?? '').trim().toLowerCase()
  return v === 'en' ? 'en' : DEFAULT_API_LANG
}

type ValidationMessages = {
  type: string
  contactName: string
  acceptTerms: string
  emailRequired: string
  emailInvalid: string
  emailFreemail: string
  stoid: string
  orgName: string
  street: string
  plz: string
  city: string
  domainMismatchWithSites: (domain: string, clinic: string) => string
  domainMismatchNoSites: (expected: string) => string
}

type ApiMessages = {
  genericOk: string
  throttled: string
  checkFields: string
  saveFailed: string
  noToken: string
  invalidToken: string
  alreadyConfirmed: string
  notValid: string
  expired: string
  confirmed: string
}

type MailMessages = {
  htmlLang: string
  brandTagline: string
  autoNote: string
  notRequested: string
  greeting: (name: string) => string
  types: Record<string, { label: string, orgRow: string, text: string }>
  fallbackOrgRow: string
  confirmation: {
    subject: string
    preheader: string
    heading: string
    intro: string
    button: string
    linkFallback: string
    manualNotice: string
    manualNoticeLabel: string
    rowType: string
    rowAddress: string
    rowEmail: string
    validity: string
    textIntro: string
    textLinkLead: string
    textRegisteredAs: (label: string) => string
    textAddress: (address: string) => string
    textManual: string
    footer: string
  }
  welcome: {
    subject: string
    preheader: string
    heading: string
    confirmed: (org: string, type: string) => string
    credentials: string
    manual: string
    pending: string
    listTitle: string
    list: string[]
    textCredentials: string
    textManual: string
    textPending: string
  }
  duplicate: {
    subject: string
    preheader: string
    intro: (org: string) => string
    rowTime: string
    rowEmail: string
    reassure: string
    reassureLead: string
    unknown: string
  }
}

type ServerCatalogue = {
  validation: ValidationMessages
  api: ApiMessages
  typeLabel: Record<string, string>
  mail: MailMessages
}

const de: ServerCatalogue = {
  validation: {
    type: 'Bitte wählen Sie aus, als was Sie sich registrieren möchten.',
    contactName: 'Bitte geben Sie Ihren Vor- und Nachnamen an.',
    acceptTerms: 'Bitte bestätigen Sie die Datenschutzhinweise.',
    emailRequired: 'Bitte geben Sie Ihre dienstliche E-Mail-Adresse an.',
    emailInvalid: 'Diese E-Mail-Adresse ist nicht gültig.',
    emailFreemail: 'Bitte verwenden Sie Ihre dienstliche E-Mail-Adresse '
      + '(keine privaten Anbieter wie GMX, Web.de, Gmail oder T-Online).',
    stoid: 'Bitte wählen Sie Ihre Klinik aus der Vorschlagsliste aus.',
    orgName: 'Bitte geben Sie den Namen Ihres Unternehmens an.',
    street: 'Bitte geben Sie die Straße und Hausnummer an.',
    plz: 'Bitte geben Sie eine gültige 5-stellige Postleitzahl an.',
    city: 'Bitte geben Sie den Ort an.',
    domainMismatchWithSites: (domain, clinic) =>
      `Die E-Mail-Domain „${domain}“ gehört nicht zu „${clinic}“. `
      + 'Bitte wählen Sie unten Ihren Standort aus.',
    domainMismatchNoSites: (expected) =>
      `Bitte verwenden Sie eine E-Mail-Adresse der Domain „${expected}“. `
      + 'Alternativ prüfen wir Ihre Registrierung manuell — nutzen Sie dafür das Bemerkungsfeld.',
  },
  api: {
    genericOk: 'Vielen Dank! Wenn die Angaben gültig sind, erhalten Sie in Kürze eine E-Mail '
      + 'mit einem Bestätigungslink. Bitte prüfen Sie auch Ihren Spam-Ordner.',
    throttled: 'Zu viele Anfragen. Bitte versuchen Sie es in einigen Minuten erneut.',
    checkFields: 'Bitte prüfen Sie die markierten Felder.',
    saveFailed: 'Die Registrierung konnte nicht gespeichert werden. Bitte versuchen Sie es später erneut.',
    noToken: 'Es wurde kein Bestätigungslink übermittelt.',
    invalidToken: 'Dieser Bestätigungslink ist ungültig oder wurde bereits verwendet. '
      + 'Bitte registrieren Sie sich erneut.',
    alreadyConfirmed: 'Ihre E-Mail-Adresse ist bereits bestätigt.',
    notValid: 'Diese Registrierung ist nicht mehr gültig.',
    expired: 'Dieser Bestätigungslink ist abgelaufen (14 Tage). Bitte registrieren Sie sich erneut.',
    confirmed: 'Vielen Dank! Ihre E-Mail-Adresse ist bestätigt.',
  },
  typeLabel: {
    klinik: 'Klinik',
    kurierdienst: 'Medizinischer Kurierdienst',
  },
  mail: {
    htmlLang: 'de',
    brandTagline: 'Blutkonserven-Plattform für Kliniken',
    autoNote: 'Diese E-Mail wurde automatisch erzeugt. Bei Fragen antworten Sie einfach auf diese Nachricht.',
    notRequested: 'Sie haben diese Registrierung nicht angefordert? Dann ignorieren Sie diese E-Mail '
      + '&ndash; ohne Bestätigung wird kein Zugang eingerichtet.',
    greeting: (name) => (name ? `Guten Tag ${name},` : 'Guten Tag,'),
    types: {
      klinik: {
        label: 'Klinik',
        orgRow: 'Einrichtung',
        text: 'Ob Sie Konserven abgeben, beziehen oder beides — das wählen Sie bei Ihrer ersten '
          + 'Anmeldung in Blut24 aus; mindestens eine Rolle ist erforderlich. Ihre Bestände '
          + 'bleiben dabei in Ihrer Hand: andere Kliniken sehen ausschließlich Summen je '
          + 'Produkt, niemals einzelne Konservennummern.',
      },
      kurierdienst: {
        label: 'Medizinischer Kurierdienst',
        orgRow: 'Unternehmen',
        text: 'Als medizinischer Kurierdienst erhalten Sie Transportaufträge der angeschlossenen '
          + 'Kliniken direkt auf das Smartphone und bestätigen Abholung und Zustellung in der '
          + 'Blut24-App. Die Teilnahme ist kostenlos. Wir prüfen Ihre Angaben nach der '
          + 'Bestätigung manuell und melden uns bei Ihnen.',
      },
    },
    fallbackOrgRow: 'Einrichtung',
    confirmation: {
      subject: 'Blut24: Bitte bestätigen Sie Ihre Registrierung',
      preheader: 'Bestätigen Sie Ihre E-Mail-Adresse, um Ihren Blut24-Zugang einzurichten.',
      heading: 'Nur noch ein Schritt: E-Mail bestätigen',
      intro: 'vielen Dank für Ihre Registrierung bei <strong>Blut24</strong>. Bitte bestätigen Sie Ihre '
        + 'E-Mail-Adresse, damit wir Ihren Zugang einrichten können. Die Nutzung ist für Kliniken '
        + 'kostenlos.',
      button: 'E-Mail-Adresse bestätigen',
      linkFallback: 'Falls die Schaltfläche nicht funktioniert, kopieren Sie diesen Link in Ihren Browser:',
      manualNoticeLabel: 'Hinweis:',
      // Neutral wording on purpose: this notice also goes to couriers, for whom no
      // domain register exists at all — not only to clinics without a stored domain.
      manualNotice: ' Ihre Angaben lassen sich nicht automatisch mit einem hinterlegten Verzeichnis abgleichen. '
        + 'Nach Ihrer Bestätigung prüfen wir sie manuell und melden uns innerhalb eines Werktages bei Ihnen.',
      rowType: 'Registrierung als',
      rowAddress: 'Anschrift',
      rowEmail: 'E-Mail',
      validity: 'Der Bestätigungslink ist 14 Tage gültig.',
      textIntro: 'vielen Dank für Ihre Registrierung bei Blut24. Die Nutzung ist für Kliniken kostenlos.',
      textLinkLead: 'Bitte bestätigen Sie Ihre E-Mail-Adresse über diesen Link:',
      textRegisteredAs: (label) => `Registrierung als: ${label}`,
      textAddress: (address) => `Anschrift: ${address}`,
      textManual: 'Hinweis: Ihre Angaben lassen sich nicht automatisch abgleichen. '
        + 'Nach Ihrer Bestätigung prüfen wir sie manuell.',
      footer: 'Blut24 — Blutkonserven-Plattform für Kliniken',
    },
    welcome: {
      subject: 'Blut24: Registrierung bestätigt',
      preheader: 'Ihre Registrierung bei Blut24 ist bestätigt.',
      heading: 'Registrierung bestätigt',
      confirmed: (org, type) => `Ihre E-Mail-Adresse ist bestätigt. <strong>${org}</strong> ist als `
        + `<strong>${type}</strong> bei Blut24 registriert.`,
      // Der Normalfall: Die Registrierung wurde automatisch freigeschaltet, der Zugang ist
      // angelegt und die Zugangsdaten sind bereits unterwegs. Kein Hinweis auf eine Prüfung
      // — die findet in diesem Fall nicht statt.
      credentials: 'Ihr Zugang ist eingerichtet und ab sofort nutzbar. Benutzername und Passwort '
        + 'erhalten Sie in einer separaten E-Mail. Bitte ändern Sie das Passwort nach der '
        + 'ersten Anmeldung.',
      manual: 'Wir prüfen Ihre Angaben nun manuell und richten Ihren Zugang anschließend ein. '
        + 'Sie hören innerhalb eines Werktages von uns.',
      pending: 'Wir richten Ihren Zugang jetzt ein und senden Ihnen die Zugangsdaten in einer '
        + 'separaten E-Mail.',
      listTitle: 'Was Sie mit Blut24 tun können:',
      list: [
        'Konserven per Scan erfassen &ndash; ohne Medienbruch',
        'Verfügbare Bestände anderer Kliniken deutschlandweit einsehen',
        'Bestellen und den DGTI-Lieferschein direkt übernehmen',
        'Verfallsdaten je Konserve im Blick behalten (FEFO)',
      ],
      textCredentials: 'Ihr Zugang ist eingerichtet und ab sofort nutzbar. Benutzername und Passwort '
        + 'erhalten Sie in einer separaten E-Mail. Bitte ändern Sie das Passwort nach der '
        + 'ersten Anmeldung.',
      textManual: 'Wir prüfen Ihre Angaben manuell und melden uns innerhalb eines Werktages.',
      textPending: 'Wir richten Ihren Zugang ein und senden die Zugangsdaten separat.',
    },
    duplicate: {
      subject: 'Blut24: erneuter Registrierungsversuch für Ihre Einrichtung',
      preheader: 'Es wurde kein zweiter Zugang angelegt.',
      intro: (org) => `für <strong>${org}</strong> ist bereits ein Zugang bei <strong>Blut24</strong> `
        + 'registriert. Soeben wurde ein weiterer Registrierungsversuch für dieselbe Einrichtung '
        + 'unternommen.',
      rowTime: 'Zeitpunkt',
      rowEmail: 'Angegebene E-Mail-Adresse',
      reassure: '<strong>Sie müssen nichts tun.</strong> Es wurde kein zweiter Zugang angelegt und Ihr '
        + 'bestehender Zugang ist unverändert. Wenn eine Kollegin oder ein Kollege einen eigenen '
        + 'Zugang benötigt, können Sie weitere Benutzer direkt in Blut24 anlegen.',
      reassureLead: 'Sie müssen nichts tun. Es wurde kein zweiter Zugang angelegt.',
      unknown: 'Kommt Ihnen der Versuch nicht bekannt vor, antworten Sie bitte einfach auf diese E-Mail.',
    },
  },
}

const en: ServerCatalogue = {
  validation: {
    type: 'Please choose what you would like to register as.',
    contactName: 'Please enter your first and last name.',
    acceptTerms: 'Please confirm the privacy notice.',
    emailRequired: 'Please enter your work e-mail address.',
    emailInvalid: 'This e-mail address is not valid.',
    emailFreemail: 'Please use your work e-mail address '
      + '(no private providers such as GMX, Web.de, Gmail or T-Online).',
    stoid: 'Please choose your hospital from the suggestion list.',
    orgName: 'Please enter the name of your company.',
    street: 'Please enter the street and house number.',
    plz: 'Please enter a valid 5-digit German postcode.',
    city: 'Please enter the town.',
    domainMismatchWithSites: (domain, clinic) =>
      `The e-mail domain “${domain}” does not belong to “${clinic}”. `
      + 'Please choose your site below.',
    domainMismatchNoSites: (expected) =>
      `Please use an e-mail address on the domain “${expected}”. `
      + 'Alternatively we can review your registration manually — please use the comment field.',
  },
  api: {
    genericOk: 'Thank you. If the details are valid, you will shortly receive an e-mail with a '
      + 'confirmation link. Please check your spam folder as well.',
    throttled: 'Too many requests. Please try again in a few minutes.',
    checkFields: 'Please check the highlighted fields.',
    saveFailed: 'The registration could not be saved. Please try again later.',
    noToken: 'No confirmation link was supplied.',
    invalidToken: 'This confirmation link is invalid or has already been used. Please register again.',
    alreadyConfirmed: 'Your e-mail address has already been confirmed.',
    notValid: 'This registration is no longer valid.',
    expired: 'This confirmation link has expired (14 days). Please register again.',
    confirmed: 'Thank you. Your e-mail address is confirmed.',
  },
  typeLabel: {
    klinik: 'hospital',
    kurierdienst: 'medical courier service',
  },
  mail: {
    htmlLang: 'en',
    brandTagline: 'The blood unit platform for hospitals',
    autoNote: 'This e-mail was generated automatically. If you have any questions, simply reply to it.',
    notRequested: 'Did you not request this registration? Then please ignore this e-mail '
      + '&ndash; without a confirmation no access is set up.',
    greeting: (name) => (name ? `Dear ${name},` : 'Hello,'),
    types: {
      klinik: {
        label: 'Hospital',
        orgRow: 'Facility',
        text: 'Whether you supply units, obtain them or do both — you choose that at your first '
          + 'sign-in to Blut24; at least one role is required. Your stock stays in your hands: '
          + 'other hospitals only ever see totals per product, never individual unit numbers.',
      },
      kurierdienst: {
        label: 'Medical courier service',
        orgRow: 'Company',
        text: 'As a medical courier service you receive transport jobs from the connected hospitals '
          + 'straight on your smartphone and confirm pick-up and delivery in the Blut24 app. Taking '
          + 'part is free of charge. After you confirm, we review your details manually and get back '
          + 'to you.',
      },
    },
    fallbackOrgRow: 'Facility',
    confirmation: {
      subject: 'Blut24: please confirm your registration',
      preheader: 'Confirm your e-mail address to have your Blut24 access set up.',
      heading: 'One step left: confirm your e-mail',
      intro: 'thank you for registering with <strong>Blut24</strong>. Please confirm your e-mail '
        + 'address so we can set up your access. Using Blut24 is free of charge for hospitals.',
      button: 'Confirm e-mail address',
      linkFallback: 'If the button does not work, copy this link into your browser:',
      manualNoticeLabel: 'Please note:',
      // Neutral wording on purpose: this notice also goes to couriers, for whom no
      // domain register exists at all — not only to clinics without a stored domain.
      manualNotice: ' Your details cannot be matched automatically against a directory on record. '
        + 'After you confirm, we will review them manually and get back to you within one working day.',
      rowType: 'Registered as',
      rowAddress: 'Address',
      rowEmail: 'E-mail',
      validity: 'The confirmation link is valid for 14 days.',
      textIntro: 'thank you for registering with Blut24. Using Blut24 is free of charge for hospitals.',
      textLinkLead: 'Please confirm your e-mail address using this link:',
      textRegisteredAs: (label) => `Registered as: ${label}`,
      textAddress: (address) => `Address: ${address}`,
      textManual: 'Please note: your details cannot be matched automatically. After you '
        + 'confirm, we will review them manually.',
      footer: 'Blut24 — the blood unit platform for hospitals',
    },
    welcome: {
      subject: 'Blut24: registration confirmed',
      preheader: 'Your registration with Blut24 is confirmed.',
      heading: 'Registration confirmed',
      confirmed: (org, type) => `Your e-mail address is confirmed. <strong>${org}</strong> is registered `
        + `with Blut24 as a <strong>${type}</strong>.`,
      // The normal case: the registration was activated automatically, the account exists
      // and the credentials are already on their way. No mention of a review — there is none.
      credentials: 'Your access is set up and ready to use. Your username and password arrive in a '
        + 'separate e-mail. Please change the password after your first sign-in.',
      manual: 'We will now review your details manually and set up your access afterwards. You will '
        + 'hear from us within one working day.',
      pending: 'We are setting up your access now and will send your login details in a separate e-mail.',
      listTitle: 'What you can do with Blut24:',
      list: [
        'Capture units by scanning &ndash; with no media break',
        'See the available stock of other hospitals across Germany',
        'Order and take over the DGTI delivery note directly',
        'Keep an eye on the expiry date of every unit (FEFO)',
      ],
      textCredentials: 'Your access is set up and ready to use. Your username and password arrive in '
        + 'a separate e-mail. Please change the password after your first sign-in.',
      textManual: 'We will review your details manually and get back to you within one working day.',
      textPending: 'We are setting up your access and will send the login details separately.',
    },
    duplicate: {
      subject: 'Blut24: another registration attempt for your facility',
      preheader: 'No second account was created.',
      intro: (org) => `<strong>${org}</strong> already has an account with <strong>Blut24</strong>. `
        + 'Another registration attempt has just been made for the same facility.',
      rowTime: 'Time',
      rowEmail: 'E-mail address given',
      reassure: '<strong>There is nothing you need to do.</strong> No second account was created and '
        + 'your existing access is unchanged. If a colleague needs their own account, you can create '
        + 'further users directly in Blut24.',
      reassureLead: 'There is nothing you need to do. No second account was created.',
      unknown: 'If this attempt is unfamiliar to you, please simply reply to this e-mail.',
    },
  },
}

const CATALOGUE: Record<ApiLang, ServerCatalogue> = { de, en }

export const serverMessages = (lang: unknown): ServerCatalogue => CATALOGUE[asLang(lang)]

/**
 * Registration type label in the requested language.
 *
 * READ PATH — the value may come off a stored row, so a retired type ('abgebende_klinik',
 * 'beziehende_klinik') is normalised to 'klinik' first. Without that, someone opening a
 * confirmation link written under the old three-type flow would be told, on the
 * confirmation page and in the welcome mail, that they are registered as
 * "abgebende_klinik" — a leaked internal identifier in the two most visible strings.
 * Anything genuinely unknown still falls back to the raw key rather than to an empty one.
 */
export const typeLabelFor = (type: string, lang: unknown): string => {
  const catalogue = serverMessages(lang).typeLabel
  return catalogue[type] || catalogue[normaliseType(type)] || type
}
