import { useState } from 'react';
import { FileCode2, FunctionSquare, Box, Wrench, GitBranch, Code2, Database, RefreshCw } from 'lucide-react';
import { useQueryClient } from '@tanstack/react-query';
import { Card } from '@/components/ui/Card';
import { Panel } from '@/components/ui/Panel';
import { SearchInput } from '@/components/ui/SearchInput';
import { Spinner } from '@/components/ui/Spinner';
import { EmptyState } from '@/components/ui/EmptyState';
import { useCodeStats } from '@/hooks/useCodeStats';
import { useTreemapData } from '@/components/treemap/useTreemapData';
import { useGraphData } from '@/components/graph/useGraphData';
import TreemapCanvas from '@/components/treemap/TreemapCanvas';
import SigmaGraph from '@/components/graph/SigmaGraph';

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function asRecord(data: unknown): Record<string, unknown> | null {
  if (data && typeof data === 'object' && !Array.isArray(data)) {
    return data as Record<string, unknown>;
  }
  return null;
}

function num(value: unknown): number {
  return typeof value === 'number' ? value : 0;
}

function fmt(n: number): string {
  if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
  if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
  return String(n);
}

// ---------------------------------------------------------------------------
// CodePage
// ---------------------------------------------------------------------------

export default function CodePage() {
  const [graphSearch, setGraphSearch] = useState('');
  const queryClient = useQueryClient();

  // Data hooks
  const codeStats = useCodeStats();
  const treemapQuery = useTreemapData();
  const graphQuery = useGraphData();

  // Extract stats
  const stats = asRecord(codeStats.data);
  const files = num(stats?.files);
  const functions = num(stats?.functions);
  const classes = num(stats?.classes);
  const methods = num(stats?.methods);
  const relations = num(stats?.relations);

  // Extract graph data
  const graphData = graphQuery.data ?? { nodes: [], edges: [] };

  const hasNoData =
    !codeStats.isLoading && !codeStats.error && files === 0 && functions === 0 && classes === 0;

  const isRefreshing = codeStats.isFetching || treemapQuery.isFetching || graphQuery.isFetching;

  const handleRefresh = () => {
    queryClient.invalidateQueries({ queryKey: ['code'] });
  };

  return (
    <div className="space-y-6">
      {/* Refresh button */}
      <div className="flex justify-end">
        <button
          onClick={handleRefresh}
          disabled={isRefreshing}
          className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-md border border-border bg-surface text-text-secondary hover:text-text-primary hover:border-accent-blue transition-colors disabled:opacity-50"
        >
          <RefreshCw className={`w-3.5 h-3.5 ${isRefreshing ? 'animate-spin' : ''}`} />
          Refresh
        </button>
      </div>

      {/* Row 1 — Stats Cards */}
      <section>
        {codeStats.isLoading ? (
          <div className="flex items-center justify-center py-8">
            <Spinner size="lg" />
          </div>
        ) : hasNoData ? (
          <EmptyState
            icon={Code2}
            title="No code indexed yet"
            description="Run the indexer to populate code statistics."
          />
        ) : (
          <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
            <Card title="Files" value={codeStats.error ? 'N/A' : fmt(files)} icon={FileCode2} gradient="blue" />
            <Card title="Functions" value={codeStats.error ? 'N/A' : fmt(functions)} icon={FunctionSquare} gradient="blue" />
            <Card title="Classes" value={codeStats.error ? 'N/A' : fmt(classes)} icon={Box} gradient="violet" />
            <Card title="Methods" value={codeStats.error ? 'N/A' : fmt(methods)} icon={Wrench} gradient="green" />
            <Card title="Relations" value={codeStats.error ? 'N/A' : fmt(relations)} icon={GitBranch} gradient="amber" />
          </div>
        )}
      </section>

      {/* Row 2 — Treemap + Graph */}
      <section className="grid grid-cols-1 lg:grid-cols-5 gap-4">
        {/* Left: Treemap (60%) */}
        <div className="lg:col-span-3">
          <Panel title="Directory Structure">
            {treemapQuery.isLoading ? (
              <div className="flex items-center justify-center py-8">
                <Spinner size="lg" />
              </div>
            ) : treemapQuery.error || !treemapQuery.data ? (
              <EmptyState
                icon={Database}
                title="No directory data"
                description="Index a codebase to see the directory treemap."
              />
            ) : (
              <TreemapCanvas data={treemapQuery.data} height={400} />
            )}
          </Panel>
        </div>

        {/* Right: Entity Graph (40%) */}
        <div className="lg:col-span-2">
          <Panel
            title="Entity Graph"
            actions={
              <SearchInput
                value={graphSearch}
                onChange={setGraphSearch}
                placeholder="Filter nodes..."
              />
            }
          >
            {graphQuery.isLoading ? (
              <div className="flex items-center justify-center py-8">
                <Spinner size="lg" />
              </div>
            ) : graphQuery.error || graphData.nodes.length === 0 ? (
              <EmptyState
                icon={GitBranch}
                title="No graph data"
                description="Index a codebase to see the entity graph."
              />
            ) : (
              <SigmaGraph
                nodes={graphData.nodes}
                edges={graphData.edges}
                searchQuery={graphSearch}
                height="400px"
              />
            )}
          </Panel>
        </div>
      </section>
    </div>
  );
}
