import {
  Archive,
  BookOpen,
  Code,
  Eye,
  GitBranch,
  GitCommit,
  GitFork,
  GitPullRequest,
  Globe,
  Key,
  Lock,
  Settings,
  Star,
  Tag,
  Users,
  Webhook,
} from 'lucide-react';
import { NavLink, Outlet, useNavigate, useParams } from 'react-router-dom';

import { Spinner } from '@/components/ui/spinner';
import { useRepo } from '@/hooks/repo/useRepo';
import { useRepoStats } from '@/hooks/repo/useRepoStats';
import { useStarRepo, useUnstarRepo } from '@/hooks/repo/useStarRepo';
import { cn } from '@/lib/utils';

export function RepoLayout() {
  const { workspaceName = '', repoName = '' } = useParams();
  const navigate = useNavigate();
  const { data: repo, isLoading, error } = useRepo(workspaceName, repoName);
  const { data: stats } = useRepoStats(workspaceName, repoName);
  const starRepo = useStarRepo();
  const unstarRepo = useUnstarRepo();

  if (isLoading) {
    return (
      <div className="flex items-center gap-2 p-8 text-[14px] text-muted-foreground">
        <Spinner />
        Loading repository...
      </div>
    );
  }

  if (error || !repo) {
    return (
      <div className="flex flex-col items-center justify-center px-8 py-20 text-center">
        <div className="grid size-16 place-items-center rounded-2xl bg-muted/40">
          <Code className="size-7 text-muted-foreground/40" />
        </div>
        <h2 className="mt-5 text-lg font-semibold text-foreground">Repository not found</h2>
        <p className="mt-2 max-w-sm text-[13px] text-muted-foreground">
          This repository doesn't exist or you don't have permission to view it.
        </p>
        <button
          type="button"
          className="mt-4 text-[13px] text-primary hover:underline"
          onClick={() => navigate(`/${workspaceName}/repos`)}
        >
          Back to repositories
        </button>
      </div>
    );
  }

  const base = `/${workspaceName}/repos/${repoName}`;

  const TABS = [
    { label: 'Code', to: '', icon: Code, end: true },
    { label: 'Commits', to: 'commits', icon: GitCommit, end: false },
    { label: 'Branches', to: 'branches', icon: GitBranch, end: false },
    { label: 'Tags', to: 'tags', icon: Tag, end: false },
    { label: 'Releases', to: 'releases', icon: Tag, end: false },
    {
      label: 'Pull Requests',
      to: 'pulls',
      icon: GitPullRequest,
      end: false,
      count: stats?.open_pull_requests_count,
    },
    { label: 'Wiki', to: 'wiki', icon: BookOpen, end: false },
    { label: 'Members', to: 'members', icon: Users, end: false },
    { label: 'Forks', to: 'forks', icon: GitFork, end: false, count: stats?.forks_count },
    { label: 'Stars', to: 'stars', icon: Star, end: false, count: stats?.stars_count },
    { label: 'Watchers', to: 'watchers', icon: Eye, end: false, count: stats?.watchers_count },
    { label: 'Deploy Keys', to: 'deploy-keys', icon: Key, end: false },
    { label: 'Webhooks', to: 'webhooks', icon: Webhook, end: false },
    { label: 'Settings', to: 'settings', icon: Settings, end: false },
  ] as const;

  return (
    <div className="px-6 py-6">
      <div className="flex items-center gap-2 flex-wrap">
        <h1 className="text-lg font-bold text-foreground">{repo.name}</h1>
        <VisibilityBadge visibility={repo.visibility} />
        {repo.archived_at && (
          <span className="inline-flex items-center gap-1 rounded-md border border-border bg-muted/30 px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
            <Archive className="size-3" />
            Archived
          </span>
        )}
        {repo.is_fork && (
          <span className="inline-flex items-center gap-1 rounded-md border border-border bg-muted/30 px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
            <GitFork className="size-3" />
            Fork
          </span>
        )}
        <div className="ml-auto flex items-center gap-1">
          <button
            type="button"
            className="inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[12px] font-medium text-foreground transition-colors hover:bg-muted"
            onClick={() => starRepo.mutate()}
          >
            <Star className="size-3" />
            Star
            {stats?.stars_count != null && (
              <span className="text-muted-foreground">{stats.stars_count}</span>
            )}
          </button>
          <button
            type="button"
            className="inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[12px] font-medium text-foreground transition-colors hover:bg-muted"
            onClick={() => unstarRepo.mutate()}
          >
            <Eye className="size-3" />
            Watch
            {stats?.watchers_count != null && (
              <span className="text-muted-foreground">{stats.watchers_count}</span>
            )}
          </button>
        </div>
      </div>

      {repo.description && (
        <p className="mt-1 max-w-2xl text-[13px] text-muted-foreground">{repo.description}</p>
      )}

      <div className="mt-2 flex items-center gap-3 text-[12px] text-muted-foreground">
        <span>
          <span className="text-foreground/60">default:</span> {repo.default_branch}
        </span>
      </div>

      <nav className="mt-5 flex items-center gap-1 overflow-x-auto rounded-xl border border-border bg-muted/30 p-1">
        {TABS.map((tab) => (
          <NavLink
            key={tab.to}
            to={tab.to === '' ? base : `${base}/${tab.to}`}
            end={'end' in tab && tab.end}
            className={({ isActive }) =>
              cn(
                'inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg px-3 text-[13px] font-medium transition-colors',
                isActive
                  ? 'bg-card text-foreground shadow-sm ring-1 ring-border'
                  : 'text-muted-foreground hover:bg-background/60 hover:text-foreground',
              )
            }
          >
            <tab.icon className="size-3.5" />
            {tab.label}
            {'count' in tab && tab.count != null && tab.count > 0 && (
              <span className="rounded-full bg-muted px-1.5 py-0 text-[10px]">
                {tab.count}
              </span>
            )}
          </NavLink>
        ))}
      </nav>

      <div className="mt-6">
        <Outlet />
      </div>
    </div>
  );
}

function VisibilityBadge({ visibility }: { visibility: string }) {
  const isPrivate = visibility === 'Private';
  return (
    <span className="inline-flex items-center gap-1 rounded-md border border-border bg-muted/30 px-2 py-0.5 text-[11px] font-medium text-muted-foreground">
      {isPrivate ? <Lock className="size-3" /> : <Globe className="size-3" />}
      {visibility}
    </span>
  );
}
