import models from '../../../../api/models'
import lnd from '../../../../api/lnd'
import { createInvoice } from 'ln-service'
import { lnurlPayDescriptionHashForUser } from '../../../../lib/lnurl'
import serialize from '../../../../api/resolvers/serial'
import * as secp256k1 from '@noble/secp256k1'
import { createHash } from 'crypto'

export default async ({ query: { username, amount, nostr } }, res) => {
  const user = await models.user.findUnique({ where: { name: username } })
  if (!user) {
    return res.status(400).json({ status: 'ERROR', reason: `user @${username} does not exist` })
  }
  try {
  // if nostr, decode, validate sig, check tags, set description hash
    let description, descriptionHash, noteStr
    if (nostr) {
      noteStr = decodeURIComponent(nostr)
      const note = JSON.parse(noteStr)
      const hasPTag = note.tags?.filter(t => t[0] === 'p').length >= 1
      const hasETag = note.tags?.filter(t => t[0] === 'e').length <= 1
      if (await secp256k1.schnorr.verify(note.sig, note.id, note.pubkey) &&
      hasPTag && hasETag) {
        description = user.hideInvoiceDesc ? undefined : 'zap'
        descriptionHash = createHash('sha256').update(noteStr).digest('hex')
      } else {
        res.status(400).json({ status: 'ERROR', reason: 'invalid NIP-57 note' })
        return
      }
    } else {
      description = user.hideInvoiceDesc ? undefined : `Funding @${username} on stacker.news`
      descriptionHash = lnurlPayDescriptionHashForUser(username)
    }

    if (!amount || amount < 1000) {
      return res.status(400).json({ status: 'ERROR', reason: 'amount must be >=1000 msats' })
    }

    // generate invoice
    const expiresAt = new Date(new Date().setMinutes(new Date().getMinutes() + 1))
    const invoice = await createInvoice({
      description: description,
      description_hash: descriptionHash,
      lnd,
      mtokens: amount,
      expires_at: expiresAt
    })

    await serialize(models,
      models.$queryRaw`SELECT * FROM create_invoice(${invoice.id}, ${invoice.request},
        ${expiresAt}, ${Number(amount)}, ${user.id}, ${noteStr || description})`)

    return res.status(200).json({
      pr: invoice.request,
      routes: []
    })
  } catch (error) {
    console.log(error)
    res.status(400).json({ status: 'ERROR', reason: error.message })
  }
}