'use client'

import dynamic from 'next/dynamic'
import Link from 'next/link'
import { useState, useCallback, useEffect } from 'react'
import { demoNodes } from '@/lib/presets'
import { detectSafeChains, getBalances, computeTransferSummary } from '@/lib/api/safe-client'
import { safeBalancesToFunnels } from '@/lib/integrations'
import { getFlow, listFlows, syncNodesToBackend, fromSmallestUnit } from '@/lib/api/flows-client'
import type { FlowNode, FunnelNodeData } from '@/lib/types'
import type { BackendFlow } from '@/lib/api/flows-client'

const BudgetRiver = dynamic(() => import('@/components/BudgetRiver'), {
  ssr: false,
  loading: () => (
    <div className="w-full h-full flex items-center justify-center bg-slate-900">
      <div className="flex items-center gap-3">
        <div className="w-8 h-8 border-4 border-cyan-500 border-t-transparent rounded-full animate-spin" />
        <span className="text-slate-400">Loading river view...</span>
      </div>
    </div>
  ),
})

export default function RiverPage() {
  const [mode, setMode] = useState<'demo' | 'live'>('demo')
  const [nodes, setNodes] = useState<FlowNode[]>(demoNodes)
  const [isSimulating, setIsSimulating] = useState(true)
  const [showConnect, setShowConnect] = useState(false)
  const [safeAddress, setSafeAddress] = useState('')
  const [connecting, setConnecting] = useState(false)
  const [connectedChains, setConnectedChains] = useState<string[]>([])
  const [statusMessage, setStatusMessage] = useState<{ text: string; type: 'success' | 'error' } | null>(null)
  const [deployedFlow, setDeployedFlow] = useState<BackendFlow | null>(null)

  // Load saved address
  useEffect(() => {
    if (typeof window === 'undefined') return
    const saved = localStorage.getItem('rfunds-owner-address')
    if (saved) setSafeAddress(saved)
  }, [])

  const showStatus = useCallback((text: string, type: 'success' | 'error') => {
    setStatusMessage({ text, type })
    setTimeout(() => setStatusMessage(null), 4000)
  }, [])

  const handleConnect = useCallback(async () => {
    if (!safeAddress.trim()) return
    setConnecting(true)
    try {
      localStorage.setItem('rfunds-owner-address', safeAddress.trim())
      const detected = await detectSafeChains(safeAddress.trim())
      if (detected.length === 0) {
        showStatus('No Safe found on supported chains (Ethereum, Base, Polygon, Arbitrum, Optimism, Gnosis)', 'error')
        setConnecting(false)
        return
      }

      const chainNames = detected.map(d => d.chain.name)
      setConnectedChains(chainNames)

      // Fetch balances + transfer history from all detected chains
      const allFunnelNodes: FlowNode[] = []
      for (const chain of detected) {
        const [balances, transferSummary] = await Promise.all([
          getBalances(safeAddress.trim(), chain.chainId),
          computeTransferSummary(safeAddress.trim(), chain.chainId),
        ])
        const funnels = safeBalancesToFunnels(
          balances,
          safeAddress.trim(),
          chain.chainId,
          transferSummary,
          { x: allFunnelNodes.length * 280, y: 100 }
        )
        allFunnelNodes.push(...funnels)
      }

      if (allFunnelNodes.length === 0) {
        showStatus('Safe found but no token balances > $1', 'error')
        setConnecting(false)
        return
      }

      setNodes(allFunnelNodes)
      setMode('live')
      setIsSimulating(false)
      setShowConnect(false)
      showStatus(`Connected: ${allFunnelNodes.length} tokens across ${chainNames.join(', ')}`, 'success')
    } catch (err) {
      showStatus(`Connection failed: ${err instanceof Error ? err.message : 'Unknown error'}`, 'error')
    } finally {
      setConnecting(false)
    }
  }, [safeAddress, showStatus])

  const handleLoadFlow = useCallback(async () => {
    if (!safeAddress.trim()) {
      showStatus('Enter a wallet address first', 'error')
      return
    }
    try {
      const flows = await listFlows(safeAddress.trim())
      if (flows.length === 0) {
        showStatus('No deployed flows found for this address', 'error')
        return
      }

      // Load the most recent active flow
      const activeFlow = flows.find(f => f.status === 'active') || flows[0]
      const flow = await getFlow(activeFlow.id)
      setDeployedFlow(flow)

      // Convert backend flow to visual nodes
      const funnelNodes: FlowNode[] = flow.funnels.map((f, i) => ({
        id: f.id,
        type: 'funnel' as const,
        position: { x: i * 280, y: 100 },
        data: {
          label: f.name,
          currentValue: fromSmallestUnit(f.balance),
          minThreshold: fromSmallestUnit(f.minThreshold),
          maxThreshold: fromSmallestUnit(f.maxThreshold),
          maxCapacity: fromSmallestUnit(f.maxThreshold) * 1.5,
          inflowRate: f.inflowRate ? fromSmallestUnit(f.inflowRate) : 0,
          overflowAllocations: f.overflowAllocations.map((a, j) => ({
            targetId: a.targetId,
            percentage: a.percentage,
            color: ['#f59e0b', '#ef4444', '#f97316'][j % 3],
          })),
          spendingAllocations: f.spendingAllocations.map((a, j) => ({
            targetId: a.targetId,
            percentage: a.percentage,
            color: ['#3b82f6', '#8b5cf6', '#ec4899'][j % 3],
          })),
        } as FunnelNodeData,
      }))

      const outcomeNodes: FlowNode[] = flow.outcomes.map((o, i) => ({
        id: o.id,
        type: 'outcome' as const,
        position: { x: i * 250, y: 600 },
        data: {
          label: o.name,
          description: o.description || '',
          fundingReceived: fromSmallestUnit(o.currentAmount),
          fundingTarget: fromSmallestUnit(o.targetAmount),
          status: o.status === 'completed' ? 'completed' as const :
            fromSmallestUnit(o.currentAmount) > 0 ? 'in-progress' as const : 'not-started' as const,
        },
      }))

      setNodes([...funnelNodes, ...outcomeNodes])
      setMode('live')
      setIsSimulating(false)
      showStatus(`Loaded flow "${flow.name}" (${flow.funnels.length} funnels, ${flow.outcomes.length} outcomes)`, 'success')
    } catch (err) {
      showStatus(`Failed to load flow: ${err instanceof Error ? err.message : 'Unknown error'}`, 'error')
    }
  }, [safeAddress, showStatus])

  // Auto-refresh in live mode
  useEffect(() => {
    if (mode !== 'live' || !deployedFlow) return

    const interval = setInterval(async () => {
      try {
        const latest = await getFlow(deployedFlow.id)
        setDeployedFlow(latest)
        setNodes(prev => syncNodesToBackend(prev, latest, Object.fromEntries(
          prev.map(n => [n.id, n.id])
        )))
      } catch {
        // Silent refresh failure
      }
    }, 30000)

    return () => clearInterval(interval)
  }, [mode, deployedFlow])

  const handleSwitchToDemo = useCallback(() => {
    setNodes(demoNodes)
    setMode('demo')
    setIsSimulating(true)
    setDeployedFlow(null)
    setConnectedChains([])
  }, [])

  return (
    <main className="h-screen w-screen flex flex-col bg-slate-900">
      {/* Status Toast */}
      {statusMessage && (
        <div className={`fixed top-16 left-1/2 -translate-x-1/2 z-[60] px-4 py-2 rounded-lg shadow-lg text-sm font-medium ${
          statusMessage.type === 'success' ? 'bg-emerald-600 text-white' : 'bg-red-600 text-white'
        }`}>
          {statusMessage.text}
        </div>
      )}

      {/* Banner */}
      <div className="bg-slate-800 text-white px-4 py-2 flex items-center justify-between text-sm flex-shrink-0 border-b border-slate-700/50">
        <div className="flex items-center gap-3">
          <Link href="/" className="flex items-center gap-2 hover:opacity-80 transition-opacity">
            <div className="w-6 h-6 bg-gradient-to-br from-amber-400 to-emerald-500 rounded flex items-center justify-center font-bold text-slate-900 text-[10px]">
              rF
            </div>
            <span className="font-medium">rFunds</span>
          </Link>
          <span className="text-slate-500">|</span>
          <span className="text-cyan-300 font-medium">Budget River</span>
          {mode === 'live' && connectedChains.length > 0 && (
            <>
              <span className="text-slate-500">|</span>
              <span className="text-xs text-emerald-400">
                {connectedChains.join(' + ')}
              </span>
            </>
          )}
          {deployedFlow && (
            <>
              <span className="text-slate-500">|</span>
              <span className={`text-xs px-2 py-0.5 rounded-full ${
                deployedFlow.status === 'active' ? 'bg-emerald-600/30 text-emerald-300' :
                'bg-amber-600/30 text-amber-300'
              }`}>
                {deployedFlow.status} &middot; {deployedFlow.name}
              </span>
            </>
          )}
        </div>

        <div className="flex items-center gap-2">
          <Link
            href="/tbff"
            className="px-3 py-1 text-slate-400 hover:text-white text-xs transition-colors"
          >
            Canvas View
          </Link>
          <Link
            href="/space"
            className="px-3 py-1 text-slate-400 hover:text-white text-xs transition-colors"
          >
            Editor
          </Link>

          <div className="w-px h-5 bg-slate-600 mx-1" />

          {mode === 'live' ? (
            <button
              onClick={handleSwitchToDemo}
              className="px-3 py-1 bg-slate-600 hover:bg-slate-500 rounded text-xs font-medium transition-colors"
            >
              Demo
            </button>
          ) : (
            <button
              onClick={() => setShowConnect(true)}
              className="px-3 py-1 bg-cyan-600 hover:bg-cyan-500 rounded text-xs font-medium transition-colors"
            >
              Connect Safe
            </button>
          )}

          <button
            onClick={() => setIsSimulating(!isSimulating)}
            className={`px-3 py-1 rounded text-xs font-medium transition-colors ${
              isSimulating
                ? 'bg-emerald-600 hover:bg-emerald-500 text-white'
                : 'bg-slate-700 hover:bg-slate-600 text-slate-300'
            }`}
          >
            {isSimulating ? 'Pause' : 'Simulate'}
          </button>
        </div>
      </div>

      {/* River Canvas */}
      <div className="flex-1 overflow-auto">
        <BudgetRiver nodes={nodes} isSimulating={isSimulating} />
      </div>

      {/* Connect Safe Dialog */}
      {showConnect && (
        <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50" onClick={() => setShowConnect(false)}>
          <div className="bg-slate-800 rounded-xl shadow-2xl p-6 w-96 border border-slate-700" onClick={e => e.stopPropagation()}>
            <h3 className="text-lg font-bold text-white mb-1">Connect Safe Treasury</h3>
            <p className="text-xs text-slate-400 mb-4">
              Enter a Safe address to load real token balances across Ethereum, Base, Polygon, Arbitrum, Optimism, and Gnosis.
            </p>
            <input
              type="text"
              value={safeAddress}
              onChange={e => setSafeAddress(e.target.value)}
              placeholder="Safe address (0x...)"
              className="w-full px-3 py-2 bg-slate-900 border border-slate-600 rounded-lg text-sm text-white font-mono text-xs mb-3 focus:border-cyan-500 focus:outline-none"
              autoFocus
              onKeyDown={e => e.key === 'Enter' && handleConnect()}
            />
            <div className="flex gap-2 mb-3">
              <button
                onClick={handleConnect}
                disabled={!safeAddress.trim() || connecting}
                className="flex-1 px-4 py-2 bg-cyan-600 text-white rounded-lg text-sm font-medium hover:bg-cyan-500 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                {connecting ? 'Connecting...' : 'Connect Safe'}
              </button>
              <button
                onClick={handleLoadFlow}
                disabled={!safeAddress.trim()}
                className="px-4 py-2 bg-violet-600 text-white rounded-lg text-sm font-medium hover:bg-violet-500 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
              >
                Load Flow
              </button>
            </div>
            <button
              onClick={() => setShowConnect(false)}
              className="w-full px-4 py-2 text-slate-400 hover:text-white text-sm border border-slate-600 rounded-lg transition-colors"
            >
              Cancel
            </button>
          </div>
        </div>
      )}

      {/* Legend */}
      <div className="absolute bottom-4 left-4 bg-slate-800/90 backdrop-blur-sm rounded-lg border border-slate-700/50 p-3 text-xs">
        <div className="text-[10px] font-medium text-slate-500 uppercase tracking-wide mb-2">Legend</div>
        <div className="space-y-1.5">
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded bg-emerald-500" />
            <span className="text-slate-400">Source / Inflow</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-1.5 rounded bg-cyan-500" />
            <span className="text-slate-400">River (healthy)</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-1.5 rounded bg-amber-500" />
            <span className="text-slate-400">Overflow branch</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded bg-violet-500" />
            <span className="text-slate-400">Spending outflow</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-md border border-blue-500 bg-blue-500/30" />
            <span className="text-slate-400">Outcome pool</span>
          </div>
        </div>
      </div>
    </main>
  )
}
