/**
 * Resolve the LAST SENT OFFER (quote PDF) of a lead/partner so it can ride
 * along as "Anlage 1" when the contract is sent / signed.
 *
 * 1. Preferred: the exact PDF that was e-mailed — every quote send attaches it
 *    to the record via Strapi (Lead_User / C_BPartner) as
 *    `Angebot_LogYou_<company>_<date>.pdf`; we pick the newest such file.
 * 2. Fallback: re-render from the record's saved `offer_conditions.quote`
 *    (same generator the send used; date = the saved timestamp).
 *
 * When the saved quote conditions are NEWER than the newest sent PDF (the rep
 * revised prices after the last send), the re-render wins — otherwise the contract
 * would cite the newer offer date while attaching the stale PDF (happened 2026-10:
 * contract "Angebot vom 21.10." with the 28.09. PDF attached). The contract modal
 * mirrors the chosen date into "Angebot vom (Anlage 1)".
 */
import strapiHelper from '../strapiHelper'
import { resolveTableId, fetchStrapiFileBytes } from '../inbox/strapiAttach'
import { readOfferConditions } from './offerConditions'
import { generateQuotePdf } from './quotePdf'

export interface LastOfferInfo {
  available: boolean
  filename?: string
  date?: string
  via?: 'attachment' | 'conditions'
  fileUrl?: string
}

const QUOTE_FILE_RE = /^(Angebot|Quote|Offer)_LogYou_.*\.pdf$/i

const listRecordFiles = async (event: any, token: string, source: string, recordId: number): Promise<any[]> => {
  const tableName = source === 'lead' ? 'Lead_User' : 'C_BPartner'
  const tableId = await resolveTableId(event, token, tableName)
  const existing: any = await strapiHelper(event, `ad-attachments?filters[AD_Table_ID][$eq]=${tableId}&filters[Record_ID][$eq]=${recordId}`, 'GET', null)
  const attId = existing?.data?.[0]?.documentId || existing?.data?.[0]?.id
  if (!attId) return []
  const res: any = await strapiHelper(event, `ad-attachments/${attId}?populate=attachment`, 'GET', null)
  const files = res?.data?.attachment || []
  return Array.isArray(files) ? files : []
}

const newestQuoteFile = (files: any[]) => files
  .filter((f: any) => QUOTE_FILE_RE.test(String(f?.name || '')))
  .sort((a: any, b: any) => new Date(b?.createdAt || 0).getTime() - new Date(a?.createdAt || 0).getTime())[0] || null

const savedQuoteDate = (cond: any): string => {
  const q = cond?.quote
  return q && typeof q === 'object' && q.customer ? String(q.savedAt || '').slice(0, 10) : ''
}

/** true when the saved quote conditions are newer than the newest sent PDF. */
const conditionsNewerThanFile = (condDate: string, f: any): boolean =>
  !!condDate && condDate > String(f?.createdAt || '').slice(0, 10)

/** Cheap check for the modal: is there a last offer to attach, and which? */
export const describeLastOffer = async (event: any, token: string, source: string, recordId: number): Promise<LastOfferInfo> => {
  let f: any = null
  try {
    f = newestQuoteFile(await listRecordFiles(event, token, source, recordId))
  } catch (err: any) {
    console.warn('[Offers] last-offer attachment lookup failed:', err?.message || err)
  }
  let condDate = ''
  try {
    condDate = savedQuoteDate(await readOfferConditions(event, token, source, recordId))
  } catch {}
  if (f && !conditionsNewerThanFile(condDate, f)) {
    return { available: true, filename: f.name, date: String(f.createdAt || '').slice(0, 10), via: 'attachment', fileUrl: f.url }
  }
  if (condDate) return { available: true, date: condDate, via: 'conditions' }
  if (f) return { available: true, filename: f.name, date: String(f.createdAt || '').slice(0, 10), via: 'attachment', fileUrl: f.url }
  return { available: false }
}

/** The bytes of the last offer (exact sent file first, regenerated second). */
export const resolveLastOfferPdf = async (event: any, token: string, source: string, recordId: number): Promise<{ buffer: Buffer; filename: string; via: 'attachment' | 'conditions' } | null> => {
  let cond: any = null
  try { cond = await readOfferConditions(event, token, source, recordId) } catch {}
  const condDate = savedQuoteDate(cond)
  let f: any = null
  try {
    f = newestQuoteFile(await listRecordFiles(event, token, source, recordId))
    if (f?.url && !conditionsNewerThanFile(condDate, f)) {
      const buffer = await fetchStrapiFileBytes(event, f.url)
      if (buffer?.length) return { buffer, filename: f.name, via: 'attachment' }
    }
  } catch (err: any) {
    console.warn('[Offers] last-offer attachment fetch failed:', err?.message || err)
  }
  try {
    const q = cond?.quote
    if (q && typeof q === 'object' && q.customer) {
      const payload = {
        docType: 'quote',
        source,
        recordId,
        customer: q.customer,
        assumptions: q.assumptions || {},
        pricing: q.pricing || {},
        inbound: q.inbound || { mode: 'included' },
        services: q.services || {},
        customPositions: q.customPositions || [],
        sections: q.sections || {},
        customTexts: q.customTexts || [],
        volumeMatrix: q.volumeMatrix || {},
        visuals: { includeScreenshot: false, includeLogo: false },
        forecast: { includeInPdf: false, lines: [] },
        // Keep the regenerated Anlage 1 identical in substance to what the customer got:
        // the cut-off (meta card + Hinweise) and the validity the quote was saved with.
        cutoff: q.cutoff && typeof q.cutoff === 'object' ? { show: q.cutoff.show === true, time: String(q.cutoff.time || '14:00') } : { show: false, time: '14:00' },
        meta: {
          validDays: Number(q.validDays) || 7,
          ...(q.validUntil ? { validUntil: String(q.validUntil) } : {}),
          language: q.language === 'en' ? 'en' : 'de',
          date: String(q.savedAt || '').slice(0, 10) || new Date().toISOString().slice(0, 10)
        }
      }
      const { buffer, filename } = await generateQuotePdf(payload)
      return { buffer, filename, via: 'conditions' }
    }
  } catch (err: any) {
    console.warn('[Offers] last-offer regeneration failed:', err?.message || err)
  }
  // Regeneration failed although the conditions were newer — the sent PDF is still better than nothing.
  try {
    if (f?.url) {
      const buffer = await fetchStrapiFileBytes(event, f.url)
      if (buffer?.length) return { buffer, filename: f.name, via: 'attachment' }
    }
  } catch {}
  return null
}
