/**
 * Initial-call questionnaire ("Erstgespräch-Fragebogen") for leads.
 *
 * ONE catalog shared by the modal (app/components/offers/LeadQuestionnaireModal.vue)
 * and the server PDF renderer (server/utils/offers/questionnairePdf.ts) — the
 * server imports it via `../../../app/utils/leadQuestionnaire` exactly like
 * `app/utils/iban.ts`. Keep it dependency-free (no Vue / no h3).
 *
 * Question types:
 *   bool    → Ja / Nein checkboxes (answer: true | false | null)
 *   number  → numeric input (+ optional unit)              (answer: number | '')
 *   text    → single-line text                             (answer: string)
 *   textarea→ multi-line text                              (answer: string)
 *   choice  → exactly one of `options` (exclusive boxes)   (answer: option key | '')
 *   multi   → any of `options` (checkbox list)             (answer: option keys[])
 *   Any question may carry `detail` → an extra free-text line ("Welche? / Which?")
 *   whose answer is stored under `<id>_detail`. `unitChoice` renders a small
 *   exclusive unit picker next to a number (answer `<id>_unit`).
 *
 * Adding a question = one entry here; the form, the PDF, the saved JSON
 * (offer_conditions.questionnaire.answers) and the activity summary follow.
 */
export type QLang = 'de' | 'en'
export type QType = 'bool' | 'number' | 'text' | 'textarea' | 'choice' | 'multi'

export interface QOption { key: string; de: string; en: string; other?: boolean }
export interface QQuestion {
  id: string
  type: QType
  de: string
  en: string
  /** Muted helper line under the label. */
  hintDe?: string
  hintEn?: string
  /** Unit label printed after a number (e.g. "kg"). */
  unit?: string
  /** Exclusive unit picker for numbers (e.g. "%" vs "Stück"). */
  unitChoice?: QOption[]
  options?: QOption[]
  /** Extra free-text line (label per language) stored as `<id>_detail`. */
  detail?: { de: string; en: string }
  /** Placeholder for text inputs. */
  placeholderDe?: string
  placeholderEn?: string
}
export interface QCategory { id: string; de: string; en: string; icon: string; questions: QQuestion[] }

export const QUESTIONNAIRE_VERSION = 1

export const QUESTIONNAIRE: QCategory[] = [
  {
    id: 'status', de: 'Aktuelle Situation', en: 'Current situation', icon: 'ti-building-store',
    questions: [
      { id: 'selling', type: 'bool', de: 'Wird bereits verkauft / versendet?', en: 'Already selling / shipping?' },
      {
        id: 'fulfilment', type: 'choice', de: 'Versand aktuell selbst oder über Dienstleister?', en: 'Shipping currently in-house or via a service provider?',
        options: [
          { key: 'self', de: 'Selbst', en: 'In-house' },
          { key: 'provider', de: 'Dienstleister', en: 'Service provider' }
        ],
        detail: { de: 'Welcher Dienstleister?', en: 'Which provider?' }
      },
      {
        id: 'platforms', type: 'multi', de: 'Anzubindende Plattform(en) / Shopsystem', en: 'Platform(s) / shop system to integrate',
        options: [
          { key: 'shopify', de: 'Shopify', en: 'Shopify' },
          { key: 'amazon', de: 'Amazon', en: 'Amazon' },
          { key: 'ebay', de: 'eBay', en: 'eBay' },
          { key: 'woocommerce', de: 'WooCommerce', en: 'WooCommerce' },
          { key: 'shopware', de: 'Shopware', en: 'Shopware' },
          { key: 'jtl', de: 'JTL', en: 'JTL' },
          { key: 'plenty', de: 'PlentyONE', en: 'PlentyONE' },
          { key: 'otto', de: 'Otto', en: 'Otto' },
          { key: 'zalando', de: 'Zalando', en: 'Zalando' },
          { key: 'kaufland', de: 'Kaufland', en: 'Kaufland' },
          { key: 'other', de: 'Sonstige', en: 'Other', other: true }
        ],
        detail: { de: 'Sonstige / Details', en: 'Other / details' }
      },
      { id: 'eta', type: 'text', de: 'Geplanter Start der Zusammenarbeit (ETA)', en: 'Planned start of cooperation (ETA)', placeholderDe: 'z. B. Oktober 2026', placeholderEn: 'e.g. October 2026' }
    ]
  },
  {
    id: 'volume', de: 'Auftragsvolumen', en: 'Order volume', icon: 'ti-chart-bar',
    questions: [
      { id: 'ordersMonth', type: 'number', de: 'Ø Bestellungen pro Monat (aktuell)', en: 'Avg. orders per month (current)', unit: '/ Monat' },
      { id: 'ordersTarget12', type: 'number', de: 'Zielmenge Bestellungen in 12 Monaten', en: 'Target orders per month in 12 months', unit: '/ Monat' },
      { id: 'picksOrder', type: 'number', de: 'Ø Picks (Positionen) pro Bestellung', en: 'Avg. picks (line items) per order' },
      {
        id: 'returns', type: 'number', de: 'Ø Retouren pro Monat', en: 'Avg. returns per month',
        unitChoice: [
          { key: 'percent', de: '% der Bestellungen', en: '% of orders' },
          { key: 'absolute', de: 'Stück (absolut)', en: 'pieces (absolute)' }
        ]
      }
    ]
  },
  {
    id: 'articles', de: 'Artikel', en: 'Articles', icon: 'ti-package',
    questions: [
      { id: 'skuCount', type: 'number', de: 'Anzahl verschiedener SKUs (Artikel)', en: 'Number of different SKUs (articles)' },
      { id: 'weightAvg', type: 'number', de: 'Ø Gewicht je Artikel', en: 'Avg. weight per article', unit: 'kg' },
      { id: 'sizeAvg', type: 'text', de: 'Ø Größe je Artikel (L × B × H)', en: 'Avg. size per article (L × W × H)', placeholderDe: 'z. B. 20 × 15 × 10 cm', placeholderEn: 'e.g. 20 × 15 × 10 cm' },
      { id: 'barcode', type: 'bool', de: 'Barcode (EAN/GTIN) auf den Artikeln vorhanden?', en: 'Barcode (EAN/GTIN) present on the articles?' },
      { id: 'barcodeDigital', type: 'bool', de: 'Barcode-Nummern digital sauber hinterlegt (Webshop / ERP)?', en: 'Barcode numbers stored cleanly in digital form (webshop / ERP)?', hintDe: 'Je Artikel als EAN/GTIN-Feld gepflegt, nicht nur auf dem Etikett', hintEn: 'Maintained per article as an EAN/GTIN field, not only printed on the label' },
      { id: 'mhd', type: 'bool', de: 'MHD (Mindesthaltbarkeitsdatum) relevant?', en: 'Best-before date (BBD) relevant?', hintDe: 'Chargen-/FEFO-Verwaltung nötig', hintEn: 'Requires batch / FEFO handling' },
      { id: 'serials', type: 'bool', de: 'Seriennummern müssen erfasst, mitgesendet und nachverfolgt werden?', en: 'Serial numbers must be captured, sent with the order and tracked?' }
    ]
  },
  {
    id: 'services', de: 'Zusatzleistungen', en: 'Additional services', icon: 'ti-tools',
    questions: [
      {
        id: 'customization', type: 'bool', de: 'Individualisierung notwendig (Beilagen, Sticker, Geschenkverpackung, …)?', en: 'Customisation required (inserts, stickers, gift wrapping, …)?',
        detail: { de: 'Welche?', en: 'Which?' }
      },
      {
        id: 'assembly', type: 'bool', de: 'Konfektionierung / Produktion notwendig (Sets, Bundles, Umverpacken)?', en: 'Kitting / assembly (production) required (sets, bundles, repacking)?',
        detail: { de: 'Was genau?', en: 'What exactly?' }
      },
      { id: 'amazonPrime', type: 'bool', de: 'Amazon Prime (Seller Fulfilled Prime) notwendig – Versand bis 14:00 Uhr?', en: 'Amazon Prime (Seller Fulfilled Prime) required – same-day dispatch until 14:00?' },
      { id: 'amazonFba', type: 'bool', de: 'Amazon FBA notwendig?', en: 'Amazon FBA required?' },
      { id: 'amazonPreFba', type: 'bool', de: 'Amazon Pre-FBA (Vorbereitung inkl. FNSKU-Umetikettierung) notwendig?', en: 'Amazon Pre-FBA (prep incl. FNSKU relabelling) required?' }
    ]
  },
  {
    id: 'inbound', de: 'Wareneingang & Lagerung', en: 'Inbound & storage', icon: 'ti-truck-loading',
    questions: [
      { id: 'initialStock', type: 'textarea', de: 'Erstanlieferung: Menge, die eingelagert wird (Paletten / Kartons / Stückzahl)', en: 'Initial delivery: quantity to be stored (pallets / cartons / pieces)', placeholderDe: 'z. B. 6 Paletten, ca. 4.000 Artikel', placeholderEn: 'e.g. 6 pallets, approx. 4,000 articles' },
      { id: 'inboundMonth', type: 'number', de: 'Ø Wareneingänge (Lieferanten-Lieferungen) pro Monat', en: 'Avg. inbound shipments (supplier deliveries) per month', unit: '/ Monat' },
      {
        id: 'inboundSorted', type: 'choice', de: 'Wareneingänge sortenrein oder gemischt?', en: 'Inbound shipments single-SKU (sorted) or mixed?',
        options: [
          { key: 'sorted', de: 'Sortenrein', en: 'Sorted (single SKU per carton/pallet)' },
          { key: 'mixed', de: 'Gemischt / unsortiert', en: 'Mixed / unsorted' }
        ]
      }
    ]
  },
  {
    id: 'admin', de: 'Organisatorisches', en: 'Organisational', icon: 'ti-file-invoice',
    questions: [
      { id: 'vatId', type: 'bool', de: 'Umsatzsteuer-ID vorhanden?', en: 'VAT ID available?', detail: { de: 'USt-IdNr.', en: 'VAT ID' } },
      { id: 'notes', type: 'textarea', de: 'Weitere Notizen / Besonderheiten', en: 'Further notes / special requirements' }
    ]
  }
]

/** Flat list of all questions (category id attached). */
export const questionnaireQuestions = (): Array<QQuestion & { categoryId: string }> =>
  QUESTIONNAIRE.flatMap((c) => c.questions.map((q) => ({ ...q, categoryId: c.id })))

/** Empty answer object with every key present (form v-model friendly). */
export const emptyQuestionnaireAnswers = (): Record<string, any> => {
  const out: Record<string, any> = {}
  for (const q of questionnaireQuestions()) {
    out[q.id] = q.type === 'bool' ? null : q.type === 'multi' ? [] : ''
    if (q.detail) out[`${q.id}_detail`] = ''
    if (q.unitChoice) out[`${q.id}_unit`] = q.unitChoice[0]?.key || ''
  }
  return out
}

/** Merge saved answers into a fresh answer object (unknown keys ignored). */
export const mergeQuestionnaireAnswers = (saved: any): Record<string, any> => {
  const base = emptyQuestionnaireAnswers()
  if (!saved || typeof saved !== 'object') return base
  for (const k of Object.keys(base)) {
    if (!(k in saved)) continue
    const v = saved[k]
    if (Array.isArray(base[k])) base[k] = Array.isArray(v) ? v.map(String) : []
    else if (base[k] === null) base[k] = v === true ? true : v === false ? false : null
    else base[k] = v === null || v === undefined ? '' : v
  }
  return base
}

export const qLabel = (q: { de: string; en: string }, lang: QLang) => (lang === 'en' ? q.en : q.de)

/** Human-readable answer for one question (PDF filled mode, activity summary). */
export const formatQuestionnaireAnswer = (q: QQuestion, answers: Record<string, any>, lang: QLang): string => {
  const en = lang === 'en'
  const v = answers?.[q.id]
  let out = ''
  if (q.type === 'bool') out = v === true ? (en ? 'Yes' : 'Ja') : v === false ? (en ? 'No' : 'Nein') : ''
  else if (q.type === 'choice') out = (q.options || []).filter((o) => o.key === v).map((o) => qLabel(o, lang)).join('')
  else if (q.type === 'multi') out = (q.options || []).filter((o) => Array.isArray(v) && v.includes(o.key)).map((o) => qLabel(o, lang)).join(', ')
  else if (q.type === 'number') {
    if (v !== '' && v !== null && v !== undefined && !isNaN(Number(v))) {
      out = Number(v).toLocaleString(en ? 'en-GB' : 'de-DE')
      if (q.unitChoice) {
        const u = q.unitChoice.find((o) => o.key === answers?.[`${q.id}_unit`])
        if (u) out += ` ${qLabel(u, lang)}`
      } else if (q.unit) out += ` ${q.unit.replace('Monat', en ? 'month' : 'Monat')}`
    }
  } else out = String(v ?? '').trim()
  const detail = q.detail ? String(answers?.[`${q.id}_detail`] ?? '').trim() : ''
  if (detail) out = out ? `${out} — ${detail}` : detail
  return out
}

/** Count of answered questions (for the modal progress chip). */
export const questionnaireProgress = (answers: Record<string, any>): { answered: number; total: number } => {
  const qs = questionnaireQuestions().filter((q) => q.id !== 'notes')
  let answered = 0
  for (const q of qs) {
    const v = answers?.[q.id]
    const has = q.type === 'bool' ? v === true || v === false
      : q.type === 'multi' ? Array.isArray(v) && v.length > 0
      : v !== '' && v !== null && v !== undefined
    if (has) answered++
  }
  return { answered, total: qs.length }
}

/** File name of the rendered PDF. */
export const questionnaireFilename = (lang: QLang, company: string, mode: 'blank' | 'filled', date = new Date()): string => {
  const c = String(company || '').normalize('NFKD').replace(/[̀-ͯ]/g, '').replace(/[^A-Za-z0-9]+/g, '_').replace(/^_+|_+$/g, '').slice(0, 40)
  const d = date.toISOString().slice(0, 10)
  const base = lang === 'en' ? 'Questionnaire_Initial_Call' : 'Fragebogen_Erstgespraech'
  if (mode === 'blank') return `${base}_${lang === 'en' ? 'blank' : 'leer'}${c ? '_' + c : ''}.pdf`
  return `${base}${c ? '_' + c : ''}_${d}.pdf`
}
