import Nostr, { getNostrProfile } from '@/lib/nostr'
import { TwitterApi } from 'twitter-api-v2'
import { msatsToSats, numWithUnits } from '@/lib/format'

const isProd = process.env.NODE_ENV === 'production'
const WEIGHTED_VOTE_THRESHOLD = 3

async function postToTwitter ({ message }) {
  if (!isProd ||
    !process.env.TWITTER_POSTER_API_KEY ||
    !process.env.TWITTER_POSTER_API_KEY_SECRET ||
    !process.env.TWITTER_POSTER_ACCESS_TOKEN ||
    !process.env.TWITTER_POSTER_ACCESS_TOKEN_SECRET) {
    console.log('Twitter poster not configured')
    return
  }

  try {
    const client = new TwitterApi({
      appKey: process.env.TWITTER_POSTER_API_KEY,
      appSecret: process.env.TWITTER_POSTER_API_KEY_SECRET,
      accessToken: process.env.TWITTER_POSTER_ACCESS_TOKEN,
      accessSecret: process.env.TWITTER_POSTER_ACCESS_TOKEN_SECRET
    })
    await client.appLogin()
    await client.v2.tweet(message)
    console.log('Successfully posted to Twitter')
  } catch (err) {
    console.error('Error posting to Twitter:', err)
  }
}

const RELAYS = [
  'wss://nos.lol/',
  'wss://nostr.land/',
  'wss://nostr.wine/',
  'wss://purplerelay.com/',
  'wss://relay.damus.io/',
  'wss://relay.snort.social/',
  'wss://relay.nostr.band/',
  'wss://relay.primal.net/'
]

async function postToNostr ({ message }) {
  if (!isProd || !process.env.NOSTR_PRIVATE_KEY) {
    console.log('Nostr poster not configured')
    return
  }

  const nostr = Nostr.get()
  const signer = nostr.getSigner({ privKey: process.env.NOSTR_PRIVATE_KEY })
  try {
    await nostr.publish({
      created_at: Math.floor(new Date().getTime() / 1000),
      content: message,
      tags: [],
      kind: 1
    }, {
      relays: RELAYS,
      signer,
      timeout: 5000
    })
  } catch (err) {
    console.error('Error posting to Nostr:', err)
  }
}

async function getHottestItem ({ models }) {
  const item = await models.$queryRaw`
    SELECT "Item".*, users.name as "userName"
    FROM "Item"
    JOIN hot_score_view ON "Item"."id" = hot_score_view.id
    JOIN users ON "Item"."userId" = users.id
    LEFT JOIN "AutoSocialPost" ON "Item"."id" = "AutoSocialPost"."itemId"
    WHERE "AutoSocialPost"."id" IS NULL
    AND "Item"."parentId" IS NULL
    AND "Item"."weightedVotes" - "Item"."weightedDownVotes" > ${WEIGHTED_VOTE_THRESHOLD}
    AND NOT "Item".bio
    AND "Item"."deletedAt" IS NULL
    ORDER BY "hot_score_view"."hot_score" DESC
    LIMIT 1`

  if (item.length === 0) {
    console.log('No item to post')
    return null
  }

  await models.AutoSocialPost.create({
    data: {
      itemId: item[0].id
    }
  })

  return item[0]
}

async function itemToMessage ({ item, postAuthorNostrProfile }) {
  return `${item.title}

by ${postAuthorNostrProfile ? `nostr:${postAuthorNostrProfile}` : `${item.userName}`} in ~${item.subName}
${numWithUnits(msatsToSats(item.msats), { abbreviate: false })} and ${numWithUnits(item.ncomments, { abbreviate: false, unitSingular: 'comment', unitPlural: 'comments' })} so far

https://stacker.news/items/${item.id}`
}

export async function postToSocial ({ models }) {
  const item = await getHottestItem({ models })
  if (!item) return

  const postAuthor = await models.user.findUnique({
    where: { id: item.userId, hideNostr: false },
    select: { nostrPubkey: true, nostrAuthPubkey: true }
  })

  const nostrKey = postAuthor?.nostrPubkey || postAuthor?.nostrAuthPubkey
  const postAuthorNostrProfile = nostrKey ? getNostrProfile(nostrKey) : null

  const twitterMessage = await itemToMessage({ item, postAuthorNostrProfile: null })
  const nostrMessage = await itemToMessage({ item, postAuthorNostrProfile })
  console.log('Twitter Message:', twitterMessage)
  console.log('Nostr Message:', nostrMessage)

  await postToTwitter({ message: twitterMessage })
  await postToNostr({ message: nostrMessage })
}
