<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 { 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 { Label } from '@/components/ui/label'
import { QrCode, Copy, Check, Loader2 } from 'lucide-vue-next'
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import type { Invoice } 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({
  amount: z.number().min(1, "Amount must be at least 1 sat").max(10000000, "Amount too large"),
  memo: z.string().max(640, "Description too long").optional()
}))

// Form setup
const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    amount: undefined,
    memo: ''
  }
})

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

// State
const createdInvoice = ref<Invoice | null>(null)
const copiedField = ref<string | null>(null)
const qrCode = ref<string | null>(null)
const isLoadingQR = ref(false)

// Computed
const isCreating = computed(() => walletService?.isCreatingInvoice?.value || false)
const error = computed(() => walletService?.error?.value)

// Watch for payment status updates
const paymentStatus = computed(() => {
  if (!createdInvoice.value) return 'pending'

  // Look for this invoice in the transactions list
  const transaction = walletService?.transactions?.value?.find(
    (tx: any) => tx.id === createdInvoice.value?.payment_hash
  )

  if (transaction) {
    return transaction.status
  }

  return 'pending'
})

const statusColor = computed(() => {
  switch (paymentStatus.value) {
    case 'confirmed': return 'text-green-600'
    case 'failed': return 'text-red-600'
    case 'pending':
    default: return 'text-yellow-600'
  }
})

const statusText = computed(() => {
  switch (paymentStatus.value) {
    case 'confirmed': return 'Paid'
    case 'failed': return 'Failed'
    case 'pending':
    default: return 'Pending'
  }
})

// Methods
const onSubmit = form.handleSubmit(async (formValues) => {
  try {
    const invoice = await walletService.createInvoice({
      amount: formValues.amount,
      memo: formValues.memo || 'Payment request'
      // Let server use default expiry
    })

    if (invoice) {
      // Force reactivity by using Object.assign with a new object
      createdInvoice.value = Object.assign({}, invoice)
      console.log('Created invoice assigned:', createdInvoice.value)

      // Use the invoice's payment_request or bolt11 for QR generation
      const paymentRequest = invoice.payment_request || invoice.bolt11
      if (paymentRequest) {
        await generateQRCode(paymentRequest)
      }
      toastService?.success('Invoice created successfully!')
    }
  } catch (error) {
    console.error('Failed to create invoice:', 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')
  }
}

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

  isLoadingQR.value = true
  try {
    // Use the existing PaymentService QR code generation
    qrCode.value = await paymentService?.generateQRCode(paymentRequest)
  } catch (error) {
    console.error('Failed to generate QR code:', error)
    toastService?.error('Failed to generate QR code')
  } finally {
    isLoadingQR.value = false
  }
}

function closeDialog() {
  emit('update:open', false)
  resetForm()
  createdInvoice.value = null
  qrCode.value = null
}

function createAnother() {
  resetForm()
  createdInvoice.value = null
  qrCode.value = null
}

// Handle dialog open/close state changes
function onOpenChange(open: boolean) {
  if (!open) {
    closeDialog()
  }
}

// Format expiry time for display
function formatExpiry(seconds: number): string {
  if (seconds < 3600) {
    return `${Math.round(seconds / 60)} minutes`
  } else if (seconds < 86400) {
    return `${Math.round(seconds / 3600)} hours`
  } else {
    return `${Math.round(seconds / 86400)} days`
  }
}
</script>

<template>
  <Dialog :open="props.open" @update:open="onOpenChange">
    <DialogContent class="sm:max-w-2xl max-h-[95vh] overflow-y-auto p-4 sm:p-6">
      <DialogHeader class="pb-2 sm:pb-4">
        <DialogTitle class="flex items-center gap-2 text-lg sm:text-xl">
          <QrCode class="h-4 w-4 sm:h-5 sm:w-5" />
          Receive Bitcoin
        </DialogTitle>
        <DialogDescription class="text-sm sm:text-base">
          Create a Lightning invoice to receive Bitcoin payments.
        </DialogDescription>
      </DialogHeader>

      <!-- Invoice Creation Form -->
      <div v-if="!createdInvoice" class="space-y-3 sm:space-y-4">
        <form @submit="onSubmit" class="space-y-3 sm:space-y-4">
          <FormField v-slot="{ componentField }" name="amount">
            <FormItem>
              <FormLabel class="text-sm font-medium">Amount (sats) *</FormLabel>
              <FormControl>
                <Input
                  type="number"
                  min="1"
                  max="10000000"
                  placeholder="Enter amount in sats"
                  class="h-9 sm:h-10"
                  v-bind="componentField"
                />
              </FormControl>
              <FormDescription class="text-xs sm:text-sm">Amount to request in satoshis</FormDescription>
              <FormMessage />
            </FormItem>
          </FormField>

          <FormField v-slot="{ componentField }" name="memo">
            <FormItem>
              <FormLabel class="text-sm font-medium">Description</FormLabel>
              <FormControl>
                <Textarea
                  placeholder="e.g., Payment for services (optional)"
                  class="min-h-[60px] sm:min-h-[80px] text-sm resize-none"
                  v-bind="componentField"
                />
              </FormControl>
              <FormDescription class="text-xs sm:text-sm">What is this payment for? (optional)</FormDescription>
              <FormMessage />
            </FormItem>
          </FormField>

          <div v-if="error" class="text-destructive text-xs sm:text-sm p-2 sm:p-3 bg-destructive/10 rounded-md">
            {{ error }}
          </div>

          <div class="flex gap-2 pt-2 sm:pt-4">
            <Button
              type="submit"
              :disabled="!isFormValid || isCreating"
              class="flex-1 h-9 sm:h-10 text-sm sm:text-base"
            >
              <Loader2 v-if="isCreating" class="w-3 h-3 sm:w-4 sm:h-4 mr-2 animate-spin" />
              {{ isCreating ? 'Creating...' : 'Create Invoice' }}
            </Button>
            <Button
              type="button"
              variant="outline"
              @click="closeDialog"
              class="h-9 sm:h-10 px-3 sm:px-4 text-sm sm:text-base"
            >
              Cancel
            </Button>
          </div>
        </form>
      </div>

      <!-- Created Invoice Display -->
      <div v-else class="space-y-4 sm:space-y-6">
        <!-- Invoice Details -->
        <div class="bg-muted/50 rounded-lg p-3 sm:p-4 space-y-2 sm:space-y-3">
          <div class="flex items-center justify-between">
            <h4 class="font-medium text-sm sm:text-base">Invoice Details</h4>
            <div class="text-xs sm:text-sm text-muted-foreground">
              Expires in {{ formatExpiry(createdInvoice.expiry || 3600) }}
            </div>
          </div>

          <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-4 text-sm">
            <div class="flex justify-between sm:block">
              <span class="text-muted-foreground">Amount:</span>
              <span class="font-medium sm:ml-2">{{ createdInvoice.amount }} sats</span>
            </div>
            <div class="flex justify-between sm:block">
              <span class="text-muted-foreground">Status:</span>
              <span class="font-medium sm:ml-2" :class="statusColor">{{ statusText }}</span>
            </div>
          </div>

          <div>
            <span class="text-muted-foreground text-xs sm:text-sm">Description:</span>
            <p class="font-medium text-sm break-words">{{ createdInvoice.memo }}</p>
          </div>
        </div>

        <!-- QR Code Display -->
        <div v-if="paymentStatus === 'pending'" class="flex flex-col items-center space-y-3 sm:space-y-4">
          <div v-if="isLoadingQR" class="w-48 h-48 sm:w-64 sm:h-64 flex items-center justify-center bg-muted rounded-lg">
            <Loader2 class="h-6 w-6 sm:h-8 sm:w-8 animate-spin text-muted-foreground" />
          </div>
          <div v-else-if="qrCode" class="text-center">
            <div class="bg-white p-2 sm:p-4 rounded-lg cursor-pointer hover:bg-gray-50 transition-colors" @click="copyToClipboard(createdInvoice.payment_request || createdInvoice.bolt11, 'qr')">
              <img
                :src="qrCode"
                alt="Lightning Invoice QR Code"
                class="w-48 h-48 sm:w-64 sm:h-64"
              />
            </div>
            <p class="text-xs text-muted-foreground mt-2">
              Click QR code to copy invoice
            </p>
          </div>
          <div v-else class="w-48 h-48 sm:w-64 sm:h-64 flex items-center justify-center bg-muted rounded-lg">
            <QrCode class="h-8 w-8 sm:h-12 sm:w-12 text-muted-foreground opacity-50" />
          </div>
        </div>

        <!-- Payment Success Message -->
        <div v-else-if="paymentStatus === 'confirmed'" class="flex flex-col items-center space-y-3 sm:space-y-4">
          <div class="w-48 h-48 sm:w-64 sm:h-64 flex flex-col items-center justify-center bg-green-50 dark:bg-green-950/20 rounded-lg border border-green-200 dark:border-green-800">
            <Check class="h-12 w-12 sm:h-16 sm:w-16 text-green-600 dark:text-green-400 mb-2 sm:mb-4" />
            <div class="text-center px-2">
              <p class="text-base sm:text-lg font-semibold text-green-800 dark:text-green-200">Payment Received!</p>
              <p class="text-sm text-green-600 dark:text-green-400 mt-1">{{ createdInvoice.amount }} sats</p>
            </div>
          </div>
        </div>

        <!-- Payment Failed Message -->
        <div v-else-if="paymentStatus === 'failed'" class="flex flex-col items-center space-y-3 sm:space-y-4">
          <div class="w-48 h-48 sm:w-64 sm:h-64 flex flex-col items-center justify-center bg-red-50 dark:bg-red-950/20 rounded-lg border border-red-200 dark:border-red-800">
            <svg class="h-12 w-12 sm:h-16 sm:w-16 text-red-600 dark:text-red-400 mb-2 sm:mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
            </svg>
            <div class="text-center px-2">
              <p class="text-base sm:text-lg font-semibold text-red-800 dark:text-red-200">Payment Failed</p>
              <p class="text-xs sm:text-sm text-red-600 dark:text-red-400 mt-1">Invoice has expired or failed</p>
            </div>
          </div>
        </div>

        <!-- Lightning Invoice (BOLT11) -->
        <div class="space-y-1 sm:space-y-2">
          <Label class="text-sm font-medium">Lightning Invoice (BOLT11)</Label>
          <div class="flex gap-1 sm:gap-2">
            <Input
              :key="`bolt11-${createdInvoice?.payment_hash}`"
              :model-value="createdInvoice?.payment_request || createdInvoice?.bolt11 || ''"
              readonly
              class="font-mono text-xs h-8 sm:h-9"
            />
            <Button
              variant="outline"
              size="sm"
              @click="copyToClipboard(createdInvoice.payment_request || createdInvoice.bolt11, 'bolt11')"
              class="h-8 w-8 sm:h-9 sm:w-auto sm:px-3 p-0 sm:p-2"
            >
              <Check v-if="copiedField === 'bolt11'" class="h-3 w-3 sm:h-4 sm:w-4 text-green-600" />
              <Copy v-else class="h-3 w-3 sm:h-4 sm:w-4" />
            </Button>
          </div>
          <p class="text-xs text-muted-foreground">
            Share this invoice with the sender to receive payment
          </p>
        </div>

        <!-- Payment Hash -->
        <div class="space-y-1 sm:space-y-2">
          <Label class="text-sm font-medium">Payment Hash</Label>
          <div class="flex gap-1 sm:gap-2">
            <Input
              :key="`hash-${createdInvoice?.payment_hash}`"
              :model-value="createdInvoice?.payment_hash || ''"
              readonly
              class="font-mono text-xs h-8 sm:h-9"
            />
            <Button
              variant="outline"
              size="sm"
              @click="copyToClipboard(createdInvoice.payment_hash, 'hash')"
              class="h-8 w-8 sm:h-9 sm:w-auto sm:px-3 p-0 sm:p-2"
            >
              <Check v-if="copiedField === 'hash'" class="h-3 w-3 sm:h-4 sm:w-4 text-green-600" />
              <Copy v-else class="h-3 w-3 sm:h-4 sm:w-4" />
            </Button>
          </div>
        </div>

        <!-- Action Buttons -->
        <div class="flex gap-2 pt-3 sm:pt-4">
          <Button
            @click="createAnother"
            variant="outline"
            class="flex-1 h-9 sm:h-10 text-sm sm:text-base"
          >
            Create Another
          </Button>
          <Button
            @click="closeDialog"
            class="flex-1 h-9 sm:h-10 text-sm sm:text-base"
          >
            Done
          </Button>
        </div>
      </div>
    </DialogContent>
  </Dialog>
</template>
