'use client'

import React, { useState } from 'react'
import { Connection, PublicKey, Transaction } from '@solana/web3.js'
import { TOKEN_PROGRAM_ID, createTransferInstruction, getAssociatedTokenAddress } from '@solana/spl-token'

interface WalletState {
  connected: boolean
  publicKey: string | null
}

interface PaymentStatus {
  paid: boolean
  processing: boolean
  error: string | null
}

interface GenerationState {
  loading: boolean
  imageUrl: string | null
  error: string | null
}

// Solflare wallet type definition
interface SolflareWallet {
  connect(): Promise<void>
  disconnect(): Promise<void>
  signAndSendTransaction(
    transaction: Transaction | VersionedTransaction,
    options?: { skipPreflight?: boolean }
  ): Promise<{ signature: string; publicKey: string }>
  publicKey: PublicKey
  connected: boolean
}

declare global {
  interface Window {
    solflare?: SolflareWallet
  }
}

// Replace these with your actual addresses
const MTM_TOKEN_MINT: string = '97RggLo3zV5kFGYW4yoQTxr4Xkz4Vg2WPHzNYXXWpump'
const PAYMENT_RECEIVER_ADDRESS: string = 'JB8YCqKBKNtS4ZHcGPJXSJokcvdgdeeyWRxGqgyX5EwP'
const REQUIRED_PAYMENT_AMOUNT: number = 2
const SOLANA_NETWORK: string = 'mainnet'
const SOLANA_RPC_URL: string = 'https://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
const SOLANA_WEBSOCKET_URL: string = 'wss://young-radial-orb.solana-mainnet.quiknode.pro/67612b364664616c29514e551bf5de38447ca3d4'
const connection = new Connection(
	SOLANA_RPC_URL,
	{
	 commitment: 'confirmed',
         wsEndpoint: SOLANA_WEBSOCKET_URL,
         confirmTransactionInitialTimeout: 30000, // 30 seconds 
	}
)

const Page: React.FC = (): React.ReactElement => {
  const [walletState, setWalletState] = useState<WalletState>({
    connected: false,
    publicKey: null,
  })
  const [paymentStatus, setPaymentStatus] = useState<PaymentStatus>({
    paid: false,
    processing: false,
    error: null,
  })
  const [inputText, setInputText] = useState<string>('')
  const [generationState, setGenerationState] = useState<GenerationState>({
    loading: false,
    imageUrl: null,
    error: null,
  })

  const connectWallet = async (): Promise<void> => {
    try {
      if (typeof window === 'undefined' || !window.solflare) {
        throw new Error('Solflare wallet not found! Please install it first.')
      }

      await window.solflare.connect()

      if (!window.solflare.publicKey) {
        throw new Error('Failed to connect to wallet')
      }

      const publicKey: string = window.solflare.publicKey.toString()
      setWalletState({
        connected: true,
        publicKey,
      })
    } catch (error) {
      console.error('Wallet connection error:', error)
      setWalletState({
        connected: false,
        publicKey: null,
      })
    }
  }

  const processPayment = async (): Promise<void> => {
    if (!walletState.connected || !walletState.publicKey || !window.solflare) {
      return
    }

    setPaymentStatus({ ...paymentStatus, processing: true, error: null })

    try {
      // Convert string addresses to PublicKeys
      const senderPublicKey = new PublicKey(walletState.publicKey)
      const mintPublicKey = new PublicKey(MTM_TOKEN_MINT)
      const receiverPublicKey = new PublicKey(PAYMENT_RECEIVER_ADDRESS)

      // Get the associated token accounts for sender and receiver
      const senderATA = await getAssociatedTokenAddress(
        mintPublicKey,
        senderPublicKey
      )
      const receiverATA = await getAssociatedTokenAddress(
        mintPublicKey,
        receiverPublicKey
      )

      // Create transfer instruction
      const transferInstruction = createTransferInstruction(
        senderATA,
        receiverATA,
        senderPublicKey,
        BigInt(REQUIRED_PAYMENT_AMOUNT * (10 ** 6)) // Convert to proper format
      )

      const latestBlockhash = await connection.getLatestBlockhash('confirmed')

      // Create transaction
      const transaction = new Transaction()
      transaction.add(transferInstruction)
      transaction.recentBlockhash = latestBlockhash.blockhash
      transaction.feePayer = senderPublicKey

      try {
        // Sign and send transaction with preflight disabled
        const { signature } = await window.solflare.signAndSendTransaction(transaction, {
          skipPreflight: true
        })

        console.log('Transaction sent:', signature)

        // Wait for confirmation with WebSocket support
        const confirmation = await connection.confirmTransaction({
          signature,
          blockhash: latestBlockhash.blockhash,
          lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
        }, 'confirmed')

        console.log('Transaction confirmed:', confirmation)

        if (confirmation.value.err) {
          throw new Error('Transaction failed to confirm')
        }

        setPaymentStatus({
          paid: true,
          processing: false,
          error: null,
        })
      } catch (error) {
        console.error('Transaction error:', error)
        throw new Error(`Failed to sign or send transaction: ${error instanceof Error ? error.message : 'Unknown error'}`)
      }
    } catch (error) {
      console.error('Payment error:', error)
      setPaymentStatus({
        ...paymentStatus,
        processing: false,
        error: error instanceof Error ? error.message : 'Payment failed. Please try again.',
      })
    }
  }

  const generateMeme = async (): Promise<void> => {
    if (!inputText || !paymentStatus.paid) {
      return
    }

    setGenerationState({
      ...generationState,
      loading: true,
      error: null,
    })

    try {
      const response = await fetch('/api/proxy', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          protocol: 'https',
          origin: 'api.openai.com',
          path: '/v1/images/generations',
          headers: {
            'Authorization': `Bearer ${process.env.NEXT_PUBLIC_OPENAI_API_KEY}`,
            'Content-Type': 'application/json',
          },
          method: 'POST',
          body: JSON.stringify({
            prompt: `Generate a meme with text: ${inputText}`,
            n: 1,
            size: '512x512',
          }),
        }),
      })

      const data = await response.json()

      if (data.data && data.data[0].url) {
        setGenerationState({
          loading: false,
          imageUrl: data.data[0].url,
          error: null,
        })
      } else {
        throw new Error('Failed to generate image')
      }
    } catch (error) {
      setGenerationState({
        ...generationState,
        loading: false,
        error: 'Failed to generate meme. Please try again.',
      })
    }
  }

  return (
    <div className="min-h-screen bg-gray-100 py-12 px-4 sm:px-6 lg:px-8">
      <div className="max-w-3xl mx-auto space-y-8">
        <div className="text-center">
          <h1 className="text-4xl font-bold text-gray-900 mb-4">
            AI Meme Generator
          </h1>
          <p className="text-lg text-gray-600">
            Connect your Solflare wallet and pay with MTM tokens to generate custom memes!
          </p>
        </div>

        <div className="bg-white p-6 rounded-lg shadow-md">
          {!walletState.connected ? (
            <button
              onClick={connectWallet}
              className="w-full bg-purple-600 text-white py-2 px-4 rounded-md hover:bg-purple-700 transition-colors"
            >
              Connect Solflare Wallet
            </button>
          ) : !paymentStatus.paid ? (
            <div className="space-y-4">
              <p className="text-green-600">
                Wallet Connected: {walletState.publicKey?.slice(0, 8)}...
              </p>
              <button
                onClick={processPayment}
                disabled={paymentStatus.processing}
                className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 transition-colors disabled:bg-blue-300"
              >
                {paymentStatus.processing ? 'Processing...' : `Pay ${REQUIRED_PAYMENT_AMOUNT} MTM Tokens`}
              </button>
              {paymentStatus.error && (
                <p className="text-red-600">{paymentStatus.error}</p>
              )}
            </div>
          ) : (
            <div className="space-y-4">
              <textarea
                value={inputText}
                onChange={(e) => setInputText(e.target.value)}
                placeholder="Enter your meme text here..."
                className="w-full p-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-transparent"
                rows={3}
              />
              <button
                onClick={generateMeme}
                disabled={generationState.loading || !inputText}
                className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition-colors disabled:bg-green-300"
              >
                {generationState.loading ? 'Generating...' : 'Generate Meme'}
              </button>
            </div>
          )}
        </div>

        {generationState.error && (
          <div className="text-red-600 text-center">
            {generationState.error}
          </div>
        )}

        {generationState.imageUrl && (
          <div className="bg-white p-6 rounded-lg shadow-md">
            <img
              src={generationState.imageUrl}
              alt="Generated meme"
              className="w-full h-auto rounded-md"
            />
          </div>
        )}
      </div>
    </div>
  )
}

export default Page
