import { useState, useRef, useEffect } from 'react';
import {
  Send, Sparkles, Wrench, ShieldCheck, Route, FileText,
  Landmark, AlertTriangle, BookOpen, ChevronDown, Plus,
  Zap, RefreshCw, FileOutput, MessageSquare,
  History, Target
} from 'lucide-react';
import type { Agent, ChatMessage, ConversationScope, ComponentItem } from '../types';
import { sampleMessages, sampleThreads } from '../data/sampleData';
import { componentItems } from '../data/components';
import type { Node, Edge } from '@xyflow/react';

const agents: { id: Agent; icon: typeof Sparkles; color: string }[] = [
  { id: 'Builder', icon: Sparkles, color: '#3b82f6' },
  { id: 'Compliance', icon: ShieldCheck, color: '#22c55e' },
  { id: 'Routing', icon: Route, color: '#f97316' },
  { id: 'ISO-20022', icon: FileText, color: '#a855f7' },
  { id: 'Settlement', icon: Landmark, color: '#eab308' },
  { id: 'Risk', icon: AlertTriangle, color: '#ef4444' },
  { id: 'Documentation', icon: BookOpen, color: '#6b7280' },
];

interface RightPanelProps {
  width: number;
  nodes: Node[];
  edges: Edge[];
  selectedNodes: Node[];
  chatInputRef: React.RefObject<HTMLInputElement | null>;
  onInsertBlock: (item: ComponentItem, position: { x: number; y: number }) => void;
  onRunValidation: () => void;
  onOptimizeRoute: () => void;
  onRunCompliance: () => void;
  onGenerateSettlement: () => void;
}

export default function RightPanel({
  width, nodes, edges, selectedNodes, chatInputRef,
  onInsertBlock, onRunValidation, onOptimizeRoute, onRunCompliance, onGenerateSettlement,
}: RightPanelProps) {
  const [activeAgent, setActiveAgent] = useState<Agent>('Builder');
  const [messages, setMessages] = useState<ChatMessage[]>(sampleMessages);
  const [input, setInput] = useState('');
  const [showAgentMenu, setShowAgentMenu] = useState(false);
  const [showContext, setShowContext] = useState(false);
  const [showThreads, setShowThreads] = useState(false);
  const [scope, setScope] = useState<ConversationScope>('full-transaction');
  const [showScopeMenu, setShowScopeMenu] = useState(false);
  const messagesEnd = useRef<HTMLDivElement>(null);

  useEffect(() => {
    messagesEnd.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const getCanvasContext = () => {
    const nodeLabels = nodes.map(n => (n.data as Record<string, unknown>).label as string);
    const categories = [...new Set(nodes.map(n => (n.data as Record<string, unknown>).category as string))];
    const hasCompliance = categories.includes('compliance');
    const hasRouting = categories.includes('routing');
    const disconnected = nodes.filter(n => !edges.some(e => e.source === n.id || e.target === n.id));
    const selectedLabels = selectedNodes.map(n => (n.data as Record<string, unknown>).label as string);
    return { nodeLabels, categories, hasCompliance, hasRouting, disconnected, selectedLabels, nodeCount: nodes.length, edgeCount: edges.length };
  };

  const sendMessage = () => {
    if (!input.trim()) return;
    const userMsg: ChatMessage = {
      id: Date.now().toString(),
      agent: 'User',
      content: input,
      timestamp: new Date(),
      type: 'user',
    };
    setMessages(prev => [...prev, userMsg]);
    const capturedInput = input;
    setInput('');

    setTimeout(() => {
      const ctx = getCanvasContext();
      const buildResponse = (): string => {
        const lowerInput = capturedInput.toLowerCase();

        switch (activeAgent) {
          case 'Builder': {
            if (selectedNodes.length > 0) {
              const sel = (selectedNodes[0].data as Record<string, unknown>).label as string;
              if (lowerInput.includes('explain')) return `The "${sel}" block ${getBlockExplanation(sel)}. It currently has ${edges.filter(e => e.source === selectedNodes[0].id || e.target === selectedNodes[0].id).length} connection(s).`;
              if (lowerInput.includes('next') || lowerInput.includes('suggest')) return `After "${sel}", I recommend adding a ${suggestNextBlock(sel)}. This would complete the ${(selectedNodes[0].data as Record<string, unknown>).category} flow.`;
            }
            if (lowerInput.includes('build') || lowerInput.includes('create') || lowerInput.includes('set up') || lowerInput.includes('payment')) {
              if (ctx.nodeCount === 0) return `To build a transaction flow, start by dragging a "Fiat Account" or "Stablecoin Wallet" from the left panel as your source. Then add a "${capturedInput.includes('swap') ? 'Swap' : 'Transfer'}" action and connect them.`;
              return `Your graph has ${ctx.nodeCount} nodes. Try dragging a "${capturedInput.includes('swap') ? 'Swap' : 'Transfer'}" block onto the canvas and connecting it to your source.`;
            }
            if (ctx.disconnected.length > 0) return `I notice ${ctx.disconnected.length} disconnected node(s) in your graph: ${ctx.disconnected.map(n => (n.data as Record<string, unknown>).label).join(', ')}. Connect them to complete the flow.`;
            return `I can help you build that flow. Try dragging a "${capturedInput.includes('swap') ? 'Swap' : 'Transfer'}" block onto the canvas and connecting it to your source. Your graph currently has ${ctx.nodeCount} nodes and ${ctx.edgeCount} connections.`;
          }
          case 'Compliance': {
            if (lowerInput.includes('check') || lowerInput.includes('compliance') || lowerInput.includes('review')) {
              if (!ctx.hasCompliance && ctx.nodeCount > 0) return `WARNING: Your transaction graph has ${ctx.nodeCount} nodes but no compliance checks. I recommend adding KYC and AML nodes before the settlement step. This is required for cross-border transactions.`;
              if (ctx.hasCompliance) return `Running compliance check on the current graph. No policy violations detected for the selected jurisdiction. ${ctx.nodeCount} nodes verified against 47 compliance rules.`;
              return `Running compliance check on the current graph. No policy violations detected for the selected jurisdiction.`;
            }
            if (lowerInput.includes('violation') || lowerInput.includes('failure')) return `Scanning graph for policy violations... ${ctx.hasCompliance ? 'All compliance nodes are properly configured. No violations found.' : 'No compliance nodes found in graph. Consider adding KYC/AML checks.'}`;
            return `Running compliance check on the current graph. No policy violations detected for the selected jurisdiction.`;
          }
          case 'Routing': {
            if (ctx.hasRouting) return `Analyzing ${ctx.nodeCount} nodes with routing configuration. Found optimal path via ${ctx.nodeLabels.find(l => l.includes('Route') || l.includes('Router')) || 'Banking Rail'}. Estimated fee: 0.02%, latency: 230ms.`;
            return `Analyzing optimal routes... Found 3 execution paths. The best route via Banking Rail offers lowest fees at 0.02%. Your graph has ${ctx.nodeCount} nodes across ${ctx.edgeCount} connections.`;
          }
          case 'ISO-20022': {
            if (ctx.nodeCount > 0) return `Based on your graph with ${ctx.nodeCount} nodes, I can generate a pain.001 message. The required fields from your current configuration: debtor (${ctx.nodeLabels[0] || 'source'}), creditor (${ctx.nodeLabels[ctx.nodeLabels.length - 1] || 'destination'}), amount, and currency.`;
            return `I can generate a pain.001 message for this transfer. The required fields based on your current graph are: debtor, creditor, amount, and currency.`;
          }
          case 'Settlement': {
            return `Current settlement window for this transaction type is T+1. ${ctx.nodeCount > 0 ? `Your graph has ${ctx.nodeCount} nodes ready for settlement processing.` : 'I recommend adding a settlement instruction block to specify your preferred CSD.'}`;
          }
          case 'Risk': {
            if (ctx.nodeCount > 0) {
              const riskLevel = ctx.hasCompliance ? 'LOW' : 'MEDIUM';
              return `Risk assessment: ${riskLevel}. ${ctx.nodeCount} nodes evaluated. ${ctx.hasCompliance ? 'Compliance checks present.' : 'No compliance nodes — risk elevated.'} ${ctx.disconnected.length > 0 ? `${ctx.disconnected.length} disconnected node(s) detected.` : 'All nodes connected.'}`;
            }
            return `Risk assessment: LOW. Transaction amount is within normal parameters. No counterparty risk flags detected.`;
          }
          case 'Documentation': {
            if (ctx.nodeCount > 0) return `Generating deal memo for "${ctx.nodeLabels[0]}" flow with ${ctx.nodeCount} nodes. Categories: ${ctx.categories.join(', ')}. ${ctx.edgeCount} connections mapped. ${ctx.hasCompliance ? 'Compliance: verified.' : 'Compliance: not yet added.'}`;
            return `I'll generate a deal memo for this transaction. It will include the execution path, compliance checks, and settlement instructions.`;
          }
          default:
            return 'How can I assist you?';
        }
      };

      const reply: ChatMessage = {
        id: (Date.now() + 1).toString(),
        agent: activeAgent,
        content: buildResponse(),
        timestamp: new Date(),
        type: 'agent',
      };
      setMessages(prev => [...prev, reply]);
    }, 800);
  };

  const currentAgentDef = agents.find(a => a.id === activeAgent)!;
  const CurrentIcon = currentAgentDef.icon;

  const scopeLabels: Record<ConversationScope, string> = {
    'current-node': 'Current Node',
    'current-flow': 'Current Flow',
    'full-transaction': 'Full Transaction',
    'terminal': 'Terminal',
    'compliance': 'Compliance Only',
  };

  // Context from canvas
  const ctx = getCanvasContext();

  const handleInsertBlock = () => {
    const suggestions = ['transfer', 'kyc', 'banking-rail'];
    const item = componentItems.find(c => c.id === suggestions[Math.floor(Math.random() * suggestions.length)]);
    if (item) onInsertBlock(item, { x: 250 + Math.random() * 200, y: 150 + Math.random() * 200 });
  };

  return (
    <div className="right-panel" style={{ width }}>
      <div className="panel-header">
        <div className="chat-header-agent" onClick={() => setShowAgentMenu(!showAgentMenu)}>
          <CurrentIcon size={14} color={currentAgentDef.color} />
          <span>{activeAgent} Agent</span>
          <ChevronDown size={12} />
          {showAgentMenu && (
            <div className="agent-dropdown">
              {agents.map(a => {
                const Icon = a.icon;
                return (
                  <div
                    key={a.id}
                    className={`agent-option ${a.id === activeAgent ? 'active' : ''}`}
                    onClick={(e) => { e.stopPropagation(); setActiveAgent(a.id); setShowAgentMenu(false); }}
                  >
                    <Icon size={14} color={a.color} />
                    <span>{a.id}</span>
                  </div>
                );
              })}
            </div>
          )}
        </div>
        <div className="chat-header-actions">
          <div className="scope-selector" onClick={() => setShowScopeMenu(!showScopeMenu)}>
            <Target size={11} />
            <span>{scopeLabels[scope]}</span>
            <ChevronDown size={10} />
            {showScopeMenu && (
              <div className="scope-dropdown">
                {(Object.keys(scopeLabels) as ConversationScope[]).map(s => (
                  <div
                    key={s}
                    className={`scope-option ${s === scope ? 'active' : ''}`}
                    onClick={e => { e.stopPropagation(); setScope(s); setShowScopeMenu(false); }}
                  >
                    {scopeLabels[s]}
                  </div>
                ))}
              </div>
            )}
          </div>
          <button
            className={`icon-btn-xs ${showThreads ? 'active' : ''}`}
            onClick={() => setShowThreads(!showThreads)}
            title="Thread History"
          >
            <History size={12} />
          </button>
          <button
            className={`context-toggle ${showContext ? 'active' : ''}`}
            onClick={() => setShowContext(!showContext)}
            title="Toggle context panel"
          >
            Context
          </button>
        </div>
      </div>

      <div className="agent-tabs">
        {agents.map(a => {
          const Icon = a.icon;
          return (
            <button
              key={a.id}
              className={`agent-tab ${a.id === activeAgent ? 'active' : ''}`}
              onClick={() => setActiveAgent(a.id)}
              title={a.id}
              style={a.id === activeAgent ? { borderBottomColor: a.color } : {}}
            >
              <Icon size={13} color={a.id === activeAgent ? a.color : '#666'} />
            </button>
          );
        })}
      </div>

      {showThreads && (
        <div className="thread-history">
          <div className="thread-history-header">Thread History</div>
          {sampleThreads.map(t => (
            <div key={t.id} className="thread-item" onClick={() => setShowThreads(false)}>
              <MessageSquare size={12} color={agents.find(a => a.id === t.agent)?.color} />
              <div className="thread-item-content">
                <span className="thread-item-title">{t.title}</span>
                <span className="thread-item-meta">{t.agent} · {t.messageCount} messages</span>
              </div>
            </div>
          ))}
        </div>
      )}

      {showContext && (
        <div className="context-panel">
          <div className="context-section">
            <span className="context-label">Selected</span>
            <span className="context-value">{ctx.selectedLabels.length > 0 ? ctx.selectedLabels.join(', ') : 'None'}</span>
          </div>
          <div className="context-section">
            <span className="context-label">Nodes</span>
            <span className="context-value">{ctx.nodeCount}</span>
          </div>
          <div className="context-section">
            <span className="context-label">Connections</span>
            <span className="context-value">{ctx.edgeCount}</span>
          </div>
          <div className="context-section">
            <span className="context-label">Jurisdiction</span>
            <span className="context-value">Multi</span>
          </div>
          <div className="context-section">
            <span className="context-label">Counterparties</span>
            <span className="context-value">{ctx.nodeCount > 0 ? Math.max(1, Math.floor(ctx.nodeCount / 3)) : 0}</span>
          </div>
          <div className="context-section">
            <span className="context-label">Compliance</span>
            <span className={`context-value ${ctx.hasCompliance ? 'pass' : (ctx.nodeCount > 0 ? 'warn' : '')}`}>
              {ctx.hasCompliance ? 'Pass' : (ctx.nodeCount > 0 ? 'Missing' : 'N/A')}
            </span>
          </div>
          <div className="context-section">
            <span className="context-label">Categories</span>
            <span className="context-value">{ctx.categories.length > 0 ? ctx.categories.join(', ') : '—'}</span>
          </div>
          <div className="context-section">
            <span className="context-label">Est. Fees</span>
            <span className="context-value">{ctx.nodeCount > 0 ? '$0.02%' : '—'}</span>
          </div>
        </div>
      )}

      <div className="chat-messages">
        {messages.map(msg => (
          <div key={msg.id} className={`chat-message ${msg.type}`}>
            <div className="message-header">
              <span className="message-agent">{msg.agent}</span>
              <span className="message-time">
                {msg.timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
              </span>
            </div>
            <div className="message-content">{msg.content}</div>
          </div>
        ))}
        <div ref={messagesEnd} />
      </div>

      <div className="action-tray">
        <button className="action-tray-btn" title="Insert recommended block" onClick={handleInsertBlock}>
          <Plus size={12} /> Insert Block
        </button>
        <button className="action-tray-btn" title="Repair graph" onClick={onRunValidation}>
          <Wrench size={12} /> Repair
        </button>
        <button className="action-tray-btn" title="Optimize route" onClick={onOptimizeRoute}>
          <Zap size={12} /> Optimize
        </button>
        <button className="action-tray-btn" title="Run compliance" onClick={onRunCompliance}>
          <ShieldCheck size={12} /> Comply
        </button>
        <button className="action-tray-btn" title="Generate settlement message" onClick={onGenerateSettlement}>
          <FileOutput size={12} /> Settle
        </button>
        <button className="action-tray-btn" title="Refresh context" onClick={() => setShowContext(true)}>
          <RefreshCw size={12} />
        </button>
      </div>

      <div className="chat-input-area">
        <input
          ref={chatInputRef}
          type="text"
          placeholder={`Ask ${activeAgent} Agent...`}
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && sendMessage()}
        />
        <button className="send-btn" onClick={sendMessage} disabled={!input.trim()}>
          <Send size={14} />
        </button>
      </div>
    </div>
  );
}

function getBlockExplanation(label: string): string {
  const explanations: Record<string, string> = {
    'Fiat Account': 'represents a traditional fiat currency account, typically used as a source or destination for fund transfers',
    'Transfer': 'moves value from one account to another along a defined path',
    'KYC': 'performs Know Your Customer verification before allowing the transaction to proceed',
    'AML': 'runs Anti-Money Laundering screening against watchlists',
    'Swap': 'exchanges one asset type for another at the current market rate',
    'Banking Rail': 'routes the transaction through traditional banking infrastructure',
  };
  return explanations[label] || 'is a transaction primitive used in flow composition';
}

function suggestNextBlock(label: string): string {
  const suggestions: Record<string, string> = {
    'Fiat Account': 'Transfer or Convert block',
    'Transfer': 'KYC compliance check',
    'KYC': 'AML screening node',
    'AML': 'Banking Rail or DEX Route',
    'Swap': 'Settlement instruction',
    'Banking Rail': 'Settlement instruction',
  };
  return suggestions[label] || 'compliance or routing node';
}
