import type { Component } from 'solid-js';
import { For, Show, createMemo, createSignal, createEffect } from 'solid-js';
import { usePersistentSignal } from '@/hooks/usePersistentSignal';
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
import { useColumnVisibility, type ColumnDef } from '@/hooks/useColumnVisibility';
import type {
  KubernetesCluster,
  KubernetesDeployment,
  KubernetesNode,
  KubernetesPod,
} from '@/types/api';
import { Card } from '@/components/shared/Card';
import { EmptyState } from '@/components/shared/EmptyState';
import { ScrollableTable } from '@/components/shared/ScrollableTable';
import { StatusDot } from '@/components/shared/StatusDot';
import { ColumnPicker } from '@/components/shared/ColumnPicker';
import { formatRelativeTime, formatBytes } from '@/utils/format';
import { DEGRADED_HEALTH_STATUSES, OFFLINE_HEALTH_STATUSES, type StatusIndicator } from '@/utils/status';

interface KubernetesClustersProps {
  clusters: KubernetesCluster[];
}

type ViewMode = 'clusters' | 'nodes' | 'pods' | 'deployments';
type StatusFilter = 'all' | 'healthy' | 'unhealthy';

const normalize = (value?: string | null): string => (value || '').trim().toLowerCase();

const getStatusIndicator = (status: string | undefined | null): StatusIndicator => {
  const normalized = normalize(status);
  if (!normalized) return { variant: 'muted', label: 'Unknown' };
  if (OFFLINE_HEALTH_STATUSES.has(normalized)) return { variant: 'danger', label: 'Offline' };
  if (DEGRADED_HEALTH_STATUSES.has(normalized)) return { variant: 'warning', label: 'Degraded' };
  if (normalized === 'online') return { variant: 'success', label: 'Online' };
  return { variant: 'muted', label: status ?? 'Unknown' };
};

const isPodHealthy = (pod: KubernetesPod): boolean => {
  const phase = normalize(pod.phase);
  if (!phase) return false;
  if (phase !== 'running') return false;

  const containers = pod.containers ?? [];
  if (containers.length === 0) return true;

  return containers.every((container) => {
    if (!container.ready) return false;
    const state = normalize(container.state);
    if (!state) return true;
    return state === 'running';
  });
};

const isDeploymentHealthy = (d: KubernetesDeployment): boolean => {
  const desired = d.desiredReplicas ?? 0;
  if (desired <= 0) return true;
  const available = d.availableReplicas ?? 0;
  const ready = d.readyReplicas ?? 0;
  const updated = d.updatedReplicas ?? 0;
  return available >= desired && ready >= desired && updated >= desired;
};

const getClusterDisplayName = (cluster: KubernetesCluster): string => {
  return cluster.customDisplayName || cluster.displayName || cluster.name || cluster.id;
};

const summarizeNodes = (nodes: KubernetesNode[] | undefined) => {
  const list = nodes ?? [];
  const notReady = list.filter((n) => !n.ready).length;
  const unschedulable = list.filter((n) => !!n.unschedulable).length;
  return { total: list.length, notReady, unschedulable };
};

const summarizePods = (pods: KubernetesPod[] | undefined) => {
  const list = pods ?? [];
  const unhealthy = list.filter((p) => !isPodHealthy(p)).length;
  return { total: list.length, unhealthy };
};

const summarizeDeployments = (deployments: KubernetesDeployment[] | undefined) => {
  const list = deployments ?? [];
  const unhealthy = list.filter((d) => !isDeploymentHealthy(d)).length;
  return { total: list.length, unhealthy };
};

const getPodStatusBadge = (pod: KubernetesPod) => {
  if (isPodHealthy(pod)) {
    return { class: 'bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300', label: 'Running' };
  }
  const phase = normalize(pod.phase);
  if (phase === 'pending') {
    return { class: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300', label: 'Pending' };
  }
  if (phase === 'failed') {
    return { class: 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300', label: 'Failed' };
  }
  if (phase === 'succeeded') {
    return { class: 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300', label: 'Completed' };
  }
  // Check for CrashLoopBackOff or other container issues
  const containers = pod.containers ?? [];
  const crashingContainer = containers.find((c) => c.reason?.toLowerCase().includes('crash'));
  if (crashingContainer) {
    return { class: 'bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300', label: 'CrashLoop' };
  }
  const waitingContainer = containers.find((c) => normalize(c.state) === 'waiting');
  if (waitingContainer) {
    return { class: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300', label: waitingContainer.reason || 'Waiting' };
  }
  return { class: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300', label: pod.phase || 'Unknown' };
};

// Get primary container image (first container)
const getPrimaryImage = (pod: KubernetesPod): string => {
  const containers = pod.containers ?? [];
  if (containers.length === 0) return '—';
  const image = containers[0].image ?? '';
  // Truncate long image names, show just the image:tag part
  const parts = image.split('/');
  return parts[parts.length - 1] || image || '—';
};

// Format age from timestamp
const formatAge = (timestamp?: number | string | null): string => {
  if (!timestamp) return '—';
  const ts = typeof timestamp === 'string' ? Date.parse(timestamp) : timestamp;
  if (isNaN(ts)) return '—';
  return formatRelativeTime(ts);
};

// Column definitions for the pods table
const POD_COLUMNS: ColumnDef[] = [
  { id: 'name', label: 'Pod', priority: 'essential', toggleable: false },
  { id: 'namespace', label: 'Namespace', priority: 'essential', toggleable: true },
  { id: 'cluster', label: 'Cluster', priority: 'primary', toggleable: true },
  { id: 'status', label: 'Status', priority: 'essential', toggleable: false },
  { id: 'ready', label: 'Ready', priority: 'primary', toggleable: true },
  { id: 'restarts', label: 'Restarts', priority: 'primary', toggleable: true },
  { id: 'image', label: 'Image', priority: 'secondary', toggleable: true },
  { id: 'age', label: 'Age', priority: 'primary', toggleable: true },
];

export const KubernetesClusters: Component<KubernetesClustersProps> = (props) => {
  const [search, setSearch] = createSignal('');
  // PERFORMANCE: Debounce search term to prevent jank during rapid typing
  const debouncedSearch = useDebouncedValue(() => search(), 200);
  const [viewMode, setViewMode] = createSignal<ViewMode>('clusters');
  const [statusFilter, setStatusFilter] = createSignal<StatusFilter>('all');
  const [showHidden, setShowHidden] = createSignal(false);
  const [namespaceFilter, setNamespaceFilter] = createSignal<string>('all');

  // Column visibility for pods table
  const podColumns = useColumnVisibility('k8s-pod-columns', POD_COLUMNS);

  // Sorting state with persistence
  type SortKey = 'name' | 'status' | 'namespace' | 'cluster' | 'age' | 'restarts' | 'ready' | 'replicas';
  type SortDir = 'asc' | 'desc';
  const [sortKey, setSortKey] = usePersistentSignal<SortKey>('k8s-sort-key', 'name');
  const [sortDirection, setSortDirection] = usePersistentSignal<SortDir>('k8s-sort-dir', 'asc');

  const toggleSort = (key: SortKey) => {
    if (sortKey() === key) {
      setSortDirection(sortDirection() === 'asc' ? 'desc' : 'asc');
    } else {
      setSortKey(key);
      setSortDirection('asc');
    }
  };

  const sortIndicator = (key: SortKey) => sortKey() === key ? (sortDirection() === 'asc' ? ' ▲' : ' ▼') : '';

  // Search input ref for keyboard focus
  let searchInputRef: HTMLInputElement | undefined;

  // Global keyboard handler - focus search on typing
  createEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement;
      const isInputField =
        target.tagName === 'INPUT' ||
        target.tagName === 'TEXTAREA' ||
        target.tagName === 'SELECT' ||
        target.contentEditable === 'true';

      // Escape clears search
      if (e.key === 'Escape' && searchInputRef) {
        setSearch('');
        searchInputRef.blur();
        return;
      }

      // Focus search on printable character (when not in input field)
      if (!isInputField && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
        searchInputRef?.focus();
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  });

  // Get all unique namespaces for the filter dropdown
  const allNamespaces = createMemo(() => {
    const namespaces = new Set<string>();
    for (const cluster of props.clusters ?? []) {
      if (!showHidden() && cluster.hidden) continue;
      for (const pod of cluster.pods ?? []) {
        if (pod.namespace) namespaces.add(pod.namespace);
      }
      for (const dep of cluster.deployments ?? []) {
        if (dep.namespace) namespaces.add(dep.namespace);
      }
    }
    return Array.from(namespaces).sort();
  });

  // Get all nodes flattened across clusters
  const allNodes = createMemo(() => {
    const clusters = props.clusters ?? [];
    const nodes: Array<{ cluster: KubernetesCluster; node: KubernetesNode }> = [];
    for (const cluster of clusters) {
      if (!showHidden() && cluster.hidden) continue;
      for (const node of cluster.nodes ?? []) {
        nodes.push({ cluster, node });
      }
    }
    return nodes;
  });

  // Get all pods flattened across clusters
  const allPods = createMemo(() => {
    const clusters = props.clusters ?? [];
    const pods: Array<{ cluster: KubernetesCluster; pod: KubernetesPod }> = [];
    for (const cluster of clusters) {
      if (!showHidden() && cluster.hidden) continue;
      for (const pod of cluster.pods ?? []) {
        pods.push({ cluster, pod });
      }
    }
    return pods;
  });

  // Get all deployments flattened across clusters
  const allDeployments = createMemo(() => {
    const clusters = props.clusters ?? [];
    const deps: Array<{ cluster: KubernetesCluster; deployment: KubernetesDeployment }> = [];
    for (const cluster of clusters) {
      if (!showHidden() && cluster.hidden) continue;
      for (const dep of cluster.deployments ?? []) {
        deps.push({ cluster, deployment: dep });
      }
    }
    return deps;
  });

  const visibleClusters = createMemo(() => {
    // PERFORMANCE: Use debounced search term
    const term = debouncedSearch().trim().toLowerCase();
    const clusters = props.clusters ?? [];
    const status = statusFilter();
    const key = sortKey();
    const dir = sortDirection();

    const filtered = clusters
      .filter((cluster) => showHidden() || !cluster.hidden)
      .filter((cluster) => {
        if (status === 'all') return true;
        const clusterStatus = normalize(cluster.status);
        const isHealthy = clusterStatus === 'online';
        if (status === 'healthy') return isHealthy;
        if (status === 'unhealthy') return !isHealthy;
        return true;
      })
      .filter((cluster) => {
        if (!term) return true;
        const haystack = [
          getClusterDisplayName(cluster),
          cluster.id,
          cluster.server ?? '',
          cluster.context ?? '',
          cluster.version ?? '',
        ]
          .join(' ')
          .toLowerCase();
        return haystack.includes(term);
      });

    // Sort clusters
    return filtered.sort((a, b) => {
      let cmp = 0;
      switch (key) {
        case 'name': cmp = getClusterDisplayName(a).localeCompare(getClusterDisplayName(b)); break;
        case 'status': cmp = (normalize(a.status) === 'online' ? 0 : 1) - (normalize(b.status) === 'online' ? 0 : 1); break;
        default: cmp = getClusterDisplayName(a).localeCompare(getClusterDisplayName(b));
      }
      return dir === 'desc' ? -cmp : cmp;
    });
  });

  const filteredNodes = createMemo(() => {
    const term = debouncedSearch().trim().toLowerCase();
    const status = statusFilter();
    const key = sortKey();
    const dir = sortDirection();

    const filtered = allNodes()
      .filter(({ node }) => {
        if (status === 'all') return true;
        const isHealthy = node.ready && !node.unschedulable;
        if (status === 'healthy') return isHealthy;
        if (status === 'unhealthy') return !isHealthy;
        return true;
      })
      .filter(({ cluster, node }) => {
        if (!term) return true;
        const haystack = [
          node.name,
          getClusterDisplayName(cluster),
          node.kubeletVersion ?? '',
          node.osImage ?? '',
          ...(node.roles ?? []),
        ]
          .join(' ')
          .toLowerCase();
        return haystack.includes(term);
      });

    // Sort nodes
    return filtered.sort((a, b) => {
      let cmp = 0;
      switch (key) {
        case 'name': cmp = (a.node.name ?? '').localeCompare(b.node.name ?? ''); break;
        case 'cluster': cmp = getClusterDisplayName(a.cluster).localeCompare(getClusterDisplayName(b.cluster)); break;
        case 'status': cmp = (a.node.ready ? 0 : 1) - (b.node.ready ? 0 : 1); break;
        default: cmp = (a.node.name ?? '').localeCompare(b.node.name ?? '');
      }
      return dir === 'desc' ? -cmp : cmp;
    });
  });

  const filteredPods = createMemo(() => {
    const term = debouncedSearch().trim().toLowerCase();
    const status = statusFilter();
    const ns = namespaceFilter();
    const key = sortKey();
    const dir = sortDirection();

    const filtered = allPods()
      .filter(({ pod }) => {
        if (ns !== 'all' && pod.namespace !== ns) return false;
        if (status === 'all') return true;
        const healthy = isPodHealthy(pod);
        if (status === 'healthy') return healthy;
        if (status === 'unhealthy') return !healthy;
        return true;
      })
      .filter(({ cluster, pod }) => {
        if (!term) return true;
        const haystack = [
          pod.name,
          pod.namespace,
          pod.nodeName ?? '',
          pod.phase ?? '',
          getClusterDisplayName(cluster),
          ...(pod.containers ?? []).map(c => c.image ?? ''),
        ]
          .join(' ')
          .toLowerCase();
        return haystack.includes(term);
      });

    // Sort
    return filtered.sort((a, b) => {
      let cmp = 0;
      switch (key) {
        case 'name': cmp = (a.pod.name ?? '').localeCompare(b.pod.name ?? ''); break;
        case 'namespace': cmp = (a.pod.namespace ?? '').localeCompare(b.pod.namespace ?? ''); break;
        case 'cluster': cmp = getClusterDisplayName(a.cluster).localeCompare(getClusterDisplayName(b.cluster)); break;
        case 'restarts': cmp = (a.pod.restarts ?? 0) - (b.pod.restarts ?? 0); break;
        case 'age': cmp = (a.pod.createdAt ?? 0) - (b.pod.createdAt ?? 0); break;
        case 'status': cmp = (isPodHealthy(a.pod) ? 0 : 1) - (isPodHealthy(b.pod) ? 0 : 1); break;
        default: cmp = (a.pod.name ?? '').localeCompare(b.pod.name ?? '');
      }
      return dir === 'desc' ? -cmp : cmp;
    });
  });

  const filteredDeployments = createMemo(() => {
    const term = debouncedSearch().trim().toLowerCase();
    const status = statusFilter();
    const ns = namespaceFilter();
    const key = sortKey();
    const dir = sortDirection();

    const filtered = allDeployments()
      .filter(({ deployment }) => {
        if (ns !== 'all' && deployment.namespace !== ns) return false;
        if (status === 'all') return true;
        const healthy = isDeploymentHealthy(deployment);
        if (status === 'healthy') return healthy;
        if (status === 'unhealthy') return !healthy;
        return true;
      })
      .filter(({ cluster, deployment }) => {
        if (!term) return true;
        const haystack = [
          deployment.name,
          deployment.namespace,
          getClusterDisplayName(cluster),
        ]
          .join(' ')
          .toLowerCase();
        return haystack.includes(term);
      });

    // Sort
    return filtered.sort((a, b) => {
      let cmp = 0;
      switch (key) {
        case 'name': cmp = (a.deployment.name ?? '').localeCompare(b.deployment.name ?? ''); break;
        case 'namespace': cmp = (a.deployment.namespace ?? '').localeCompare(b.deployment.namespace ?? ''); break;
        case 'cluster': cmp = getClusterDisplayName(a.cluster).localeCompare(getClusterDisplayName(b.cluster)); break;
        case 'replicas': cmp = (a.deployment.desiredReplicas ?? 0) - (b.deployment.desiredReplicas ?? 0); break;
        case 'ready': cmp = (a.deployment.readyReplicas ?? 0) - (b.deployment.readyReplicas ?? 0); break;
        case 'status': cmp = (isDeploymentHealthy(a.deployment) ? 0 : 1) - (isDeploymentHealthy(b.deployment) ? 0 : 1); break;
        default: cmp = (a.deployment.name ?? '').localeCompare(b.deployment.name ?? '');
      }
      return dir === 'desc' ? -cmp : cmp;
    });
  });

  const isEmpty = createMemo(() => (props.clusters?.length ?? 0) === 0);

  const hasActiveFilters = createMemo(
    () => search().trim() !== '' || statusFilter() !== 'all' || showHidden() || namespaceFilter() !== 'all',
  );

  const handleReset = () => {
    setSearch('');
    setStatusFilter('all');
    setShowHidden(false);
    setNamespaceFilter('all');
    setViewMode('clusters');
  };

  return (
    <div class="space-y-4">
      {/* Filter Bar */}
      <Card padding="sm">
        <div class="flex flex-col gap-3">
          {/* Search - full width on its own row */}
          <div class="relative">
            <input
              ref={searchInputRef}
              type="text"
              placeholder="Search clusters, nodes, pods..."
              value={search()}
              onInput={(e) => setSearch(e.currentTarget.value)}
              onKeyDown={(e) => {
                if (e.key === 'Escape') {
                  setSearch('');
                  e.currentTarget.blur();
                }
              }}
              class="w-full pl-9 pr-8 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 dark:focus:border-blue-400 outline-none transition-all"
            />
            <svg
              class="absolute left-3 top-2 h-4 w-4 text-gray-400 dark:text-gray-500"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
              />
            </svg>
            <Show when={search()}>
              <button
                type="button"
                class="absolute right-2 top-1/2 -translate-y-1/2 transform text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
                onClick={() => setSearch('')}
                aria-label="Clear search"
              >
                <svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </Show>
          </div>

          {/* Filters - second row */}
          <div class="flex flex-wrap items-center gap-2">
            {/* View Mode Toggle */}
            <div class="inline-flex rounded-lg bg-gray-100 dark:bg-gray-700 p-0.5">
              <button
                type="button"
                onClick={() => setViewMode('clusters')}
                class={`px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${viewMode() === 'clusters'
                  ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-200 dark:ring-gray-600'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                Clusters
              </button>
              <button
                type="button"
                onClick={() => setViewMode('nodes')}
                class={`px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${viewMode() === 'nodes'
                  ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-200 dark:ring-gray-600'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                Nodes
              </button>
              <button
                type="button"
                onClick={() => setViewMode('pods')}
                class={`px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${viewMode() === 'pods'
                  ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-200 dark:ring-gray-600'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                Pods
              </button>
              <button
                type="button"
                onClick={() => setViewMode('deployments')}
                class={`px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${viewMode() === 'deployments'
                  ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-200 dark:ring-gray-600'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                Deployments
              </button>
            </div>

            <div class="h-5 w-px bg-gray-200 dark:bg-gray-600 hidden sm:block" />

            {/* Status Filter */}
            <div class="inline-flex rounded-lg bg-gray-100 dark:bg-gray-700 p-0.5">
              <button
                type="button"
                onClick={() => setStatusFilter('all')}
                class={`px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${statusFilter() === 'all'
                  ? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-gray-200 dark:ring-gray-600'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                All
              </button>
              <button
                type="button"
                onClick={() => setStatusFilter(statusFilter() === 'healthy' ? 'all' : 'healthy')}
                class={`inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${statusFilter() === 'healthy'
                  ? 'bg-white dark:bg-gray-800 text-green-600 dark:text-green-400 shadow-sm ring-1 ring-green-200 dark:ring-green-800'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                <span class={`w-2 h-2 rounded-full ${statusFilter() === 'healthy' ? 'bg-green-500' : 'bg-green-400/60'}`} />
                Healthy
              </button>
              <button
                type="button"
                onClick={() => setStatusFilter(statusFilter() === 'unhealthy' ? 'all' : 'unhealthy')}
                class={`inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-md transition-all duration-150 active:scale-95 ${statusFilter() === 'unhealthy'
                  ? 'bg-white dark:bg-gray-800 text-amber-600 dark:text-amber-400 shadow-sm ring-1 ring-amber-200 dark:ring-amber-800'
                  : 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
                  }`}
              >
                <span class={`w-2 h-2 rounded-full ${statusFilter() === 'unhealthy' ? 'bg-amber-500' : 'bg-amber-400/60'}`} />
                Unhealthy
              </button>
            </div>

            {/* Namespace Filter - only show for pods/deployments */}
            <Show when={(viewMode() === 'pods' || viewMode() === 'deployments') && allNamespaces().length > 1}>
              <div class="h-5 w-px bg-gray-200 dark:bg-gray-600 hidden sm:block" />
              <select
                value={namespaceFilter()}
                onChange={(e) => setNamespaceFilter(e.currentTarget.value)}
                class="px-2.5 py-1 text-xs font-medium rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500"
              >
                <option value="all">All namespaces</option>
                <For each={allNamespaces()}>
                  {(ns) => <option value={ns}>{ns}</option>}
                </For>
              </select>
            </Show>

            <div class="h-5 w-px bg-gray-200 dark:bg-gray-600 hidden sm:block" />

            {/* Show Hidden Toggle */}
            <label class="flex items-center gap-2 text-xs text-gray-600 dark:text-gray-400 cursor-pointer select-none">
              <input
                type="checkbox"
                checked={showHidden()}
                onChange={(e) => setShowHidden(e.currentTarget.checked)}
                class="rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500/20"
              />
              Show hidden
            </label>

            {/* Column Picker - only show for pods view */}
            <Show when={viewMode() === 'pods'}>
              <div class="h-5 w-px bg-gray-200 dark:bg-gray-600 hidden sm:block" />
              <ColumnPicker
                columns={podColumns.availableToggles()}
                isHidden={podColumns.isHiddenByUser}
                onToggle={podColumns.toggle}
                onReset={podColumns.resetToDefaults}
              />
            </Show>

            {/* Reset Button */}
            <Show when={hasActiveFilters()}>
              <div class="h-5 w-px bg-gray-200 dark:bg-gray-600 hidden sm:block" />
              <button
                type="button"
                onClick={handleReset}
                class="flex items-center justify-center gap-1 px-2.5 py-1 text-xs font-medium rounded-lg text-blue-700 dark:text-blue-300 bg-blue-100 dark:bg-blue-900/50 hover:bg-blue-200 dark:hover:bg-blue-900/70 transition-colors"
                title="Reset filters"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" />
                  <path d="M21 3v5h-5" />
                  <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" />
                  <path d="M8 16H3v5" />
                </svg>
                <span class="hidden sm:inline">Reset</span>
              </button>
            </Show>
          </div>
        </div>
      </Card>

      {/* Main Table */}
      <Card padding="none" class="overflow-hidden">
        <Show
          when={!isEmpty()}
          fallback={
            <div class="p-10">
              <EmptyState
                title="No Kubernetes clusters reporting yet"
                description="Enable Kubernetes monitoring on a unified agent to start reporting cluster health."
              />
            </div>
          }
        >
          {/* Clusters View */}
          <Show when={viewMode() === 'clusters'}>
            <ScrollableTable minWidth="900px" persistKey="kubernetes-clusters-table">
              <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                <thead class="bg-gray-50 dark:bg-gray-900/40">
                  <tr>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('name')}>Cluster{sortIndicator('name')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('status')}>Status{sortIndicator('status')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Nodes</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Pods</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Deployments</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Version</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Last Seen</th>
                  </tr>
                </thead>
                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
                  <For each={visibleClusters()} fallback={
                    <tr><td colSpan={7} class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">No clusters match the current filters.</td></tr>
                  }>
                    {(cluster) => {
                      const indicator = () => getStatusIndicator(cluster.status);
                      const nodes = () => summarizeNodes(cluster.nodes);
                      const pods = () => summarizePods(cluster.pods);
                      const deployments = () => summarizeDeployments(cluster.deployments);

                      return (
                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-900/20">
                          <td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
                            <div class="flex items-center gap-2">
                              <span class="font-medium">{getClusterDisplayName(cluster)}</span>
                              <Show when={cluster.pendingUninstall}>
                                <span class="text-[10px] px-2 py-0.5 rounded-full bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200">
                                  Pending uninstall
                                </span>
                              </Show>
                              <Show when={cluster.hidden}>
                                <span class="text-[10px] px-2 py-0.5 rounded-full bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-200">
                                  Hidden
                                </span>
                              </Show>
                            </div>
                            <div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5 truncate max-w-xs font-mono">
                              {cluster.server || '—'}
                            </div>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <div class="flex items-center gap-2">
                              <StatusDot variant={indicator().variant} size="sm" />
                              <span>{indicator().label}</span>
                            </div>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <span class={nodes().notReady > 0 ? 'text-amber-600 dark:text-amber-400' : ''}>{nodes().total - nodes().notReady}</span>
                            <span class="text-gray-400">/{nodes().total}</span>
                            <Show when={nodes().notReady > 0}>
                              <span class="ml-1 text-xs text-gray-400">ready</span>
                            </Show>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <span class={pods().unhealthy > 0 ? 'text-amber-600 dark:text-amber-400' : ''}>{pods().total - pods().unhealthy}</span>
                            <span class="text-gray-400">/{pods().total}</span>
                            <Show when={pods().unhealthy > 0}>
                              <span class="ml-1 text-xs text-gray-400">healthy</span>
                            </Show>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <span class={deployments().unhealthy > 0 ? 'text-amber-600 dark:text-amber-400' : ''}>{deployments().total - deployments().unhealthy}</span>
                            <span class="text-gray-400">/{deployments().total}</span>
                            <Show when={deployments().unhealthy > 0}>
                              <span class="ml-1 text-xs text-gray-400">ok</span>
                            </Show>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-mono">
                            {cluster.version || '—'}
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            {cluster.lastSeen ? formatRelativeTime(cluster.lastSeen) : '—'}
                          </td>
                        </tr>
                      );
                    }}
                  </For>
                </tbody>
              </table>
            </ScrollableTable>
          </Show>

          {/* Nodes View */}
          <Show when={viewMode() === 'nodes'}>
            <ScrollableTable minWidth="1000px" persistKey="kubernetes-nodes-table">
              <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                <thead class="bg-gray-50 dark:bg-gray-900/40">
                  <tr>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('name')}>Node{sortIndicator('name')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('cluster')}>Cluster{sortIndicator('cluster')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('status')}>Status{sortIndicator('status')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Roles</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">CPU</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Memory</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Pods</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Version</th>
                  </tr>
                </thead>
                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
                  <For each={filteredNodes()} fallback={
                    <tr><td colSpan={8} class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">No nodes match the current filters.</td></tr>
                  }>
                    {({ cluster, node }) => {
                      const isHealthy = () => node.ready && !node.unschedulable;
                      const roles = () => (node.roles ?? []).join(', ') || 'worker';

                      return (
                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-900/20">
                          <td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
                            <div class="font-medium">{node.name}</div>
                            <div class="text-xs text-gray-500 dark:text-gray-400 truncate max-w-xs">
                              {node.osImage || '—'}
                            </div>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            {getClusterDisplayName(cluster)}
                          </td>
                          <td class="px-4 py-3 text-sm">
                            <Show when={isHealthy()} fallback={
                              <span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300">
                                <span class="w-1.5 h-1.5 rounded-full bg-amber-500" />
                                {!node.ready ? 'NotReady' : 'Unschedulable'}
                              </span>
                            }>
                              <span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300">
                                <span class="w-1.5 h-1.5 rounded-full bg-green-500" />
                                Ready
                              </span>
                            </Show>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <span class="px-2 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-xs">
                              {roles()}
                            </span>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-mono">
                            {node.allocatableCpuCores ?? node.capacityCpuCores ?? '—'} cores
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-mono">
                            {node.allocatableMemoryBytes ? formatBytes(node.allocatableMemoryBytes) : node.capacityMemoryBytes ? formatBytes(node.capacityMemoryBytes) : '—'}
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-mono">
                            {node.allocatablePods ?? node.capacityPods ?? '—'}
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-mono">
                            {node.kubeletVersion || '—'}
                          </td>
                        </tr>
                      );
                    }}
                  </For>
                </tbody>
              </table>
            </ScrollableTable>
          </Show>

          {/* Pods View */}
          <Show when={viewMode() === 'pods'}>
            <ScrollableTable minWidth="800px" persistKey="kubernetes-pods-table">
              <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                <thead class="bg-gray-50 dark:bg-gray-900/40">
                  <tr>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('name')}>Pod{sortIndicator('name')}</th>
                    <Show when={podColumns.isColumnVisible('namespace')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('namespace')}>Namespace{sortIndicator('namespace')}</th>
                    </Show>
                    <Show when={podColumns.isColumnVisible('cluster')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('cluster')}>Cluster{sortIndicator('cluster')}</th>
                    </Show>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('status')}>Status{sortIndicator('status')}</th>
                    <Show when={podColumns.isColumnVisible('ready')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('ready')}>Ready{sortIndicator('ready')}</th>
                    </Show>
                    <Show when={podColumns.isColumnVisible('restarts')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('restarts')}>Restarts{sortIndicator('restarts')}</th>
                    </Show>
                    <Show when={podColumns.isColumnVisible('image')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Image</th>
                    </Show>
                    <Show when={podColumns.isColumnVisible('age')}>
                      <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('age')}>Age{sortIndicator('age')}</th>
                    </Show>
                  </tr>
                </thead>
                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
                  <For each={filteredPods()} fallback={
                    <tr><td colSpan={8} class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">No pods match the current filters.</td></tr>
                  }>
                    {({ cluster, pod }) => {
                      const statusBadge = () => getPodStatusBadge(pod);
                      const containers = () => pod.containers ?? [];
                      const readyContainers = () => containers().filter(c => c.ready).length;

                      return (
                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-900/20">
                          <td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
                            <div class="font-medium truncate max-w-[200px]" title={pod.name}>{pod.name}</div>
                            <div class="text-xs text-gray-500 dark:text-gray-400 truncate">
                              {pod.nodeName || 'unscheduled'}
                            </div>
                          </td>
                          <Show when={podColumns.isColumnVisible('namespace')}>
                            <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                              <span class="px-2 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-xs font-mono">
                                {pod.namespace}
                              </span>
                            </td>
                          </Show>
                          <Show when={podColumns.isColumnVisible('cluster')}>
                            <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                              {getClusterDisplayName(cluster)}
                            </td>
                          </Show>
                          <td class="px-4 py-3 text-sm">
                            <span class={`inline-flex px-2 py-0.5 rounded-full text-xs font-medium ${statusBadge().class}`}>
                              {statusBadge().label}
                            </span>
                          </td>
                          <Show when={podColumns.isColumnVisible('ready')}>
                            <td class="px-4 py-3 text-sm">
                              <span class={readyContainers() === containers().length ? 'text-green-600 dark:text-green-400' : 'text-amber-600 dark:text-amber-400'}>
                                {readyContainers()}/{containers().length}
                              </span>
                            </td>
                          </Show>
                          <Show when={podColumns.isColumnVisible('restarts')}>
                            <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                              <Show when={(pod.restarts ?? 0) > 0} fallback={<span class="text-gray-400">0</span>}>
                                <span class="text-amber-600 dark:text-amber-400 font-medium">{pod.restarts}</span>
                              </Show>
                            </td>
                          </Show>
                          <Show when={podColumns.isColumnVisible('image')}>
                            <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                              <span class="font-mono text-xs truncate max-w-[150px] block" title={(pod.containers ?? [])[0]?.image}>
                                {getPrimaryImage(pod)}
                              </span>
                            </td>
                          </Show>
                          <Show when={podColumns.isColumnVisible('age')}>
                            <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 whitespace-nowrap">
                              {formatAge(pod.createdAt)}
                            </td>
                          </Show>
                        </tr>
                      );
                    }}
                  </For>
                </tbody>
              </table>
            </ScrollableTable>
          </Show>

          {/* Deployments View */}
          <Show when={viewMode() === 'deployments'}>
            <ScrollableTable minWidth="800px" persistKey="kubernetes-deployments-table">
              <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                <thead class="bg-gray-50 dark:bg-gray-900/40">
                  <tr>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('name')}>Deployment{sortIndicator('name')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('namespace')}>Namespace{sortIndicator('namespace')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('cluster')}>Cluster{sortIndicator('cluster')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('status')}>Status{sortIndicator('status')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('replicas')}>Replicas{sortIndicator('replicas')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:text-gray-700 dark:hover:text-gray-200" onClick={() => toggleSort('ready')}>Ready{sortIndicator('ready')}</th>
                    <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Up-to-date</th>
                  </tr>
                </thead>
                <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
                  <For each={filteredDeployments()} fallback={
                    <tr><td colSpan={7} class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">No deployments match the current filters.</td></tr>
                  }>
                    {({ cluster, deployment }) => {
                      const healthy = () => isDeploymentHealthy(deployment);
                      const desired = () => deployment.desiredReplicas ?? 0;
                      const ready = () => deployment.readyReplicas ?? 0;
                      const updated = () => deployment.updatedReplicas ?? 0;

                      return (
                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-900/20">
                          <td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
                            <div class="font-medium">{deployment.name}</div>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            <span class="px-2 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-xs font-mono">
                              {deployment.namespace}
                            </span>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300">
                            {getClusterDisplayName(cluster)}
                          </td>
                          <td class="px-4 py-3 text-sm">
                            <Show when={healthy()} fallback={
                              <span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300">
                                <span class="w-1.5 h-1.5 rounded-full bg-amber-500" />
                                Progressing
                              </span>
                            }>
                              <span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300">
                                <span class="w-1.5 h-1.5 rounded-full bg-green-500" />
                                Available
                              </span>
                            </Show>
                          </td>
                          <td class="px-4 py-3 text-sm text-gray-700 dark:text-gray-300 font-medium">
                            {desired()}
                          </td>
                          <td class="px-4 py-3 text-sm">
                            <span class={ready() >= desired() ? 'text-green-600 dark:text-green-400' : 'text-amber-600 dark:text-amber-400'}>
                              {ready()}/{desired()}
                            </span>
                          </td>
                          <td class="px-4 py-3 text-sm">
                            <span class={updated() >= desired() ? 'text-green-600 dark:text-green-400' : 'text-amber-600 dark:text-amber-400'}>
                              {updated()}/{desired()}
                            </span>
                          </td>
                        </tr>
                      );
                    }}
                  </For>
                </tbody>
              </table>
            </ScrollableTable>
          </Show>
        </Show>
      </Card>
    </div>
  );
};
