import { finalizeEvent, type EventTemplate, type Event } from 'nostr-tools'
import type { NostrIdentity } from './identity'
import { hexToBytes } from '@/lib/utils/crypto'

/**
 * Nostr event kinds
 */
export const EventKinds = {
  TEXT_NOTE: 1,
  REACTION: 7,
  ZAP: 9735,
  PROFILE_METADATA: 0,
  CONTACT_LIST: 3,
  REPOST: 6,
  DELETE: 5
} as const

/**
 * Create a text note event
 */
export function createTextNote(content: string, identity: NostrIdentity, replyTo?: string): Event {
  const eventTemplate: EventTemplate = {
    kind: EventKinds.TEXT_NOTE,
    created_at: Math.floor(Date.now() / 1000),
    tags: [],
    content
  }

  // Add reply tags if this is a reply
  if (replyTo) {
    eventTemplate.tags.push(['e', replyTo, '', 'reply'])
  }

  return finalizeEvent(eventTemplate, hexToBytes(identity.privateKey))
}

/**
 * Create a reaction event (like/dislike)
 */
export function createReaction(
  targetEventId: string,
  targetAuthor: string,
  reaction: string,
  identity: NostrIdentity
): Event {
  const eventTemplate: EventTemplate = {
    kind: EventKinds.REACTION,
    created_at: Math.floor(Date.now() / 1000),
    tags: [
      ['e', targetEventId],
      ['p', targetAuthor]
    ],
    content: reaction
  }

  return finalizeEvent(eventTemplate, hexToBytes(identity.privateKey))
}

/**
 * Create a profile metadata event
 */
export function createProfileMetadata(profile: Record<string, any>, identity: NostrIdentity): Event {
  const eventTemplate: EventTemplate = {
    kind: EventKinds.PROFILE_METADATA,
    created_at: Math.floor(Date.now() / 1000),
    tags: [],
    content: JSON.stringify(profile)
  }

  return finalizeEvent(eventTemplate, hexToBytes(identity.privateKey))
}

/**
 * Create a contact list event (following)
 */
export function createContactList(contacts: string[], identity: NostrIdentity): Event {
  const eventTemplate: EventTemplate = {
    kind: EventKinds.CONTACT_LIST,
    created_at: Math.floor(Date.now() / 1000),
    tags: contacts.map(pubkey => ['p', pubkey]),
    content: ''
  }

  return finalizeEvent(eventTemplate, hexToBytes(identity.privateKey))
}

/**
 * Create a delete event
 */
export function createDeleteEvent(eventIds: string[], identity: NostrIdentity, reason?: string): Event {
  const eventTemplate: EventTemplate = {
    kind: EventKinds.DELETE,
    created_at: Math.floor(Date.now() / 1000),
    tags: eventIds.map(id => ['e', id]),
    content: reason || ''
  }

  return finalizeEvent(eventTemplate, hexToBytes(identity.privateKey))
}

/**
 * Extract reply information from event tags
 */
export function getReplyInfo(event: any): { isReply: boolean; replyTo?: string; mentions: string[] } {
  const eTags = event.tags.filter((tag: string[]) => tag[0] === 'e')
  const pTags = event.tags.filter((tag: string[]) => tag[0] === 'p')

  // Find reply target (last e tag with "reply" marker or last e tag)
  const replyTag = eTags.find((tag: string[]) => tag[3] === 'reply') || eTags[eTags.length - 1]
  
  return {
    isReply: !!replyTag,
    replyTo: replyTag?.[1],
    mentions: pTags.map((tag: string[]) => tag[1])
  }
}

/**
 * Extract reactions from events
 */
export function extractReactions(events: any[]): Map<string, { [reaction: string]: number }> {
  const reactions = new Map<string, { [reaction: string]: number }>()

  events
    .filter(event => event.kind === EventKinds.REACTION)
    .forEach(event => {
      const targetEventId = event.tags.find((tag: string[]) => tag[0] === 'e')?.[1]
      if (!targetEventId) return

      const reaction = event.content || '👍'
      const current = reactions.get(targetEventId) || {}
      current[reaction] = (current[reaction] || 0) + 1
      reactions.set(targetEventId, current)
    })

  return reactions
}

/**
 * Extract reply counts from events
 */
export function extractReplyCounts(events: any[]): Map<string, number> {
  const replyCounts = new Map<string, number>()

  events
    .filter(event => event.kind === EventKinds.TEXT_NOTE)
    .forEach(event => {
      const replyInfo = getReplyInfo(event)
      if (replyInfo.isReply && replyInfo.replyTo) {
        const current = replyCounts.get(replyInfo.replyTo) || 0
        replyCounts.set(replyInfo.replyTo, current + 1)
      }
    })

  return replyCounts
}