'use client';

import { useState, useEffect } from 'react';
import { RefreshCw, Cpu, HardDrive, Archive, Layers, Zap } from 'lucide-react';
import { formatBytes } from '../../../lib/format';
import { ProgressBar } from '../../../components/ProgressBar';

interface VmCategory {
  active: number;
  wired: number;
  compressor: number;
  inactive: number;
  purgeable: number;
  speculative: number;
  free: number;
}

interface GroupedProcess {
  name: string;
  rss: number;
  pctMem: number;
  count: number;
  pids: number[];
}

interface MemoryDrilldownData {
  totalRam: number;
  categories: VmCategory;
  processes: GroupedProcess[];
}

const CATEGORY_META: Record<
  keyof VmCategory,
  { label: string; color: string; description: string }
> = {
  active: {
    label: 'Active',
    color: 'var(--accent-primary)',
    description: 'Pages recently used by apps',
  },
  wired: {
    label: 'Wired',
    color: 'var(--danger)',
    description: 'Kernel & drivers — cannot be paged out',
  },
  compressor: {
    label: 'Compressed',
    color: 'var(--warning)',
    description: 'Pages compressed to save RAM (still counts as used)',
  },
  inactive: {
    label: 'Inactive',
    color: 'var(--accent-secondary)',
    description: 'Recently freed — reclaimable on demand',
  },
  purgeable: {
    label: 'Purgeable',
    color: 'var(--purple)',
    description: 'Cache that macOS can discard immediately',
  },
  speculative: {
    label: 'Speculative',
    color: 'var(--text-tertiary)',
    description: 'Pre-fetched pages — reclaimable',
  },
  free: {
    label: 'Free',
    color: 'var(--success)',
    description: 'Unused pages — immediately available',
  },
};

export function MemoryDrilldown() {
  const [data, setData] = useState<MemoryDrilldownData | null>(null);
  const [loading, setLoading] = useState(true);

  const fetchData = async () => {
    setLoading(true);
    try {
      const res = await fetch('/api/system/memory');
      if (res.ok) setData(await res.json());
    } catch {
      // ignore
    }
    setLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, []);

  if (loading && !data) {
    return (
      <div className="flex items-center justify-center py-6">
        <RefreshCw className="w-4 h-4 animate-spin" style={{ color: 'var(--text-tertiary)' }} />
      </div>
    );
  }
  if (!data) return null;

  const total = data.totalRam;
  const cats = data.categories;
  const appMemory = cats.active + cats.wired + cats.compressor;

  return (
    <div className="space-y-4">
      {/* Category breakdown header */}
      <div className="flex items-center justify-between">
        <span className="text-xs font-semibold" style={{ color: 'var(--text-secondary)' }}>
          Memory Categories (vm_stat)
        </span>
        <button
          onClick={fetchData}
          disabled={loading}
          className="p-1 rounded transition-colors"
          style={{ color: 'var(--text-tertiary)' }}
          title="Refresh"
        >
          <RefreshCw className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`} />
        </button>
      </div>

      {/* Stacked bar */}
      <div
        className="flex w-full h-6 rounded-md overflow-hidden"
        style={{ background: 'var(--surface-muted)' }}
      >
        {(Object.keys(CATEGORY_META) as (keyof VmCategory)[]).map(key => {
          const bytes = cats[key];
          const pct = (bytes / total) * 100;
          if (pct < 0.3) return null;
          const meta = CATEGORY_META[key];
          return (
            <div
              key={key}
              className="h-full flex items-center justify-center text-[9px] font-medium overflow-hidden shrink-0"
              style={{
                width: `${pct}%`,
                background: meta.color,
                color: 'var(--bg-canvas)',
                opacity: 0.85,
              }}
              title={`${meta.label}: ${formatBytes(bytes)} (${pct.toFixed(1)}%)`}
            >
              {pct > 6 ? meta.label : ''}
            </div>
          );
        })}
      </div>

      {/* Legend grid */}
      <div className="grid grid-cols-2 gap-x-4 gap-y-1.5">
        {(Object.keys(CATEGORY_META) as (keyof VmCategory)[]).map(key => {
          const bytes = cats[key];
          const pct = (bytes / total) * 100;
          const meta = CATEGORY_META[key];
          const isApp = key === 'active' || key === 'wired' || key === 'compressor';
          return (
            <div key={key} className="flex items-center justify-between" title={meta.description}>
              <div className="flex items-center gap-1.5">
                <span
                  className="w-2.5 h-2.5 rounded-sm inline-block shrink-0"
                  style={{ background: meta.color, opacity: 0.85 }}
                />
                <span
                  className="text-[11px]"
                  style={{ color: isApp ? 'var(--text-secondary)' : 'var(--text-tertiary)' }}
                >
                  {meta.label}
                </span>
              </div>
              <span className="text-[11px] font-mono" style={{ color: 'var(--text-tertiary)' }}>
                {formatBytes(bytes)}
                <span className="ml-1 text-[9px]">({pct.toFixed(1)}%)</span>
              </span>
            </div>
          );
        })}
      </div>

      {/* Summary line */}
      <div
        className="flex items-center justify-between px-2 py-1.5 rounded-md text-[11px]"
        style={{ background: 'var(--surface-muted)' }}
      >
        <span style={{ color: 'var(--text-secondary)' }}>
          <strong>App memory</strong> (active + wired + compressed)
        </span>
        <span className="font-mono font-semibold" style={{ color: 'var(--text-primary)' }}>
          {formatBytes(appMemory)}
        </span>
      </div>

      {/* Top processes */}
      <div>
        <span className="text-xs font-semibold" style={{ color: 'var(--text-secondary)' }}>
          Top Processes by Memory
        </span>
      </div>
      <div className="space-y-1.5">
        {data.processes.slice(0, 15).map((proc, i) => {
          const pct = (proc.rss / total) * 100;
          const isOllama = proc.name.toLowerCase().includes('ollama');
          const isNode =
            proc.name.toLowerCase().includes('node') || proc.name.toLowerCase().includes('next');
          return (
            <div key={`${proc.name}-${i}`}>
              <div className="flex items-center justify-between mb-0.5">
                <div className="flex items-center gap-1.5 min-w-0">
                  {isOllama ? (
                    <Zap className="w-3 h-3 shrink-0" style={{ color: 'var(--success)' }} />
                  ) : isNode ? (
                    <Layers
                      className="w-3 h-3 shrink-0"
                      style={{ color: 'var(--accent-secondary)' }}
                    />
                  ) : (
                    <Cpu className="w-3 h-3 shrink-0" style={{ color: 'var(--text-tertiary)' }} />
                  )}
                  <span
                    className="text-[11px] font-mono truncate"
                    style={{
                      color: isOllama
                        ? 'var(--success)'
                        : isNode
                          ? 'var(--accent-secondary)'
                          : 'var(--text-secondary)',
                    }}
                  >
                    {proc.name}
                    {proc.count > 1 && (
                      <span style={{ color: 'var(--text-tertiary)' }}> ×{proc.count}</span>
                    )}
                  </span>
                </div>
                <span
                  className="text-[11px] font-mono shrink-0 ml-2"
                  style={{ color: 'var(--text-tertiary)' }}
                >
                  {formatBytes(proc.rss)}
                  <span className="ml-1 text-[9px]">({pct.toFixed(1)}%)</span>
                </span>
              </div>
              <div
                className="h-1.5 rounded-full overflow-hidden"
                style={{ background: 'var(--surface-muted)' }}
              >
                <div
                  className="h-full rounded-full"
                  style={{
                    width: `${Math.max(0.5, pct)}%`,
                    background: isOllama
                      ? 'var(--success)'
                      : isNode
                        ? 'var(--accent-secondary)'
                        : 'var(--accent-primary)',
                    opacity: 0.7,
                  }}
                />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
