/**
 * POST /api/offers/forecast/send
 * Body: forecast payload incl. email { to, cc?, subject, message }.
 * Builds the custom-forecast PDF ONCE, e-mails it (from info@logyou.de, like the
 * quote), attaches the same PDF to the triggering record (partner → C_BPartner,
 * lead → Lead_User), stores the editor state as offer_conditions.forecast and
 * logs an activity. Every step after the send is fail-soft.
 */
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'
import forceLogoutHelper from '../../../utils/forceLogoutHelper'
import { BRAND, LEGAL_FOOTER_LINES } from '../../../utils/offers/quotePdf'
import { generateForecastPdf, validateForecastPayload, conditionsFromForecastPayload } from '../../../utils/offers/forecastPdf'
import { attachToStrapi } from '../../../utils/inbox/strapiAttach'
import { saveOfferConditions } from '../../../utils/offers/offerConditions'
import { logContactActivity, strapiPublicFileUrl } from '../../../utils/offers/contactActivity'
import { mailTransport } from '../../../utils/offers/contractSigning'

const EMAIL_TEXTS: any = {
  de: {
    headline: 'Ihre individuelle Kostenprognose',
    attachmentBox: 'Die Prognose liegt dieser E-Mail als PDF-Anhang bei. Unverbindliche Beispielrechnung — abgerechnet wird nach tatsächlichem Verbrauch.',
    auto: 'Diese E-Mail wurde automatisch versendet.'
  },
  en: {
    headline: 'Your individual cost forecast',
    attachmentBox: 'The forecast is attached to this email as a PDF. Non-binding example calculation — billing is based on actual consumption.',
    auto: 'This email was sent automatically.'
  }
}

const generateForecastEmailHtml = (message: string, language: string) => {
  const T = EMAIL_TEXTS[language === 'en' ? 'en' : 'de']
  const messageHtml = String(message || '')
    .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    .replace(/\n/g, '<br>')
  return `<!DOCTYPE html>
<html>
<body style="margin:0;padding:0;background-color:#f0f2f5;font-family:Arial,Helvetica,sans-serif;">
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f0f2f5;padding:24px 0;">
    <tr><td align="center">
      <table role="presentation" width="600" cellpadding="0" cellspacing="0" style="max-width:600px;width:100%;background-color:#ffffff;border-radius:8px;overflow:hidden;box-shadow:0 1px 4px rgba(0,0,0,0.08);">
        <tr>
          <td style="background-color:${BRAND.navy};border-bottom:4px solid ${BRAND.orange};padding:26px 32px;">
            <div style="color:#ffffff;font-size:20px;font-weight:bold;">${T.headline}</div>
            <div style="color:${BRAND.headerSub};font-size:12px;margin-top:6px;">LogYou GmbH &middot; logyou.de</div>
          </td>
        </tr>
        <tr>
          <td style="padding:30px 32px;color:#33414E;font-size:14px;line-height:1.6;">
            ${messageHtml}
          </td>
        </tr>
        <tr>
          <td style="padding:0 32px 28px 32px;">
            <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#F6F8FA;border-left:4px solid ${BRAND.orange};border-radius:4px;">
              <tr>
                <td style="padding:14px 18px;color:#33414E;font-size:13px;">
                  &#128206;&nbsp; ${T.attachmentBox}
                </td>
              </tr>
            </table>
          </td>
        </tr>
        <tr>
          <td style="background-color:#f7f8fa;border-top:1px solid #e3e7ec;padding:16px 32px;color:#8a97a5;font-size:10px;line-height:1.6;text-align:center;">
            ${LEGAL_FOOTER_LINES.join('<br>')}
            <br><br>${T.auto}
          </td>
        </tr>
      </table>
    </td></tr>
  </table>
</body>
</html>`
}

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 = await readBody(event)
  const invalid = validateForecastPayload(body)
  if (invalid) return { status: 400, message: invalid }
  const toEmail = String(body?.email?.to || '').trim()
  if (!/.+@.+\..+/.test(toEmail)) {
    return { status: 400, message: 'A valid recipient email is required' }
  }
  const language = body?.meta?.language === 'en' ? 'en' : 'de'
  const en = language === 'en'
  const source = body.source === 'lead' ? 'lead' : 'partner'
  const recordId = Number(body.recordId)

  // Build the PDF once — reused for the email attachment AND the record attachment.
  const { buffer, filename } = await generateForecastPdf(body)

  const ccList = String(body?.email?.cc || '')
    .split(/[,;]/)
    .map((s: string) => s.trim())
    .filter((s: string) => s.length > 0)

  try {
    await mailTransport().sendMail({
      from: 'info@logyou.de',
      to: toEmail,
      cc: ccList.length > 0 ? ccList : undefined,
      subject: body?.email?.subject || filename.replace(/\.pdf$/, ''),
      text: body?.email?.message || '',
      html: generateForecastEmailHtml(body?.email?.message || '', language),
      attachments: [{ filename, content: buffer, contentType: 'application/pdf' }]
    })
  } catch (err: any) {
    console.error('Forecast email send error:', err)
    return { status: 500, message: `Failed to send email: ${err.message}` }
  }

  // Attach to the record — own try/catch so a failure never reverts the send.
  let attached = false
  let attachWarning = ''
  let attachedUrl = ''
  try {
    if (recordId > 0) {
      const up = await attachToStrapi(event, token, {
        tableName: source === 'lead' ? 'Lead_User' : 'C_BPartner',
        recordId,
        recordUu: body.recordUu || undefined,
        buffer,
        filename,
        mimeType: 'application/pdf'
      })
      attached = true
      attachedUrl = strapiPublicFileUrl(up.fileUrl)
    } else {
      attachWarning = 'No record id — attachment skipped'
    }
  } catch (err: any) {
    console.error('Forecast attachment error:', err)
    attachWarning = 'Email sent, but attaching the PDF to the record failed'
  }

  // Remember the editor state for the next open (fail-soft).
  let conditionsSaved = false
  try {
    if (recordId > 0) {
      await saveOfferConditions(event, token, source, recordId, 'forecast', {
        ...conditionsFromForecastPayload(body),
        lastSend: { at: new Date().toISOString(), to: toEmail, filename }
      })
      conditionsSaved = true
    }
  } catch (err: any) {
    console.error('Forecast conditions save skipped:', err?.message || err)
  }

  // Activity on the record with the PDF as a document button (fail-soft).
  let activityLogged = false
  try {
    if (recordId > 0) {
      const ccText = ccList.length ? ` (CC: ${ccList.join(', ')})` : ''
      const scenarioText = (Array.isArray(body.scenarios) ? body.scenarios : [])
        .map((s: any, i: number) => `${s?.heading || s?.orders}: ${new Intl.NumberFormat(en ? 'en-IE' : 'de-DE', { style: 'currency', currency: 'EUR' }).format(Number(body?.totals?.total?.[i]) || 0)}`)
        .join(' · ')
      const created = await logContactActivity(event, token, {
        source,
        recordId,
        type: 'EM',
        contactEmail: toEmail,
        description: en ? `Cost forecast sent: ${filename}` : `Kostenprognose gesendet: ${filename}`,
        comments: [
          en ? `Individual cost forecast ${filename} e-mailed to ${toEmail}${ccText}.` : `Individuelle Kostenprognose ${filename} per E-Mail an ${toEmail}${ccText} gesendet.`,
          scenarioText ? (en ? `Monthly total — ${scenarioText}` : `Gesamt pro Monat — ${scenarioText}`) : ''
        ].filter(Boolean).join('\n'),
        documents: attachedUrl ? [{ title: en ? 'Forecast (PDF)' : 'Prognose (PDF)', url: attachedUrl }] : []
      })
      activityLogged = !!created
    }
  } catch (err: any) {
    console.error('Forecast activity skipped:', err?.message || err)
  }

  return {
    status: 200,
    message: 'Forecast sent successfully',
    filename,
    attached,
    conditionsSaved,
    activityLogged,
    warning: attachWarning || undefined
  }
}

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