import type { LucideIcon } from 'lucide-react';
import type { GiteaRepo } from './shared';
import { Archive, GitFork, Lock, Star } from 'lucide-react';
import { DataList, DataRow, MetaItem, RelativeTime } from '@/components/Data';
import { EmptyState, ErrorState, Loading } from './GiteaBits';
import { giteaRepoPath } from './shared';
import { useGiteaRepos } from './useGiteaData';

// The repositories the stored token can see. Rows are real links into /gitea/repo/:owner/:name — cmd-click,
// middle-click and the back button all work, which is the whole point of keeping the selection in the URL.

export const RepositoriesView = () => {
  const { data: repos, isLoading, error } = useGiteaRepos();

  if (isLoading) return <Loading label="Loading repositories…" />;
  if (error) return <ErrorState title="Could not list repositories" error={error} />;
  if (!repos?.length) {
    return (
      <EmptyState
        title="No repositories"
        hint="This token cannot see any repositories. If that is a surprise, check that it was granted the read:repository scope."
      />
    );
  }

  return (
    <DataList>
      {repos.map((repo) => (
        <RepoRow key={repo.id} repo={repo} />
      ))}
    </DataList>
  );
};

/**
 * A bare attribute icon. The wrapping span exists for the tooltip — lucide takes no `title`, and an
 * unlabelled icon is precisely what the icon language means by "if it needs explanation it is too
 * complicated". A tooltip is the cheap repair when the icon has to stay for density.
 */
const Flag = ({ icon: Icon, label, tone }: { icon: LucideIcon; label: string; tone?: string }) => (
  <span title={label} className="flex shrink-0 items-center">
    <Icon className={`h-3.5 w-3.5 ${tone ?? 'text-muted-foreground'}`} aria-label={label} />
  </span>
);

/**
 * `owner.login` rather than splitting `full_name` on the slash: a repository name cannot contain a slash but
 * relying on that to parse an identifier is the kind of assumption that breaks quietly.
 */
export const RepoRow = ({ repo }: { repo: GiteaRepo }) => {
  const owner = repo.owner?.login ?? repo.full_name.split('/')[0] ?? '';

  return (
    <DataRow
      to={giteaRepoPath(owner, repo.name)}
      title={
        <>
          {/* The owner is context, the name is the focal point — one weight per row, so the prefix
              recedes rather than competing with the thing being scanned for. */}
          <span className="truncate text-sm">
            <span className="text-muted-foreground">{owner}/</span>
            <span className="font-medium">{repo.name}</span>
          </span>
          {repo.private && <Flag icon={Lock} label="Private" />}
          {repo.fork && <Flag icon={GitFork} label="Fork" />}
          {repo.archived && <Flag icon={Archive} label="Archived" tone="text-warning" />}
        </>
      }
      description={repo.description}
      meta={[
        repo.language,
        !!repo.stars_count && <MetaItem icon={Star}>{repo.stars_count}</MetaItem>,
        !!repo.forks_count && <MetaItem icon={GitFork}>{repo.forks_count}</MetaItem>,
        repo.updated_at && <RelativeTime value={repo.updated_at} prefix="updated" />,
      ]}
    />
  );
};
