<template>
  <Card class="w-full">
    <CardHeader>
      <div class="flex items-center justify-between">
        <CardTitle class="flex items-center gap-2">
          <Edit3 class="h-5 w-5" />
          Compose Note
        </CardTitle>
        <Button variant="ghost" size="sm" @click="emit('close')" class="h-8 w-8 p-0">
          <X class="h-4 w-4" />
        </Button>
      </div>
      <CardDescription>
        Share your thoughts with the community
      </CardDescription>
    </CardHeader>

    <CardContent>
      <form @submit="onSubmit" class="space-y-4">
        <!-- Note Content -->
        <FormField v-slot="{ componentField }" name="content">
          <FormItem>
            <FormLabel>Message *</FormLabel>
            <FormControl>
              <Textarea
                placeholder="What's on your mind?"
                class="min-h-[120px] resize-y"
                v-bind="componentField"
                :maxlength="280"
              />
            </FormControl>
            <div class="flex items-center justify-between">
              <FormDescription>
                Share your thoughts, updates, or announcements
              </FormDescription>
              <span class="text-xs text-muted-foreground">
                {{ characterCount }}/280
              </span>
            </div>
            <FormMessage />
          </FormItem>
        </FormField>

        <!-- Reply To (if replying) -->
        <div v-if="replyTo" class="p-3 border rounded-lg bg-muted/50">
          <div class="flex items-center justify-between mb-2">
            <div class="flex items-center gap-2">
              <Reply class="h-4 w-4 text-muted-foreground" />
              <span class="text-sm text-muted-foreground">Replying to</span>
            </div>
            <Button variant="ghost" size="sm" @click="clearReply">
              <X class="h-4 w-4" />
            </Button>
          </div>
          <div class="text-sm truncate">
            {{ replyTo.content.slice(0, 100) }}{{ replyTo.content.length > 100 ? '...' : '' }}
          </div>
        </div>

        <!-- Mentions -->
        <FormField name="mentions">
          <FormItem>
            <FormLabel>Mentions (optional)</FormLabel>
            <FormControl>
              <div class="space-y-2">
                <Input
                  v-model="newMention"
                  placeholder="Add npub or hex pubkey"
                  @keydown.enter.prevent="addMention"
                />
                <div v-if="mentions.length > 0" class="flex flex-wrap gap-2">
                  <Badge
                    v-for="(mention, index) in mentions"
                    :key="index"
                    variant="secondary"
                    class="gap-1"
                  >
                    {{ formatPubkey(mention) }}
                    <button @click="removeMention(index)" class="ml-1 hover:text-destructive">
                      <X class="h-3 w-3" />
                    </button>
                  </Badge>
                </div>
              </div>
            </FormControl>
            <FormDescription>
              Press Enter to add mentions. Use npub format or hex pubkeys.
            </FormDescription>
            <FormMessage />
          </FormItem>
        </FormField>

        <!-- Actions -->
        <div class="flex items-center justify-between pt-4 border-t">
          <div class="flex items-center gap-2 text-sm text-muted-foreground">
            <Globe class="h-4 w-4" />
            <span>Public post</span>
          </div>

          <div class="flex gap-2">
            <Button
              v-if="replyTo"
              type="button"
              variant="outline"
              @click="clearReply"
            >
              Cancel Reply
            </Button>
            <Button
              type="submit"
              :disabled="isPublishing || !isFormValid"
              class="gap-2"
            >
              <Send class="h-4 w-4" />
              {{ isPublishing ? 'Publishing...' : 'Publish Note' }}
            </Button>
          </div>
        </div>
      </form>
    </CardContent>
  </Card>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import {
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Edit3, Send, Globe, Reply, X } from 'lucide-vue-next'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
import { useToast } from '@/core/composables/useToast'
import { finalizeEvent, type EventTemplate } from 'nostr-tools'

export interface ReplyToNote {
  id: string
  content: string
  pubkey: string
}

interface Props {
  replyTo?: ReplyToNote
}

interface Emits {
  (e: 'note-published', noteId: string): void
  (e: 'clear-reply'): void
  (e: 'close'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// Services
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE)
const toast = useToast()

// Form state
const isPublishing = ref(false)
const mentions = ref<string[]>([])
const newMention = ref('')

// Form schema
const formSchema = toTypedSchema(z.object({
  content: z.string()
    .min(1, "Content is required")
    .max(280, "Content must be 280 characters or less"),
  mentions: z.array(z.string()).optional()
}))

// Form setup
const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    content: '',
    mentions: []
  }
})

const { values, meta, resetForm, setFieldValue } = form

// Computed properties
const isFormValid = computed(() => meta.value.valid && values.content.trim().length > 0)
const characterCount = computed(() => values.content?.length || 0)

// Watch mentions array and sync with form
watch(mentions, (newMentions) => {
  setFieldValue('mentions', newMentions)
}, { deep: true })

// Methods
const formatPubkey = (pubkey: string): string => {
  if (pubkey.startsWith('npub')) {
    return pubkey.slice(0, 12) + '...'
  }
  return pubkey.slice(0, 8) + '...' + pubkey.slice(-4)
}

const addMention = () => {
  const mention = newMention.value.trim()
  if (mention && !mentions.value.includes(mention)) {
    // Basic validation for pubkey format
    if (mention.startsWith('npub') || (mention.length === 64 && /^[0-9a-f]+$/i.test(mention))) {
      mentions.value.push(mention)
      newMention.value = ''
    } else {
      toast.error("Invalid pubkey format - please use npub format or 64-character hex pubkey")
    }
  }
}

const removeMention = (index: number) => {
  mentions.value.splice(index, 1)
}

const clearReply = () => {
  emit('clear-reply')
}

// Convert npub to hex if needed
const convertPubkeyToHex = (pubkey: string): string => {
  if (pubkey.startsWith('npub')) {
    try {
      // This would need proper bech32 decoding - for now return as is
      // In a real implementation, use nostr-tools nip19.decode
      return pubkey // Placeholder - needs proper conversion
    } catch {
      return pubkey
    }
  }
  return pubkey
}

// Helper function to convert hex string to Uint8Array
const hexToUint8Array = (hex: string): Uint8Array => {
  const bytes = new Uint8Array(hex.length / 2)
  for (let i = 0; i < hex.length; i += 2) {
    bytes[i / 2] = parseInt(hex.substr(i, 2), 16)
  }
  return bytes
}

// Submit handler
const onSubmit = form.handleSubmit(async (values) => {
  if (!authService?.isAuthenticated.value || !authService?.user.value) {
    toast.error("Please sign in to publish notes")
    return
  }

  if (!relayHub?.isConnected.value) {
    toast.error("Not connected to Nostr relays")
    return
  }

  const userPubkey = authService.user.value.pubkey
  const userPrivkey = authService.user.value.prvkey

  if (!userPubkey || !userPrivkey) {
    toast.error("User keys not available - please sign in again")
    return
  }

  isPublishing.value = true

  try {
    // Build tags array
    const tags: string[][] = []

    // Add reply tags if replying
    if (props.replyTo) {
      tags.push(['e', props.replyTo.id, '', 'reply'])
      tags.push(['p', props.replyTo.pubkey])
    }

    // Add mention tags
    mentions.value.forEach(mention => {
      const hexPubkey = convertPubkeyToHex(mention)
      tags.push(['p', hexPubkey])
    })

    // Create note event template
    const eventTemplate: EventTemplate = {
      kind: 1,
      content: values.content.trim(),
      tags,
      created_at: Math.floor(Date.now() / 1000)
    }

    console.log('Creating note event:', eventTemplate)

    // Sign the event
    const privkeyBytes = hexToUint8Array(userPrivkey)
    const signedEvent = finalizeEvent(eventTemplate, privkeyBytes)

    console.log('Publishing signed note:', signedEvent)

    // Publish the note
    const result = await relayHub.publishEvent(signedEvent)

    toast.success(`Note published to ${result.success}/${result.total} relays!`)

    // Reset form
    resetForm()
    mentions.value = []

    // Emit success event
    emit('note-published', signedEvent.id)

    console.log('Note published with ID:', signedEvent.id)

  } catch (error) {
    console.error('Failed to publish note:', error)
    toast.error(error instanceof Error ? error.message : "Failed to publish note")
  } finally {
    isPublishing.value = false
  }
})
</script>

<style scoped>
.resize-y {
  resize: vertical;
}
</style>