import { getApiUrl } from '@/lib/config/lnbits'
import type { Order } from '@/modules/market/stores/market'

export interface LightningInvoice {
  checking_id: string
  payment_hash: string
  wallet_id: string
  amount: number
  fee: number
  bolt11: string // This is the payment request/invoice
  status: string
  memo?: string
  expiry?: string
  preimage?: string
  extra?: Record<string, any>
  created_at?: string
  updated_at?: string
}

export interface CreateInvoiceRequest {
  amount: number
  memo: string
  unit?: 'sat' | 'btc'
  expiry?: number
  extra?: Record<string, any>
}

export interface PaymentStatus {
  paid: boolean
  amount_paid: number
  paid_at?: number
  payment_hash: string
}

export class InvoiceService {
  private baseUrl: string

  constructor() {
    // Use the payments endpoint for invoice creation
    this.baseUrl = getApiUrl('/payments')
  }

  private async request<T>(
    endpoint: string,
    adminKey: string,
    options: RequestInit = {}
  ): Promise<T> {
    // Construct the URL - for payments, we just append the endpoint
    const url = `${this.baseUrl}${endpoint}`
    console.log('Invoice Service Request:', { url, endpoint })

    const headers: HeadersInit = {
      'Content-Type': 'application/json',
      'X-Api-Key': adminKey, // Use the wallet's admin key
      ...options.headers,
    }

    const response = await fetch(url, {
      ...options,
      headers,
    })

    if (!response.ok) {
      const errorText = await response.text()
      console.error('Invoice Service Error:', {
        status: response.status,
        statusText: response.statusText,
        errorText,
        url
      })
      throw new Error(`Invoice request failed: ${response.status} ${response.statusText}`)
    }

    return response.json()
  }

  /**
   * Create a Lightning invoice for an order
   */
  async createInvoice(order: Order, adminKey: string, extra?: Record<string, any>): Promise<LightningInvoice> {
    const invoiceData: CreateInvoiceRequest = {
      amount: order.total,
      unit: 'sat',
      memo: `Order ${order.id} - ${order.items.length} items`,
      expiry: extra?.expiry || 3600, // Allow configurable expiry, default 1 hour
      extra: {
        tag: 'nostrmarket', // Use nostrmarket tag for compatibility
        order_id: extra?.order_id || order.id, // Use passed order_id or fallback to order.id
        merchant_pubkey: extra?.merchant_pubkey || order.sellerPubkey, // Use passed merchant_pubkey or fallback
        ...extra // Allow additional metadata to be passed in
      }
    }

    try {
      // Log the exact data being sent to LNBits
      const requestBody = {
        out: false, // Incoming payment
        ...invoiceData
      }
      
      console.log('Sending invoice request to LNBits:', {
        url: `${this.baseUrl}`,
        body: requestBody,
        extra: requestBody.extra
      })
      
      // Use the correct LNBits payments endpoint
      const response = await this.request<LightningInvoice>('', adminKey, {
        method: 'POST',
        body: JSON.stringify(requestBody)
      })

      console.log('Full LNBits response:', response)
      console.log('Response type:', typeof response)
      console.log('Response keys:', Object.keys(response))
      console.log('Response expiry field:', response.expiry)
      console.log('Response created_at field:', response.created_at)

      // Check if we have the expected fields
      if (!response.bolt11) {
        console.error('Missing bolt11 in response:', response)
        throw new Error('Invalid invoice response: missing bolt11')
      }

      console.log('Lightning invoice created with nostrmarket tag:', {
        orderId: order.id,
        paymentHash: response.payment_hash,
        amount: response.amount,
        paymentRequest: response.bolt11.substring(0, 50) + '...',
        extra: invoiceData.extra
      })

      return response
    } catch (error) {
      console.error('Failed to create Lightning invoice:', error)
      throw new Error('Failed to create payment invoice')
    }
  }

  /**
   * Check payment status of an invoice
   */
  async checkPaymentStatus(paymentHash: string, adminKey: string): Promise<PaymentStatus> {
    try {
      const response = await this.request<PaymentStatus>(`/${paymentHash}`, adminKey, {})
      return response
    } catch (error) {
      console.error('Failed to check payment status:', error)
      throw new Error('Failed to check payment status')
    }
  }

  /**
   * Get all payments for a wallet
   */
  async getWalletPayments(adminKey: string, limit: number = 100): Promise<PaymentStatus[]> {
    try {
      const response = await this.request<PaymentStatus[]>(`?limit=${limit}`, adminKey, {})
      return response
    } catch (error) {
      console.error('Failed to get wallet payments:', error)
      throw new Error('Failed to get wallet payments')
    }
  }

  /**
   * Validate a Lightning payment request
   */
  validatePaymentRequest(paymentRequest: string): boolean {
    // Basic validation - should start with 'lnbc' and be a valid length
    return paymentRequest.startsWith('lnbc') && paymentRequest.length > 50
  }

  /**
   * Extract payment hash from a payment request
   */
  extractPaymentHash(paymentRequest: string): string | null {
    try {
      // This is a simplified extraction - in production you'd use a proper BOLT11 decoder
      const match = paymentRequest.match(/lnbc[0-9]+[a-z0-9]+/i)
      return match ? match[0] : null
    } catch (error) {
      console.error('Failed to extract payment hash:', error)
      return null
    }
  }
}

