<script setup lang="ts">
import { ref, computed } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { nip19 } from 'nostr-tools'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Switch } from '@/components/ui/switch'
import { Label } from '@/components/ui/label'
import { Separator } from '@/components/ui/separator'
import { Badge } from '@/components/ui/badge'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { QrCode, Copy, Check, RefreshCw, Trash2, Plus } from 'lucide-vue-next'
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import type { PayLink } from '../services/WalletService'

interface Props {
  open: boolean
}

interface Emits {
  (e: 'update:open', value: boolean): void
}

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

// Services
const walletService = injectService(SERVICE_TOKENS.WALLET_SERVICE) as any
const toastService = injectService(SERVICE_TOKENS.TOAST_SERVICE) as any
const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE) as any

// Form validation schema
const formSchema = toTypedSchema(z.object({
  description: z.string().min(1, "Description is required").max(200, "Description too long"),
  minAmount: z.number().min(1, "Minimum amount must be at least 1 sat"),
  maxAmount: z.number().min(1, "Maximum amount must be at least 1 sat"),
  username: z.string().optional(),
  allowComments: z.boolean().default(false)
}))

// Form setup
const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    description: '',
    minAmount: 1,
    maxAmount: 100000,
    username: '',
    allowComments: false
  }
})

const { resetForm, meta } = form
const isFormValid = computed(() => meta.value.valid)

// State
const activeTab = ref('create')
const selectedPayLink = ref<PayLink | null>(null)
const copiedField = ref<string | null>(null)
const qrCode = ref<string | null>(null)
const isLoadingQR = ref(false)

// Computed
const existingPayLinks = computed(() => walletService?.payLinks?.value || [])
const isCreating = computed(() => walletService?.isCreatingPayLink?.value || false)
const error = computed(() => walletService?.error?.value)

// Methods
const onSubmit = form.handleSubmit(async (formValues) => {
  try {
    const payLink = await walletService.createReceiveAddress({
      description: formValues.description,
      minAmount: formValues.minAmount,
      maxAmount: formValues.maxAmount,
      username: formValues.username || undefined,
      allowComments: formValues.allowComments
    })
    
    if (payLink) {
      selectedPayLink.value = payLink
      activeTab.value = 'existing'
      resetForm()
      toastService?.success('Receive address created successfully!')
    }
  } catch (error) {
    console.error('Failed to create receive address:', error)
  }
})

async function copyToClipboard(text: string, field: string) {
  try {
    await navigator.clipboard.writeText(text)
    copiedField.value = field
    toastService?.success('Copied to clipboard!')
    
    setTimeout(() => {
      copiedField.value = null
    }, 2000)
  } catch (error) {
    console.error('Failed to copy:', error)
    toastService?.error('Failed to copy to clipboard')
  }
}

function encodeLNURL(url: string): string {
  try {
    // Convert URL to bytes
    const bytes = new TextEncoder().encode(url)
    // Encode as bech32 with 'lnurl' prefix
    const bech32 = nip19.encodeBytes('lnurl', bytes)
    // Return with lightning: prefix in uppercase
    return `lightning:${bech32.toUpperCase()}`
  } catch (error) {
    console.error('Failed to encode LNURL:', error)
    return url // Fallback to original URL
  }
}

async function generateQRCode(data: string) {
  if (!data) return

  isLoadingQR.value = true
  try {
    // Encode LNURL with proper bech32 format and lightning: prefix
    const encodedLNURL = encodeLNURL(data)
    // Use the existing PaymentService QR code generation
    qrCode.value = await paymentService?.generateQRCode(encodedLNURL)
  } catch (error) {
    console.error('Failed to generate QR code:', error)
    toastService?.error('Failed to generate QR code')
  } finally {
    isLoadingQR.value = false
  }
}

async function deletePayLink(link: PayLink) {
  if (await walletService.deletePayLink(link.id)) {
    toastService?.success('Receive address deleted')
    if (selectedPayLink.value?.id === link.id) {
      selectedPayLink.value = null
    }
  }
}

async function selectPayLink(link: PayLink) {
  selectedPayLink.value = link
  // Generate QR code when selecting a pay link
  if (link.lnurl) {
    await generateQRCode(link.lnurl)
  }
}

function closeDialog() {
  emit('update:open', false)
  resetForm()
  selectedPayLink.value = null
  activeTab.value = 'create'
}

// Handle dialog open/close state changes
function onOpenChange(open: boolean) {
  if (open && walletService) {
    walletService.refresh()
  } else if (!open) {
    // Dialog is being closed (including X button) - just emit the update
    emit('update:open', false)
    // Clean up state
    resetForm()
    selectedPayLink.value = null
    activeTab.value = 'create'
  }
}
</script>

<template>
  <Dialog :open="props.open" @update:open="onOpenChange">
    <DialogContent class="sm:max-w-2xl max-h-[90vh] overflow-y-auto">
      <DialogHeader>
        <DialogTitle class="flex items-center gap-2">
          <QrCode class="h-5 w-5" />
          Receive Bitcoin
        </DialogTitle>
        <DialogDescription>
          Create LNURL addresses and Lightning addresses to receive Bitcoin payments.
        </DialogDescription>
      </DialogHeader>

      <Tabs v-model="activeTab" class="w-full">
        <TabsList class="grid w-full grid-cols-2">
          <TabsTrigger value="create">Create New</TabsTrigger>
          <TabsTrigger value="existing">Existing Addresses</TabsTrigger>
        </TabsList>

        <TabsContent value="create" class="space-y-4">
          <form @submit="onSubmit" class="space-y-4">
            <FormField v-slot="{ componentField }" name="description">
              <FormItem>
                <FormLabel>Description *</FormLabel>
                <FormControl>
                  <Textarea
                    placeholder="e.g., Tips for my work"
                    v-bind="componentField"
                  />
                </FormControl>
                <FormDescription>What are you receiving payments for?</FormDescription>
                <FormMessage />
              </FormItem>
            </FormField>

            <div class="grid grid-cols-2 gap-4">
              <FormField v-slot="{ componentField }" name="minAmount">
                <FormItem>
                  <FormLabel>Min Amount (sats) *</FormLabel>
                  <FormControl>
                    <Input
                      type="number"
                      min="1"
                      placeholder="1"
                      v-bind="componentField"
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              </FormField>

              <FormField v-slot="{ componentField }" name="maxAmount">
                <FormItem>
                  <FormLabel>Max Amount (sats) *</FormLabel>
                  <FormControl>
                    <Input
                      type="number"
                      min="1"
                      placeholder="100000"
                      v-bind="componentField"
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              </FormField>
            </div>

            <FormField v-slot="{ componentField }" name="username">
              <FormItem>
                <FormLabel>Lightning Address Username (Optional)</FormLabel>
                <FormControl>
                  <Input
                    placeholder="e.g., satoshi"
                    v-bind="componentField"
                  />
                </FormControl>
                <FormDescription>Creates a Lightning address like: satoshi@yourdomain.com</FormDescription>
                <FormMessage />
              </FormItem>
            </FormField>

            <FormField v-slot="{ value, handleChange }" name="allowComments" type="checkbox">
              <FormItem class="flex flex-row items-center justify-between rounded-lg border p-3">
                <div class="space-y-0.5">
                  <FormLabel>Allow Comments</FormLabel>
                  <FormDescription>Let senders include a message with their payment</FormDescription>
                </div>
                <FormControl>
                  <Switch :checked="value" @update:checked="handleChange" />
                </FormControl>
              </FormItem>
            </FormField>

            <div v-if="error" class="text-destructive text-sm">
              {{ error }}
            </div>

            <div class="flex gap-2 pt-4">
              <Button
                type="submit"
                :disabled="!isFormValid || isCreating"
                class="flex-1"
              >
                <RefreshCw v-if="isCreating" class="w-4 h-4 mr-2 animate-spin" />
                <Plus v-else class="w-4 h-4 mr-2" />
                {{ isCreating ? 'Creating...' : 'Create Receive Address' }}
              </Button>
              <Button type="button" variant="outline" @click="closeDialog">
                Cancel
              </Button>
            </div>
          </form>
        </TabsContent>

        <TabsContent value="existing" class="space-y-4">
          <div v-if="existingPayLinks.length === 0" class="text-center py-8 text-muted-foreground">
            <QrCode class="h-12 w-12 mx-auto mb-4 opacity-50" />
            <p>No receive addresses created yet</p>
            <Button variant="outline" @click="activeTab = 'create'" class="mt-4">
              Create Your First Address
            </Button>
          </div>

          <div v-else class="space-y-4">
            <!-- Pay Links List -->
            <div class="grid gap-2 max-h-48 overflow-y-auto">
              <div 
                v-for="link in existingPayLinks" 
                :key="link.id"
                @click="selectPayLink(link)"
                class="flex items-center justify-between p-3 border rounded-lg cursor-pointer hover:bg-accent transition-colors"
                :class="{ 'bg-accent border-primary': selectedPayLink?.id === link.id }"
              >
                <div class="flex-1">
                  <p class="font-medium">{{ link.description }}</p>
                  <div class="flex items-center gap-2 text-sm text-muted-foreground">
                    <span>{{ link.min }}-{{ link.max }} sats</span>
                    <Badge v-if="link.username" variant="secondary">{{ link.username }}</Badge>
                  </div>
                </div>
                <Button 
                  variant="ghost" 
                  size="sm"
                  @click.stop="deletePayLink(link)"
                  class="text-destructive hover:text-destructive"
                >
                  <Trash2 class="h-4 w-4" />
                </Button>
              </div>
            </div>

            <!-- Selected Pay Link Details -->
            <div v-if="selectedPayLink" class="border rounded-lg p-4 space-y-4">
              <div class="flex items-center justify-between">
                <h4 class="font-medium">{{ selectedPayLink.description }}</h4>
                <div class="flex items-center gap-2 text-sm text-muted-foreground">
                  <span>{{ selectedPayLink.min }}-{{ selectedPayLink.max }} sats</span>
                </div>
              </div>
              
              <Separator />

              <!-- QR Code Display -->
              <div class="flex flex-col items-center space-y-4">
                <div v-if="isLoadingQR" class="w-48 h-48 flex items-center justify-center bg-muted rounded-lg">
                  <RefreshCw class="h-8 w-8 animate-spin text-muted-foreground" />
                </div>
                <div v-else-if="qrCode" class="bg-white p-4 rounded-lg">
                  <img 
                    :src="qrCode" 
                    alt="LNURL QR Code" 
                    class="w-48 h-48"
                  />
                </div>
                <div v-else class="w-48 h-48 flex items-center justify-center bg-muted rounded-lg">
                  <QrCode class="h-12 w-12 text-muted-foreground opacity-50" />
                </div>
                
                <!-- Encoded LNURL (for QR) -->
                <div class="w-full space-y-2">
                  <Label>LNURL (Encoded)</Label>
                  <div class="flex gap-2">
                    <Input
                      :value="selectedPayLink.lnurl ? encodeLNURL(selectedPayLink.lnurl) : ''"
                      readonly
                      class="font-mono text-xs"
                    />
                    <Button
                      variant="outline"
                      size="sm"
                      @click="copyToClipboard(selectedPayLink.lnurl ? encodeLNURL(selectedPayLink.lnurl) : '', 'encoded-lnurl')"
                    >
                      <Check v-if="copiedField === 'encoded-lnurl'" class="h-4 w-4 text-green-600" />
                      <Copy v-else class="h-4 w-4" />
                    </Button>
                  </div>
                </div>

                <!-- Raw LNURL -->
                <div class="w-full space-y-2">
                  <Label>LNURL (Raw)</Label>
                  <div class="flex gap-2">
                    <Input
                      :value="selectedPayLink.lnurl"
                      readonly
                      class="font-mono text-xs"
                    />
                    <Button
                      variant="outline"
                      size="sm"
                      @click="copyToClipboard(selectedPayLink.lnurl || '', 'lnurl')"
                    >
                      <Check v-if="copiedField === 'lnurl'" class="h-4 w-4 text-green-600" />
                      <Copy v-else class="h-4 w-4" />
                    </Button>
                  </div>
                </div>

                <!-- Lightning Address (if available) -->
                <div v-if="selectedPayLink.lnaddress" class="w-full space-y-2">
                  <Label>Lightning Address</Label>
                  <div class="flex gap-2">
                    <Input 
                      :value="selectedPayLink.lnaddress" 
                      readonly 
                      class="font-mono"
                    />
                    <Button 
                      variant="outline" 
                      size="sm"
                      @click="copyToClipboard(selectedPayLink.lnaddress || '', 'lnaddress')"
                    >
                      <Check v-if="copiedField === 'lnaddress'" class="h-4 w-4 text-green-600" />
                      <Copy v-else class="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <div class="flex justify-end pt-4">
            <Button variant="outline" @click="closeDialog">
              Close
            </Button>
          </div>
        </TabsContent>
      </Tabs>
    </DialogContent>
  </Dialog>
</template>