import { useState, useMemo, lazy, Suspense } from 'react';
import { Link } from 'react-router-dom';
import { Layers, ZoomIn, ZoomOut, RefreshCw, Box, Grid3X3 } from 'lucide-react';
import { useDag } from '../hooks/useApi';
import { truncateHash } from '../lib/utils';
import { cn } from '../lib/utils';

// Lazy load 3D component for better initial page load
const DAGVisualization3D = lazy(() => import('../components/DAGVisualization3D'));

type ViewMode = '2d' | '3d';

export default function DAG() {
  const [depth, setDepth] = useState(15);
  const [viewMode, setViewMode] = useState<ViewMode>('3d');
  const { data, isLoading, error, refetch } = useDag(depth);

  const visualization = useMemo(() => {
    if (!data) return null;

    // Group blocks by blue score for layout
    const scoreGroups = new Map<number, typeof data.blocks>();
    data.blocks.forEach((block) => {
      const group = scoreGroups.get(block.blueScore) || [];
      group.push(block);
      scoreGroups.set(block.blueScore, group);
    });

    // Sort scores descending (newest first)
    const sortedScores = Array.from(scoreGroups.keys()).sort((a, b) => b - a);

    return { scoreGroups, sortedScores };
  }, [data]);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="p-2 rounded-lg bg-synor-900/50">
            <Layers size={24} className="text-synor-400" />
          </div>
          <div>
            <h1 className="text-2xl font-bold">DAG Visualization</h1>
            <p className="text-sm text-gray-400">
              Visualize the block DAG structure
            </p>
          </div>
        </div>

        {/* Controls */}
        <div className="flex items-center gap-2">
          {/* View mode toggle */}
          <div className="flex items-center bg-gray-800 rounded-lg p-1 mr-2">
            <button
              onClick={() => setViewMode('2d')}
              className={cn(
                'px-3 py-1.5 rounded-md text-sm font-medium transition-colors flex items-center gap-1.5',
                viewMode === '2d'
                  ? 'bg-synor-600 text-white'
                  : 'text-gray-400 hover:text-white'
              )}
              title="2D View"
            >
              <Grid3X3 size={16} />
              2D
            </button>
            <button
              onClick={() => setViewMode('3d')}
              className={cn(
                'px-3 py-1.5 rounded-md text-sm font-medium transition-colors flex items-center gap-1.5',
                viewMode === '3d'
                  ? 'bg-synor-600 text-white'
                  : 'text-gray-400 hover:text-white'
              )}
              title="3D View"
            >
              <Box size={16} />
              3D
            </button>
          </div>

          <button
            onClick={() => setDepth(Math.max(5, depth - 5))}
            className="btn btn-secondary p-2"
            title="Show fewer blocks"
          >
            <ZoomOut size={18} />
          </button>
          <span className="px-3 text-sm text-gray-400">{depth} blocks</span>
          <button
            onClick={() => setDepth(Math.min(50, depth + 5))}
            className="btn btn-secondary p-2"
            title="Show more blocks"
          >
            <ZoomIn size={18} />
          </button>
          <button
            onClick={() => refetch()}
            className={cn('btn btn-secondary p-2 ml-2', isLoading && 'animate-spin')}
            disabled={isLoading}
            title="Refresh"
          >
            <RefreshCw size={18} />
          </button>
        </div>
      </div>

      {/* DAG Visualization */}
      {isLoading ? (
        <DAGSkeleton />
      ) : error ? (
        <div className="card p-6 text-red-400">
          Error loading DAG: {error.message}
        </div>
      ) : data ? (
        viewMode === '3d' ? (
          /* 3D Visualization */
          <div className="card overflow-hidden">
            <div className="card-header">
              <div className="flex items-center justify-between">
                <span className="text-sm text-gray-400">
                  {data.blocks.length} blocks, {data.edges.length} edges
                </span>
                <div className="flex items-center gap-4 text-sm">
                  <div className="flex items-center gap-2">
                    <div className="w-3 h-3 rounded-full bg-violet-500" />
                    <span className="text-gray-400">Chain Block</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-3 h-3 rounded-full bg-blue-500" />
                    <span className="text-gray-400">Blue Block</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-3 h-3 rounded-full bg-red-500" />
                    <span className="text-gray-400">Red Block</span>
                  </div>
                </div>
              </div>
            </div>
            <Suspense fallback={<DAGSkeleton />}>
              <DAGVisualization3D data={data} />
            </Suspense>
          </div>
        ) : visualization ? (
          /* 2D Visualization (original) */
          <div className="card overflow-hidden">
            <div className="card-header">
              <div className="flex items-center justify-between">
                <span className="text-sm text-gray-400">
                  {data.blocks.length} blocks, {data.edges.length} edges
                </span>
                <div className="flex items-center gap-4 text-sm">
                  <div className="flex items-center gap-2">
                    <div className="w-3 h-3 rounded-full bg-synor-500" />
                    <span className="text-gray-400">Chain Block</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-3 h-3 rounded-full bg-blue-500" />
                    <span className="text-gray-400">Blue Block</span>
                  </div>
                </div>
              </div>
            </div>
            <div className="p-4 overflow-x-auto scrollbar-thin">
              <div className="min-w-[800px]">
                {visualization.sortedScores.map((score) => {
                  const blocks = visualization.scoreGroups.get(score) || [];
                  return (
                    <div key={score} className="flex items-center gap-4 mb-3">
                      <div className="w-20 text-right text-sm text-gray-500">
                        {score.toLocaleString()}
                      </div>
                      <div className="flex items-center gap-2 flex-wrap">
                        {blocks.map((block) => (
                          <Link
                            key={block.hash}
                            to={`/block/${block.hash}`}
                            className={cn(
                              'group relative px-3 py-2 rounded-lg border transition-all',
                              block.isChainBlock
                                ? 'bg-synor-900/50 border-synor-700 hover:border-synor-500'
                                : block.isBlue
                                ? 'bg-blue-900/30 border-blue-800 hover:border-blue-600'
                                : 'bg-red-900/30 border-red-800 hover:border-red-600'
                            )}
                            title={block.hash}
                          >
                            <span className="font-mono text-xs">
                              {block.shortHash}
                            </span>
                            {block.txCount > 0 && (
                              <span className="ml-2 text-xs text-gray-500">
                                {block.txCount} tx
                              </span>
                            )}
                            {/* Tooltip */}
                            <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-gray-800 rounded-lg shadow-lg opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-10 whitespace-nowrap">
                              <div className="text-xs text-gray-400">
                                Blue Score: {block.blueScore}
                              </div>
                              <div className="hash text-xs mt-1">
                                {truncateHash(block.hash, 16, 16)}
                              </div>
                            </div>
                          </Link>
                        ))}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        ) : null
      ) : null}

      {/* Legend */}
      <div className="card p-4">
        <h3 className="font-semibold mb-3">Understanding the DAG</h3>
        <div className="grid sm:grid-cols-2 gap-4 text-sm text-gray-400">
          <div>
            <p className="font-medium text-gray-200 mb-1">Blue Score</p>
            <p>
              The vertical position represents the block's blue score in the GHOSTDAG
              protocol. Higher scores indicate more recent blocks.
            </p>
          </div>
          <div>
            <p className="font-medium text-gray-200 mb-1">Block Types</p>
            <ul className="list-disc list-inside space-y-1">
              <li>Chain blocks form the main chain (selected chain)</li>
              <li>Blue blocks are honest blocks that contribute to consensus</li>
              <li>Red blocks are potentially malicious or delayed blocks</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}

function DAGSkeleton() {
  return (
    <div className="card p-4 animate-pulse">
      <div className="space-y-4">
        {Array.from({ length: 10 }).map((_, i) => (
          <div key={i} className="flex items-center gap-4">
            <div className="w-20 h-4 bg-gray-800 rounded" />
            <div className="flex gap-2">
              {Array.from({ length: Math.floor(Math.random() * 3) + 1 }).map((_, j) => (
                <div key={j} className="w-20 h-8 bg-gray-800 rounded-lg" />
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
