// Fabrikanalyse-Export (Demo-067 C, KAR-982) — DOCX. Conceptual template:
// lib/assessment-export.ts's exportForAISummary (Markdown, same grouping —
// main category -> sub category -> question -> rating/comment — same AI-
// instruction framing). This builder produces the DOCX equivalent with the
// shared AI-instruction block prepended, and reads the DE columns directly
// (question_text_de / answer_text_N_de / label_de, falling back to the base
// column) instead of importing lib/assessment-lang.ts's getAssessmentText —
// that file starts with `'use client'`, so it must not be imported into a
// server-only builder (Next.js client/server module-graph boundary); output
// language is always German here anyway (task requirement), so the fallback
// is inlined below (`deText`).
//
// Pure function of its inputs — no Supabase/DB access. The caller (server
// action) loads assessment/questions/responses and passes plain rows in.

import type { Paragraph, Table } from 'docx'
import type { Assessment, AssessmentResponse, QuestionWithCategories, ResponseDraft } from '@/lib/assessment-types'
import { computeMainCategoryStats, computeOverallStats } from '@/lib/assessment-analytics'
import { buildAiInstructionBlock } from './ai-instruction-block'
import {
  bodyText,
  buildDocument,
  dataTable,
  docTitle,
  formatNumberDe,
  formatPercentDe,
  heading1,
  heading2,
  heading3,
  kvTable,
  packDocumentToBuffer,
  renderAiInstructionBlock,
  spacer,
} from './docx-shared'

const RATING_LABEL: Record<number, string> = {
  1: 'Nicht erfüllt',
  2: 'Teilweise',
  3: 'Erfüllt',
  4: 'Best Practice',
}

function deText(base: string, localized: string | null | undefined): string {
  return localized && localized.trim() !== '' ? localized : base
}

/** Same reshape as components/assessment/assessment-dashboard.tsx's local
 * initResponses() — duplicated (not imported) because that function lives
 * in a 'use client' component; identical defaults (is_relevant true,
 * is_flagged false, selected_rating null, comment ''). */
function toResponseDraftMap(
  questions: QuestionWithCategories[],
  responses: AssessmentResponse[],
): Record<string, ResponseDraft> {
  const byQ = new Map(responses.map((r) => [r.question_id, r]))
  const map: Record<string, ResponseDraft> = {}
  for (const q of questions) {
    const r = byQ.get(q.id)
    map[q.id] = {
      dbId: r?.id ?? null,
      is_relevant: r?.is_relevant ?? true,
      is_flagged: r?.is_flagged ?? false,
      selected_rating: r?.selected_rating ?? null,
      comment: r?.comment ?? '',
    }
  }
  return map
}

export interface AssessmentDocxInput {
  assessment: Assessment
  questions: QuestionWithCategories[]
  responses: AssessmentResponse[]
  /** Client-formatted timestamp (engine stays Date-free) — same convention
   * as QAF's generatedAtLabel (app/qaf-differences/actions.ts). */
  generatedAtLabel: string
}

export async function buildFabrikanalyseCopilotDocx(input: AssessmentDocxInput): Promise<Buffer> {
  const { assessment, questions, generatedAtLabel } = input
  const responses = toResponseDraftMap(questions, input.responses)

  const overall = computeOverallStats(questions, responses)
  const mainStats = computeMainCategoryStats(questions, responses)

  const dateStr = assessment.conducted_at
    ? new Date(assessment.conducted_at).toLocaleDateString('de-DE')
    : null

  const aiBlock = buildAiInstructionBlock({
    exportTitle: 'Fabrikanalyse-Export',
    aboutText:
      'Dieses Dokument ist der Export einer Fabrikanalyse (FA) — einer werksweiten, strukturierten ' +
      'Bewertung über mehrere Kategorien und Unterkategorien. Es enthält die Bewertungen (Skala 1–4), ' +
      'Kommentare und eine Kategorien-Übersicht, so wie sie zum Exportzeitpunkt im System standen.',
    usageHints: [
      'Erstelle eine Management Summary pro Hauptkategorie und hebe kritische Bereiche (Bewertung 1–2) hervor.',
      'Formuliere konkrete, priorisierte Handlungsempfehlungen aus den Kommentaren zu niedrig bewerteten Fragen.',
      'Zitiere bei Kernaussagen die betroffene Frage (Nummer + Kategorie), damit die Aussage nachvollziehbar bleibt.',
    ],
    isDemo: assessment.is_demo === true,
  })

  const children: (Paragraph | Table)[] = [
    docTitle('Fabrikanalyse-Export'),
    bodyText(`${assessment.title} — ${assessment.supplier_name ?? '—'}${dateStr ? ` — ${dateStr}` : ''}`, { bold: true }),
    spacer(),
    ...renderAiInstructionBlock(aiBlock),

    heading1('Steckbrief'),
    kvTable([
      ['Titel', assessment.title],
      ['Zulieferer', assessment.supplier_name ?? '—'],
      ['Standort', assessment.location ?? '—'],
      ['Assessment-Nr.', assessment.assessment_number ?? '—'],
      ['Datum', dateStr ?? '—'],
      ['Status', assessment.status],
      ['Erzeugt am', generatedAtLabel],
    ]),

    heading1('Gesamtübersicht'),
    kvTable([
      ['Gesamtbewertung', overall.score !== null ? `${formatNumberDe(overall.score)} / 4,00` : '— (nicht bewertet)'],
      ['Fortschritt', `${overall.answered}/${overall.totalRelevant} Fragen (${formatPercentDe(overall.progress / 100, 0)})`],
      ['Markiert', String(overall.flagged)],
      ['Kommentiert', String(overall.commented)],
    ]),

    heading1('Kategorien-Übersicht'),
    dataTable(
      ['Hauptkategorie', 'Ø Bewertung', 'Beantwortet', 'Fortschritt'],
      mainStats.map((m) => [
        m.label,
        m.avg !== null ? formatNumberDe(m.avg) : '—',
        `${m.answered}/${m.total}`,
        formatPercentDe(m.progress / 100, 0),
      ]),
    ),
    spacer(),
  ]

  // ── Detail: main category -> sub category -> question (mirrors
  // exportForAISummary's grouping/sort exactly). ──────────────────────────
  const mainMap = new Map<
    string,
    { label: string; sortOrder: number; subs: Map<string, { label: string; sortOrder: number; qs: QuestionWithCategories[] }> }
  >()
  for (const q of [...questions].sort((a, b) => a.index_number - b.index_number)) {
    const mainLabel = deText(q.main_category.label, q.main_category.label_de)
    const subLabel = deText(q.sub_category.label, q.sub_category.label_de)
    if (!mainMap.has(q.main_category_id)) {
      mainMap.set(q.main_category_id, { label: mainLabel, sortOrder: q.main_category.sort_order, subs: new Map() })
    }
    const m = mainMap.get(q.main_category_id)!
    if (!m.subs.has(q.sub_category_id)) {
      m.subs.set(q.sub_category_id, { label: subLabel, sortOrder: q.sub_category.sort_order, qs: [] })
    }
    m.subs.get(q.sub_category_id)!.qs.push(q)
  }

  children.push(heading1('Fragen im Detail'))
  for (const [, main] of [...mainMap.entries()].sort((a, b) => a[1].sortOrder - b[1].sortOrder)) {
    children.push(heading2(main.label))
    for (const [, sub] of [...main.subs.entries()].sort((a, b) => a[1].sortOrder - b[1].sortOrder)) {
      children.push(heading3(sub.label))
      const relevantQs = sub.qs.filter((q) => responses[q.id]?.is_relevant !== false)
      if (relevantQs.length === 0) {
        children.push(bodyText('Keine relevanten Fragen in dieser Unterkategorie.', { italics: true }))
        continue
      }
      for (const q of relevantQs) {
        const r = responses[q.id]
        const rating = r?.selected_rating ?? null
        const comment = r?.comment?.trim() ?? ''
        const qText = deText(q.question_text, q.question_text_de)
        children.push(bodyText(`Frage ${q.index_number}: ${qText}`, { bold: true }))
        if (rating !== null) {
          const answerCol = [q.answer_text_1, q.answer_text_2, q.answer_text_3, q.answer_text_4][rating - 1]
          const answerColDe = [q.answer_text_1_de, q.answer_text_2_de, q.answer_text_3_de, q.answer_text_4_de][rating - 1]
          const aText = deText(answerCol, answerColDe) || RATING_LABEL[rating]
          children.push(bodyText(`Bewertung: ${rating} — ${RATING_LABEL[rating]} (${aText})`))
        } else {
          children.push(bodyText('Bewertung: — (nicht bewertet)', { color: '69707A' }))
        }
        if (comment) children.push(bodyText(`Kommentar: ${comment}`))
        children.push(spacer())
      }
    }
  }

  const doc = buildDocument(`Fabrikanalyse-Export — ${assessment.title}`, children)
  return packDocumentToBuffer(doc)
}
