/**
 * useBlockchainBet Hook
 *
 * Handles bet-related blockchain transactions.
 *
 * Features:
 * - Create bet on blockchain
 * - Accept bet (user signs with MetaMask)
 * - Request oracle settlement
 * - Monitor transaction status
 *
 * NOTE: This is pseudocode/skeleton showing the architecture.
 * In production, you would use ethers.js or web3.js with the contract ABIs.
 */

import { useState, useCallback } from 'react'
import { useWeb3Wallet } from './useWeb3Wallet'
import type { CreateBetData } from '@/types'

interface TransactionStatus {
  hash: string | null
  status: 'idle' | 'pending' | 'confirming' | 'success' | 'error'
  error: string | null
}

interface UseBlockchainBetReturn {
  createBet: (betData: CreateBetData) => Promise<{ betId: number; txHash: string | null } | null>
  acceptBet: (betId: number, stakeAmount: number) => Promise<string | null>
  settleBet: (betId: number, winnerId: number) => Promise<string | null>
  txStatus: 'idle' | 'pending' | 'confirming' | 'success' | 'error'
  txHash: string | null
  isProcessing: boolean
}

export const useBlockchainBet = (): UseBlockchainBetReturn => {
  const { walletAddress, isConnected } = useWeb3Wallet()
  const [txStatus, setTxStatus] = useState<TransactionStatus>({
    hash: null,
    status: 'idle',
    error: null
  })

  /**
   * Create a bet on the blockchain
   *
   * Flow:
   * 1. Create bet in backend database (gets local ID)
   * 2. User signs transaction to create bet on blockchain
   * 3. Wait for confirmation
   * 4. Update backend with blockchain bet ID and tx hash
   */
  const createBet = useCallback(async (betData: CreateBetData) => {
    // For MVP: Skip wallet requirement, just create in backend
    // Blockchain integration can be added later

    setTxStatus({ hash: null, status: 'pending', error: null })

    try {
      // Step 1: Create bet in backend database
      const token = localStorage.getItem('access_token')
      const backendResponse = await fetch(`${import.meta.env.VITE_API_URL}/api/v1/bets`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${token}`
        },
        body: JSON.stringify(betData)
      })

      if (!backendResponse.ok) {
        const error = await backendResponse.json()
        throw new Error(error.detail || 'Failed to create bet')
      }

      const bet = await backendResponse.json()
      const localBetId = bet.id

      // For MVP: Simulate blockchain success without actual blockchain interaction
      setTxStatus(prev => ({ ...prev, status: 'confirming' }))

      // Simulate brief confirmation delay
      await new Promise(resolve => setTimeout(resolve, 500))

      setTxStatus({
        hash: null,
        status: 'success',
        error: null
      })

      console.log('[Backend] Bet created:', {
        localBetId,
        betData
      })

      return {
        betId: localBetId,
        txHash: null
      }
    } catch (error: any) {
      console.error('[Backend] Create bet failed:', error)
      setTxStatus({
        hash: null,
        status: 'error',
        error: error.message || 'Failed to create bet'
      })
      throw error
    }
  }, [])

  /**
   * Accept a bet on the blockchain
   *
   * Flow:
   * 1. User signs transaction with stake amount
   * 2. Smart contract locks both parties' funds
   * 3. Wait for confirmation
   * 4. Backend indexer picks up BetMatched event
   */
  const acceptBet = useCallback(async (betId: number, stakeAmount: number) => {
    if (!isConnected || !walletAddress) {
      setTxStatus({
        hash: null,
        status: 'error',
        error: 'Please connect your wallet first'
      })
      return null
    }

    setTxStatus({ hash: null, status: 'pending', error: null })

    try {
      // Pseudocode: Call smart contract
      // const contract = new ethers.Contract(
      //   BET_ESCROW_ADDRESS,
      //   BET_ESCROW_ABI,
      //   signer
      // )

      // const tx = await contract.acceptBet(betId, {
      //   value: ethers.utils.parseEther(stakeAmount.toString())
      // })

      // setTxStatus(prev => ({ ...prev, hash: tx.hash, status: 'confirming' }))

      // // Wait for confirmation
      // await tx.wait()

      // Placeholder for pseudocode
      const mockTxHash = '0xdef456ghi789...'

      setTxStatus({
        hash: mockTxHash,
        status: 'confirming',
        error: null
      })

      // Simulate confirmation delay
      await new Promise(resolve => setTimeout(resolve, 2000))

      setTxStatus({
        hash: mockTxHash,
        status: 'success',
        error: null
      })

      console.log('[Blockchain] Bet accepted:', {
        betId,
        stakeAmount,
        txHash: mockTxHash
      })

      // Notify backend
      // await fetch(`/api/v1/bets/${betId}/accept`, {
      //   method: 'POST',
      //   headers: { 'Content-Type': 'application/json' },
      //   body: JSON.stringify({ tx_hash: tx.hash })
      // })

      return mockTxHash
    } catch (error: any) {
      console.error('[Blockchain] Accept bet failed:', error)

      // Handle user rejection
      if (error.code === 4001) {
        setTxStatus({
          hash: null,
          status: 'error',
          error: 'Transaction rejected by user'
        })
      } else {
        setTxStatus({
          hash: null,
          status: 'error',
          error: error.message || 'Transaction failed'
        })
      }
      return null
    }
  }, [isConnected, walletAddress])

  /**
   * Request oracle settlement for a bet
   *
   * This is typically called automatically after the event ends,
   * but can also be manually triggered by participants.
   */
  const settleBet = useCallback(async (betId: number, winnerId: number) => {
    if (!isConnected || !walletAddress) {
      setTxStatus({
        hash: null,
        status: 'error',
        error: 'Please connect your wallet first'
      })
      return null
    }

    setTxStatus({ hash: null, status: 'pending', error: null })

    try {
      // For automatic settlement, backend calls the oracle
      // For manual settlement (after timeout), users can call directly

      // Pseudocode: Request settlement via backend
      // const response = await fetch(`/api/v1/bets/${betId}/request-settlement`, {
      //   method: 'POST',
      //   headers: { 'Content-Type': 'application/json' },
      //   body: JSON.stringify({ winner_id: winnerId })
      // })

      // const { request_id } = await response.json()

      // Placeholder for pseudocode
      const mockRequestId = 7

      setTxStatus({
        hash: null,
        status: 'confirming',
        error: null
      })

      console.log('[Blockchain] Settlement requested:', {
        betId,
        winnerId,
        requestId: mockRequestId
      })

      // Settlement happens asynchronously via oracle network
      // Frontend can poll for status or listen to WebSocket events

      setTxStatus({
        hash: null,
        status: 'success',
        error: null
      })

      return `request-${mockRequestId}`
    } catch (error: any) {
      console.error('[Blockchain] Settle bet failed:', error)
      setTxStatus({
        hash: null,
        status: 'error',
        error: error.message || 'Settlement request failed'
      })
      return null
    }
  }, [isConnected, walletAddress])

  const isProcessing = txStatus.status === 'pending' || txStatus.status === 'confirming'

  return {
    createBet,
    acceptBet,
    settleBet,
    txStatus: txStatus.status,
    txHash: txStatus.hash,
    isProcessing
  }
}
