import {
  type FormMetadata,
  type SubmitResponsePayload
} from '@defra/forms-model'
import { addDays, format as dateFormat } from 'date-fns'

import { config } from '../../../../../config/index.js'
import { getAnswer } from '../../components/helpers/components.js'
import { escapeMarkdown } from '../../components/helpers/index.js'
import { PaymentField } from '../../components/index.js'
import { type checkFormStatus } from '../../helpers.js'
import { type FormModel } from '../../models/index.js'
import {
  type DetailItem,
  type DetailItemField
} from '../../models/types.js'
import { type FormContext } from '../../types.js'
import {
  formatCurrency,
  formatPaymentDate
} from '../../../payment/helper.js'

const designerUrl = config.get('designerUrl')

export function format(
  _context: FormContext,
  items: DetailItem[],
  model: FormModel,
  submitResponse: SubmitResponsePayload,
  formStatus: ReturnType<typeof checkFormStatus>,
  _formMetadata?: FormMetadata
) {
  const { files } = submitResponse.result

  const formName = escapeMarkdown(model.name)

  /**
   * @todo Refactor this below but the code to
   * generate the question and answers works for now
   */
  const now = new Date()
  const formattedNow = `${dateFormat(now, 'h:mmaaa')} on ${dateFormat(now, 'd MMMM yyyy')}`

  const fileExpiryDate = addDays(now, 90)
  const formattedExpiryDate = `${dateFormat(fileExpiryDate, 'h:mmaaa')} on ${dateFormat(fileExpiryDate, 'eeee d MMMM yyyy')}`

  const lines: string[] = []

  lines.push(
    `^ For security reasons, the links in this email expire at ${escapeMarkdown(formattedExpiryDate)}\n`
  )

  if (formStatus.isPreview) {
    lines.push(`This is a test of the ${formName} ${formStatus.state} form.\n`)
  }

  lines.push(`${formName} form received at ${escapeMarkdown(formattedNow)}.\n`)
  lines.push('---\n')

  const regularItems = items.filter((item) => !isPaymentItem(item))
  const paymentItems = items.filter((item) => isPaymentItem(item))

  regularItems.forEach((item) => {
    const label = escapeMarkdown(item.label)

    lines.push(`## ${label}\n`)

    if ('subItems' in item) {
      const filename = escapeMarkdown(`Download ${label} (CSV)`)
      const fileId = files.repeaters[item.name]

      lines.push(`[${filename}](${designerUrl}/file-download/${fileId})\n`)
    } else {
      lines.push(
        getAnswer(item.field, item.state, {
          format: 'email'
        })
      )
    }

    lines.push('---\n')
  })

  const filename = escapeMarkdown('Download main form (CSV)')
  lines.push(`[${filename}](${designerUrl}/file-download/${files.main})\n`)

  appendPaymentSection(paymentItems, lines)

  return lines.join('\n')
}

/**
 * Check if an item is a PaymentField
 */
function isPaymentItem(item: DetailItem): boolean {
  if ('subItems' in item) {
    return false
  }
  return item.field instanceof PaymentField
}

/**
 * Appends the payment details section to the email lines if payment exists
 */
function appendPaymentSection(paymentItems: DetailItem[], lines: string[]) {
  if (paymentItems.length === 0) {
    return
  }

  const paymentItem = paymentItems[0] as DetailItemField
  const paymentField = paymentItem.field as PaymentField
  const paymentState = paymentField.getPaymentStateFromState(paymentItem.state)

  if (!paymentState) {
    return
  }

  const formattedAmount = formatCurrency(paymentState.amount)
  const dateOfPayment = paymentState.preAuth?.createdAt
    ? formatPaymentDate(paymentState.preAuth.createdAt)
    : ''

  lines.push(
    '---\n',
    `# Your payment of ${formattedAmount} was successful\n`,
    '## Payment for\n',
    `${escapeMarkdown(paymentState.description)}\n`,
    '---\n',
    '## Total amount\n',
    `${formattedAmount}\n`,
    '---\n',
    '## Date of payment\n',
    `${escapeMarkdown(dateOfPayment)}\n`,
    '---\n'
  )
}
