/**
 * Assemble the document package that goes out with a contract: the contract
 * itself plus the selected annexes. One place for titles, order and loaders so
 * the send route, the signing portal and the e-mails all agree.
 *
 * Attachment flags (body.attachments): offer (Anlage 1 — last sent quote),
 * agb (2a — stored AGB), adsp (2b — static PDF), logistikagb (2c — static PDF),
 * avv (3 — stored AVV). Absent flag = included, `false` = left out.
 * flyer (marketing overview) is the exception: OPT-IN, only attached when `true`.
 */
import { resolveLastOfferPdf } from './offerAttachments'
import { generateLegalDocPdf } from './agbPdf'
import { loadStaticAnnex } from './staticAnnexes'
import { getLegalDocumentWithFallback } from '../legalDocsDb'
import { generateFlyerPdf } from './flyerPdf'

export interface PackageDocument {
  key: 'contract' | 'offer' | 'agb' | 'adsp' | 'logistikagb' | 'avv' | 'flyer'
  title: string
  filename: string
  buffer: Buffer
  version?: number
  signable?: boolean
}

export const PACKAGE_KEYS = ['offer', 'agb', 'adsp', 'logistikagb', 'avv', 'flyer'] as const

export const packageTitle = (key: string, language: string): string => {
  const en = language === 'en'
  switch (key) {
    case 'contract': return en ? 'Fulfillment agreement' : 'Fulfillment-Rahmenvertrag'
    case 'offer': return en ? 'Annex 1 – Offer' : 'Anlage 1 – Angebot'
    case 'agb': return en ? 'Annex 2a – Terms and Conditions (AGB)' : 'Anlage 2a – AGB'
    case 'adsp': return en ? 'Annex 2b – ADSp 2017' : 'Anlage 2b – ADSp 2017'
    case 'logistikagb': return en ? 'Annex 2c – Logistik-AGB 2019' : 'Anlage 2c – Logistik-AGB 2019'
    case 'avv': return en ? 'Annex 3 – Data Processing Agreement (Art. 28 GDPR)' : 'Anlage 3 – Auftragsverarbeitungsvertrag (AVV)'
    case 'flyer': return en ? 'LogYou & LogShip – Overview' : 'LogYou & LogShip – Überblick'
    default: return key
  }
}

export const wantsAttachment = (attachments: any, key: string): boolean => !(attachments && attachments[key] === false)

/** Availability info for the modal (no heavy rendering). */
export const describePackageAvailability = (language: string) => {
  const agb = getLegalDocumentWithFallback('agb', language)
  const avv = getLegalDocumentWithFallback('avv', language)
  return {
    agb: { available: !!String(agb.contentHtml || '').trim(), version: agb.version, language: agb.language, updatedAt: agb.updatedAt },
    avv: { available: !!String(avv.contentHtml || '').trim(), version: avv.version, language: avv.language, updatedAt: avv.updatedAt },
    adsp: { available: true },
    logistikagb: { available: true }
  }
}

/**
 * Load every selected annex. Never throws for a single missing annex — the
 * returned `warnings` list names what could not be included so the send route
 * can surface it to the user while still sending the contract.
 */
export const assembleContractPackage = async (
  event: any,
  token: string,
  opts: { source: string; recordId: number; language: string; attachments: any; contract: { buffer: Buffer; filename: string } }
): Promise<{ documents: PackageDocument[]; warnings: string[] }> => {
  const { language } = opts
  const en = language === 'en'
  const documents: PackageDocument[] = [
    { key: 'contract', title: packageTitle('contract', language), filename: opts.contract.filename, buffer: opts.contract.buffer, signable: true }
  ]
  const warnings: string[] = []

  if (wantsAttachment(opts.attachments, 'offer')) {
    try {
      const offer = opts.recordId > 0 ? await resolveLastOfferPdf(event, token, opts.source, opts.recordId) : null
      if (offer) documents.push({ key: 'offer', title: packageTitle('offer', language), filename: offer.filename, buffer: offer.buffer })
      else warnings.push(en ? 'No previous offer found — Annex 1 not attached' : 'Kein früheres Angebot gefunden — Anlage 1 nicht angehängt')
    } catch (err: any) {
      warnings.push(en ? 'Offer (Annex 1) could not be attached' : 'Angebot (Anlage 1) konnte nicht angehängt werden')
    }
  }
  if (wantsAttachment(opts.attachments, 'agb')) {
    try {
      const agb = await generateLegalDocPdf('agb', language)
      documents.push({ key: 'agb', title: packageTitle('agb', language), filename: agb.filename, buffer: agb.buffer, version: agb.version })
    } catch (err: any) {
      warnings.push(en ? 'AGB (Annex 2a) could not be attached' : 'AGB (Anlage 2a) konnten nicht angehängt werden')
    }
  }
  for (const key of ['adsp', 'logistikagb'] as const) {
    if (!wantsAttachment(opts.attachments, key)) continue
    const st = await loadStaticAnnex(key)
    if (st) documents.push({ key, title: packageTitle(key, language), filename: st.filename, buffer: st.buffer })
    else warnings.push(`${packageTitle(key, language)}: ${en ? 'file not available' : 'Datei nicht verfügbar'}`)
  }
  if (wantsAttachment(opts.attachments, 'avv')) {
    try {
      const avv = await generateLegalDocPdf('avv', language)
      documents.push({ key: 'avv', title: packageTitle('avv', language), filename: avv.filename, buffer: avv.buffer, version: avv.version })
    } catch (err: any) {
      warnings.push(en ? 'AVV (Annex 3) could not be attached' : 'AVV (Anlage 3) konnte nicht angehängt werden')
    }
  }
  // Marketing flyer — OPT-IN (default off), so an explicit true is required.
  if (opts.attachments && opts.attachments.flyer === true) {
    try {
      const fl = await generateFlyerPdf(language)
      documents.push({ key: 'flyer', title: packageTitle('flyer', language), filename: fl.filename, buffer: fl.buffer })
    } catch (err: any) {
      warnings.push(en ? 'Flyer could not be attached' : 'Flyer konnte nicht angehängt werden')
    }
  }
  return { documents, warnings }
}
