import { Link, NavLink } from 'react-router';
import { Archive, ArrowLeft, ExternalLink, GitFork, Lock, Star } from 'lucide-react';
import { EmptyState, ErrorState, Loading } from './GiteaBits';
import { RepoCodeView } from './RepoCodeView';
import { RepoIssuesView } from './RepoIssuesView';
import { RepoPullsView } from './RepoPullsView';
import { RepoBranchesView, RepoCommitsView, RepoReleasesView } from './RepoHistoryViews';
import { GITEA_REPO_TABS, giteaRepoPath, giteaSectionPath } from './shared';
import { useGiteaLocation } from './useGiteaLocation';
import { useGiteaRepo } from './useGiteaData';

// One repository: the identity header, the tab strip, and whichever tab the URL names.
//
// The ref is resolved HERE rather than in each tab, because ?ref= is legitimately absent on a first visit
// and every tab would otherwise need the same "fall back to the repo's default branch" dance. Tabs receive
// a ref that is always a real branch name.

export const RepoView = () => {
  const { owner, repo: name, tab, item, path, refName } = useGiteaLocation();
  const { data: repo, isLoading, error } = useGiteaRepo({ owner: owner ?? '', repo: name ?? '' });

  if (!owner || !name) return <EmptyState title="No repository selected" />;
  if (isLoading) return <Loading label={`Loading ${owner}/${name}…`} />;
  if (error) return <ErrorState title={`Could not open ${owner}/${name}`} error={error} />;
  if (!repo) return <EmptyState title={`${owner}/${name} not found`} />;

  const effectiveRef = refName ?? repo.default_branch ?? 'main';
  const tabProps = { repo, owner, name, refName: effectiveRef };

  return (
    <div className="flex h-full flex-col">
      <div className="border-b px-4 pt-3">
        <Link
          to={giteaSectionPath('repositories')}
          className="mb-2 inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground"
        >
          <ArrowLeft className="h-3.5 w-3.5" />
          All repositories
        </Link>

        <div className="flex items-start gap-2">
          <h2 className="flex min-w-0 flex-1 flex-wrap items-center gap-1.5 text-base leading-snug">
            {/* Same weight split as the list row: the owner is context and the name is the subject, so
                the two screens agree about what this repository is called. */}
            <span className="truncate">
              <span className="font-normal text-muted-foreground">{repo.owner?.login ?? ''}/</span>
              <span className="font-semibold">{repo.name}</span>
            </span>
            {repo.private && <Lock className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />}
            {repo.fork && <GitFork className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />}
            {repo.archived && <Archive className="h-3.5 w-3.5 shrink-0 text-warning" />}
          </h2>
          <a
            href={repo.html_url}
            target="_blank"
            rel="noreferrer"
            className="shrink-0 text-muted-foreground hover:text-foreground"
            title="Open in Gitea"
          >
            <ExternalLink className="h-4 w-4" />
          </a>
        </div>

        {repo.description && <p className="mt-1 text-sm text-muted-foreground">{repo.description}</p>}

        <div className="mt-2 flex flex-wrap items-center gap-3 text-xs tabular-nums text-muted-foreground">
          {repo.language && <span>{repo.language}</span>}
          {!!repo.stars_count && (
            <span className="flex items-center gap-1.5">
              <Star className="h-3.5 w-3.5" />
              {repo.stars_count}
            </span>
          )}
          {!!repo.forks_count && (
            <span className="flex items-center gap-1.5">
              <GitFork className="h-3.5 w-3.5" />
              {repo.forks_count}
            </span>
          )}
          {repo.website && (
            <a href={repo.website} target="_blank" rel="noreferrer" className="text-primary hover:underline">
              {repo.website.replace(/^https?:\/\//, '')}
            </a>
          )}
        </div>

        <nav className="-mb-px mt-2 flex gap-1 overflow-x-auto">
          {GITEA_REPO_TABS.filter((entry) => {
            // Mirror what the instance has switched on. Gitea hides the Issues tab when a repo has issues
            // disabled, and a tab that always 404s is worse than no tab.
            if (entry.id === 'issues') return repo.has_issues !== false;
            if (entry.id === 'pulls') return repo.has_pull_requests !== false;
            if (entry.id === 'releases') return repo.has_releases !== false;
            return true;
          }).map((entry) => (
            <NavLink
              key={entry.id}
              to={giteaRepoPath(owner, name, { tab: entry.id, ref: refName ?? undefined })}
              end={false}
              className={() =>
                `whitespace-nowrap border-b-2 px-3 py-2 text-sm transition-colors ${
                  entry.id === tab
                    ? 'border-primary font-medium text-primary'
                    : 'border-transparent text-muted-foreground hover:text-foreground'
                }`
              }
            >
              {entry.label}
              {entry.id === 'issues' && !!repo.open_issues_count && (
                <span className="ml-1.5 rounded-full bg-muted px-1.5 py-0.5 text-xs tabular-nums">
                  {repo.open_issues_count}
                </span>
              )}
              {entry.id === 'pulls' && !!repo.open_pr_counter && (
                <span className="ml-1.5 rounded-full bg-muted px-1.5 py-0.5 text-xs tabular-nums">
                  {repo.open_pr_counter}
                </span>
              )}
            </NavLink>
          ))}
        </nav>
      </div>

      <div className="min-h-0 flex-1">
        {tab === 'issues' ? (
          <RepoIssuesView repo={repo} owner={owner} name={name} item={item} />
        ) : tab === 'pulls' ? (
          <RepoPullsView repo={repo} owner={owner} name={name} item={item} />
        ) : tab === 'commits' ? (
          <RepoCommitsView {...tabProps} />
        ) : tab === 'branches' ? (
          <RepoBranchesView {...tabProps} />
        ) : tab === 'releases' ? (
          <RepoReleasesView {...tabProps} />
        ) : (
          <RepoCodeView repo={repo} owner={owner} name={name} path={path} refName={effectiveRef} />
        )}
      </div>
    </div>
  );
};
