import { Link, useSearchParams } from 'react-router';
import { Loader2, Check, CircleSlash, AlertTriangle, PauseCircle } from 'lucide-react';
import { useAppStore, type StoreItem } from './useAppStore';

// The list of everything installable, with what has happened to each.
//
// Rows are real links carrying `?selected=<id>`, per docs/navigation-audit.md: the selection is
// addressable, so it belongs in the URL rather than a panel channel. That is what makes cmd-click,
// middle-click and a pasted link all work, and what stops this list and the detail pane disagreeing.

/** One glyph for the whole state, because "installed but the process died" has to be visible at a glance. */
function StatusBadge({ item }: { item: StoreItem }) {
  const { status, enabled } = item.install;

  if (status === 'not-installed') return null;
  if (status === 'installing') {
    return <Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground" aria-label="installing" />;
  }
  if (status === 'failed') return <AlertTriangle className="h-3.5 w-3.5 text-destructive" aria-label="failed" />;
  // Blocked is not a failure: everything worked and it is waiting for something only a person can give.
  if (status === 'blocked') return <PauseCircle className="h-3.5 w-3.5 text-amber-500" aria-label="needs you" />;
  if (!enabled) return <CircleSlash className="h-3.5 w-3.5 text-muted-foreground" aria-label="disabled" />;

  // Installed and enabled, but the process is not running — the case worth surfacing rather than
  // showing a tick that lies.
  if (item.processStatus && item.processStatus !== 'online') {
    return <AlertTriangle className="h-3.5 w-3.5 text-amber-500" aria-label={item.processStatus} />;
  }
  return <Check className="h-3.5 w-3.5 text-emerald-500" aria-label="installed" />;
}

export const AppStoreList = () => {
  const { items, isLoading, error } = useAppStore();
  const [params] = useSearchParams();
  const selected = params.get('selected');

  if (isLoading) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        <Loader2 className="mr-2 h-4 w-4 animate-spin" /> Loading
      </div>
    );
  }
  if (error) {
    // Distinguished from "nothing installable", which would otherwise look identical and is not a
    // problem the user can act on.
    return <div className="p-4 text-sm text-destructive">Could not load the app store.</div>;
  }

  const installed = items.filter((i) => i.install.status !== 'not-installed');
  const available = items.filter((i) => i.install.status === 'not-installed');

  const Row = ({ item }: { item: StoreItem }) => (
    <Link
      to={`?selected=${item.id}`}
      className={`flex items-center gap-2 rounded-md px-3 py-2 text-sm transition-colors hover:bg-accent ${
        selected === item.id ? 'bg-accent' : ''
      }`}
    >
      <span className="min-w-0 flex-1 truncate">{item.label}</span>
      <StatusBadge item={item} />
    </Link>
  );

  return (
    <div className="flex h-full flex-col overflow-y-auto p-2">
      {installed.length > 0 && (
        <>
          <div className="px-3 py-1 text-xs font-medium uppercase tracking-wide text-muted-foreground">Installed</div>
          {installed.map((item) => (
            <Row key={item.id} item={item} />
          ))}
        </>
      )}
      <div className="mt-2 px-3 py-1 text-xs font-medium uppercase tracking-wide text-muted-foreground">Available</div>
      {available.map((item) => (
        <Row key={item.id} item={item} />
      ))}
    </div>
  );
};
