/**
 * POST /api/offers/questionnaire/save — persist the initial-call questionnaire
 * on the lead/partner (offer_conditions.questionnaire) and, when `attach` is
 * true, render the FILLED PDF, attach it to the record (Strapi, same flow as the
 * quote/contract/SEPA PDFs) and log a C_ContactActivity with the answers.
 *
 * Body: { source: 'lead'|'partner', recordId, recordUu?, language: 'de'|'en',
 *         meta: { company, contactName, interviewer, date, channel },
 *         answers: {...}, attach: boolean }
 * Returns { status, message, filename?, attachedUrl?, warning? }.
 */
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'
import forceLogoutHelper from '../../../utils/forceLogoutHelper'
import { buildQuestionnairePdf } from '../../../utils/offers/questionnairePdf'
import { attachToStrapi } from '../../../utils/inbox/strapiAttach'
import { logContactActivity, strapiPublicFileUrl } from '../../../utils/offers/contactActivity'
import { saveOfferConditions, readOfferConditions } from '../../../utils/offers/offerConditions'
import { QUESTIONNAIRE, QUESTIONNAIRE_VERSION, qLabel, formatQuestionnaireAnswer, mergeQuestionnaireAnswers, questionnaireFilename, questionnaireProgress } from '../../../../app/utils/leadQuestionnaire'

const handleFunc = async (event: any, authToken: string | null = null) => {
  const token = authToken ?? await getTokenHelper(event)
  if (!token) return { status: 401, message: 'Not authenticated' }
  const body: any = await readBody(event)
  const language = body?.language === 'en' ? 'en' : 'de'
  const en = language === 'en'
  const source = body?.source === 'lead' ? 'lead' : 'partner'
  const recordId = Number(body?.recordId) || 0
  if (!(recordId > 0)) return { status: 400, message: 'recordId required' }
  const meta = {
    company: String(body?.meta?.company || '').trim(),
    contactName: String(body?.meta?.contactName || '').trim(),
    interviewer: String(body?.meta?.interviewer || '').trim(),
    date: String(body?.meta?.date || '').trim() || new Date().toISOString().slice(0, 10),
    channel: ['phone', 'meeting', 'video'].includes(body?.meta?.channel) ? body.meta.channel : ''
  }
  const answers = mergeQuestionnaireAnswers(body?.answers)
  const attach = body?.attach === true
  const now = new Date().toISOString()
  const warnings: string[] = []

  // 1) answers on the record (draft AND final) — read-merge-write keeps quote/contract/sepa intact
  const section: any = { version: QUESTIONNAIRE_VERSION, language, meta, answers, updatedAt: now, updatedBy: Number(getCookie(event, 'logship_user_id')) || null }
  let prior: any = null
  try {
    prior = (await readOfferConditions(event, token, source, recordId))?.questionnaire || null
  } catch { /* fail-soft */ }
  if (prior?.completedAt) section.completedAt = prior.completedAt
  if (prior?.attachedUrl) section.attachedUrl = prior.attachedUrl
  if (prior?.filename) section.filename = prior.filename

  let filename = ''
  let attachedUrl = ''
  if (attach) {
    // 2) filled PDF → Strapi attachment on the record
    const buffer = await buildQuestionnairePdf({ language, mode: 'filled', meta, answers })
    filename = questionnaireFilename(language, meta.company, 'filled')
    try {
      const up = await attachToStrapi(event, token, { tableName: source === 'lead' ? 'Lead_User' : 'C_BPartner', recordId, recordUu: body?.recordUu || undefined, buffer, filename, mimeType: 'application/pdf' })
      attachedUrl = strapiPublicFileUrl(up.fileUrl)
    } catch (err: any) {
      console.error('[Questionnaire] attach failed:', err?.message || err)
      warnings.push(en ? 'PDF could not be attached' : 'PDF konnte nicht angehängt werden')
    }
    section.completedAt = now
    section.filename = filename
    if (attachedUrl) section.attachedUrl = attachedUrl

    // 3) activity with a readable summary of every answered question
    try {
      const lines: string[] = []
      for (const cat of QUESTIONNAIRE) {
        const rows = cat.questions.map((q) => ({ q, a: formatQuestionnaireAnswer(q, answers, language) })).filter((r) => r.a)
        if (!rows.length) continue
        lines.push(`## ${qLabel(cat, language)}`)
        for (const r of rows) lines.push(`${qLabel(r.q, language)}: ${r.a}`)
      }
      const p = questionnaireProgress(answers)
      const channel = meta.channel ? ({ de: { phone: 'Telefon', meeting: 'persönlich', video: 'Video-Call' }, en: { phone: 'phone', meeting: 'in person', video: 'video call' } } as any)[language][meta.channel] : ''
      await logContactActivity(event, token, {
        source, recordId,
        type: meta.channel === 'meeting' ? 'ME' : 'PC',
        description: en ? `Initial-call questionnaire completed (${p.answered}/${p.total})` : `Erstgespräch-Fragebogen ausgefüllt (${p.answered}/${p.total})`,
        comments: [
          en ? `Questionnaire${channel ? ` (${channel})` : ''} recorded by ${meta.interviewer || '—'} on ${meta.date}.` : `Fragebogen${channel ? ` (${channel})` : ''} aufgenommen von ${meta.interviewer || '—'} am ${meta.date}.`,
          '',
          ...lines
        ].join('\n'),
        documents: attachedUrl ? [{ title: en ? 'Questionnaire (PDF)' : 'Fragebogen Erstgespräch (PDF)', url: attachedUrl }] : []
      })
    } catch (err: any) {
      console.error('[Questionnaire] activity failed:', err?.message || err)
    }
  }

  try {
    await saveOfferConditions(event, token, source, recordId, 'questionnaire', section)
  } catch (err: any) {
    console.error('[Questionnaire] conditions save failed:', err?.message || err)
    warnings.push(en ? 'Answers could not be stored on the record (offer_conditions)' : 'Antworten konnten nicht am Datensatz gespeichert werden (offer_conditions)')
  }

  return {
    status: 200,
    message: attach ? (en ? 'Questionnaire saved and attached' : 'Fragebogen gespeichert und angehängt') : (en ? 'Draft saved' : 'Entwurf gespeichert'),
    filename: filename || undefined,
    attachedUrl: attachedUrl || undefined,
    warning: warnings.join(' · ') || undefined
  }
}

export default defineEventHandler(async (event) => {
  let data: any = {}
  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      const authToken = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }
  return data
})
