/**
 * POST /api/offers/quote/send
 * Body: OfferQuotePayload incl. email { to, cc?, subject, message }.
 * Builds the branded Angebot PDF ONCE, emails it to the recipient
 * (from info@logyou.de — quotes are sales conversations, replies land in the
 * real inbox) and attaches the same PDF to the triggering record:
 * partner → C_BPartner, lead → Lead_User (the lead page's AttachmentModal target).
 */
import nodemailer from 'nodemailer'
import refreshTokenHelper from '../../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../../utils/errorHandlingHelper'
import forceLogoutHelper from '../../../utils/forceLogoutHelper'
import { generateQuotePdf, BRAND, LEGAL_FOOTER_LINES } from '../../../utils/offers/quotePdf'
import { attachToStrapi } from '../../../utils/inbox/strapiAttach'
import { saveOfferConditions, conditionsFromQuotePayload } from '../../../utils/offers/offerConditions'
import { generateFlyerPdf } from '../../../utils/offers/flyerPdf'
import { createSigningRequest, isSigningAvailable, writeSigningFile, sha256Hex } from '../../../utils/offers/contractSigningDb'
import { confirmLink, confirmCtaHtml, confirmCtaText, resolveConfirmationExpiry } from '../../../utils/offers/quoteConfirmation'
import { logContactActivity, strapiPublicFileUrl } from '../../../utils/offers/contactActivity'
import { formatDateHuman } from '../../../utils/offers/contractSigning'

const EMAIL_TEXTS: any = {
  de: {
    headline: 'Ihr Fulfillment-Angebot',
    attachmentBox: 'Das Angebot liegt dieser E-Mail als PDF-Anhang bei.',
    linkOnlyBox: 'Das Angebot steht über den Button oben zum Lesen und Herunterladen als PDF bereit — der Klick ist unverbindlich.',
    validity: (days: number) => `Gültigkeit: ${days} Tage.`,
    auto: 'Diese E-Mail wurde automatisch versendet.'
  },
  en: {
    headline: 'Your fulfillment quote',
    attachmentBox: 'The quote is attached to this email as a PDF.',
    linkOnlyBox: 'The quote is available for reading and download as PDF via the button above — clicking it is non-binding.',
    validity: (days: number) => `Validity: ${days} days.`,
    auto: 'This email was sent automatically.'
  }
}

const generateQuoteEmailHtml = (message: string, language: string, validDays: number, confirmation: { link: string; expiresAt: string } | null = null, attachPdf = true) => {
  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>
        ${confirmation ? `<tr><td style="padding:0 32px 18px 32px;">${confirmCtaHtml(language, confirmation.link, confirmation.expiresAt)}</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;">
                  ${attachPdf ? '&#128206;' : '&#128196;'}&nbsp; ${attachPdf ? T.attachmentBox : T.linkOnlyBox} ${T.validity(validDays)}
                </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)
  if (!body?.customer?.company || !body?.customer?.contactName) {
    return { status: 400, message: 'Company and contact name are required' }
  }
  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 validDays = Number(body?.meta?.validDays) || 7

  const source = body.source === 'lead' ? 'lead' : 'partner'
  const recordIdNum = Number(body.recordId)

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

  // Online confirmation link (opt-out checkbox in the quote modal; default on).
  // Same store as contract signing (kind 'quote'); the link lives as long as the
  // quote is valid and a new quote send supersedes the record's older open link.
  let confirmation: { token: string; link: string; expiresAt: string } | null = null
  let confirmWarning = ''
  if (body?.confirmation?.enabled !== false) {
    if (!isSigningAvailable()) {
      confirmWarning = language === 'en' ? 'Online confirmation unavailable (store) — sent without link' : 'Online-Bestätigung nicht verfügbar (Speicher) — ohne Link versendet'
    } else {
      try {
        const expiresAt = resolveConfirmationExpiry(validDays)
        const { email: _e, ...payloadWithoutEmail } = body
        const req = createSigningRequest({
          kind: 'quote',
          source,
          recordId: recordIdNum > 0 ? recordIdNum : 0,
          recordUu: body.recordUu || undefined,
          company: String(body.customer.company),
          contactName: String(body.customer.contactName),
          email: toEmail,
          language,
          payload: payloadWithoutEmail,
          documents: [{ key: 'offer', title: language === 'en' ? 'Quote' : 'Angebot', filename, sha256: sha256Hex(buffer), size: buffer.length }],
          createdBy: Number(getCookie(event, 'logship_user_id')) || null,
          expiresAt
        })
        writeSigningFile(req.token, filename, buffer)
        confirmation = { token: req.token, link: confirmLink(req.token), expiresAt }
      } catch (err: any) {
        console.error('Quote confirmation link creation failed:', err)
        confirmWarning = language === 'en' ? 'Confirmation link could not be created — sent without it' : 'Bestätigungs-Link konnte nicht erstellt werden — ohne Link versendet'
      }
    }
  }

  // Optional marketing flyer (opt-in checkbox in the quote modal) — fail-soft.
  let flyerAttachment: any[] = []
  let flyerWarning = ''
  if (body?.attachments?.flyer === true) {
    try {
      const fl = await generateFlyerPdf(language)
      flyerAttachment = [{ filename: fl.filename, content: fl.buffer, contentType: 'application/pdf' }]
    } catch (err: any) {
      console.error('Flyer attachment failed:', err?.message || err)
      flyerWarning = 'Flyer could not be attached'
    }
  }

  const transporter = nodemailer.createTransport({
    host: 'localhost',
    port: 25,
    secure: false,
    tls: {
      rejectUnauthorized: false
    }
  })

  // Quote PDF as e-mail attachment: opt-in while the online link is present
  // (default off — the customer reads/downloads it in the portal); WITHOUT a
  // link (disabled, store unavailable or creation failed) it is always attached.
  const attachPdf = !confirmation || body?.confirmation?.attachPdf === true

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

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

  // Attach the PDF to the triggering record for later reference — its own
  // try/catch so an attachment failure never reverts the successful send.
  let attached = false
  let attachWarning = ''
  let attachedUrl = ''
  try {
    const tableName = body.source === 'lead' ? 'Lead_User' : 'C_BPartner'
    const recordId = Number(body.recordId)
    if (recordId > 0) {
      const up = await attachToStrapi(event, token, {
        tableName,
        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('Quote attachment error:', err)
    attachWarning = 'Email sent, but attaching the PDF to the record failed'
  }

  // Persist the just-sent conditions on the record — the next quote/contract
  // starts from them. Fail-soft: the offer_conditions column may not exist yet.
  let conditionsSaved = false
  try {
    const recordId = Number(body.recordId)
    if (recordId > 0) {
      await saveOfferConditions(event, token, source, recordId, 'quote', {
        ...conditionsFromQuotePayload(body),
        lastSend: { at: new Date().toISOString(), to: toEmail, filename, confirmationToken: confirmation?.token || null, confirmationExpiresAt: confirmation?.expiresAt || null }
      })
      conditionsSaved = true
    }
  } catch (err: any) {
    console.error('Offer conditions save skipped:', err?.message || err)
  }

  // Activity on the record: "Angebot gesendet" with the attached PDF as a document
  // button (fail-soft — never affects the send result).
  let activityLogged = false
  try {
    if (recordIdNum > 0) {
      const en = language === 'en'
      const ccText = ccList.length ? (en ? ` (CC: ${ccList.join(', ')})` : ` (CC: ${ccList.join(', ')})`) : ''
      const lines = [
        en ? `Quote ${filename} e-mailed to ${toEmail}${ccText}.` : `Angebot ${filename} per E-Mail an ${toEmail}${ccText} gesendet.`,
        en ? `Validity: ${validDays} days.` : `Gültigkeit: ${validDays} Tage.`,
        confirmation ? (en ? `Online confirmation link (valid until ${formatDateHuman(confirmation.expiresAt, 'en')}${attachPdf ? ', PDF also attached' : ', PDF in portal only'}): ${confirmation.link}` : `Online-Bestätigungs-Link (gültig bis ${formatDateHuman(confirmation.expiresAt, 'de')}${attachPdf ? ', PDF zusätzlich angehängt' : ', PDF nur im Portal'}): ${confirmation.link}`) : '',
        flyerAttachment.length ? (en ? 'Marketing flyer attached.' : 'Marketing-Flyer angehängt.') : ''
      ].filter(Boolean)
      const docs = attachedUrl ? [{ title: en ? 'Quote (PDF)' : 'Angebot (PDF)', url: attachedUrl }] : []
      const created = await logContactActivity(event, token, {
        source,
        recordId: recordIdNum,
        type: 'EM',
        contactEmail: toEmail,
        description: en ? `Quote sent: ${filename}` : `Angebot gesendet: ${filename}`,
        comments: lines.join('\n'),
        documents: docs
      })
      activityLogged = !!created
    }
  } catch (err: any) {
    console.error('Quote activity skipped:', err?.message || err)
  }

  return {
    status: 200,
    message: 'Quote sent successfully',
    filename,
    attached,
    conditionsSaved,
    activityLogged,
    confirmation,
    attachedToMail: attachPdf,
    flyerAttached: flyerAttachment.length > 0,
    warning: [attachWarning, flyerWarning, confirmWarning].filter(Boolean).join(' · ') || 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
})
