import type { GiteaRepo } from './shared';
import { useState } from 'react';
import { Link } from 'react-router';
import { ChevronLeft, ChevronRight, Download, ExternalLink, GitBranch, Package, Shield, Tag } from 'lucide-react';
import { DataRow, RelativeTime } from '@/components/Data';
import { Avatar, EmptyState, ErrorState, Loading } from './GiteaBits';
import { GiteaMarkdown } from './GiteaMarkdown';
import { commitTitle, formatBytes, giteaRepoPath, shortSha } from './shared';
import { useGiteaBranches, useGiteaCommits, useGiteaReleases, useGiteaTags } from './useGiteaData';

// The three history tabs — commits, branches (with tags) and releases. Grouped in one file because each is
// a single list with no detail screen behind it, and splitting them would be three files of forty lines.

type TabProps = { repo: GiteaRepo; owner: string; name: string; refName: string };

// ── Commits ───────────────────────────────────────────────────────────────────────────────────────

export const RepoCommitsView = ({ owner, name, refName }: TabProps) => {
  // Paging is component state, not a URL param: the ref and the repo are what make a commit list
  // addressable, and "which page of the scrollback" is not something worth a history entry.
  const [page, setPage] = useState(1);
  const { data: commits, isLoading, error } = useGiteaCommits({ owner, repo: name }, { ref: refName, page });

  if (isLoading) return <Loading label="Loading commits…" />;
  if (error) return <ErrorState title="Could not load commits" error={error} />;
  if (!commits?.length) return <EmptyState title="No commits" />;

  return (
    <div className="flex h-full flex-col">
      <div className="min-h-0 flex-1 overflow-y-auto">
        <div className="divide-y">
          {commits.map((commit) => (
            <DataRow
              key={commit.sha}
              lead={<Avatar user={commit.author} size={24} />}
              title={commitTitle(commit.commit.message)}
              meta={[
                commit.author?.login ?? commit.commit.author?.name ?? 'unknown',
                <RelativeTime value={commit.commit.author?.date ?? commit.created} prefix="committed" />,
              ]}
              trail={
                <a
                  href={commit.html_url}
                  target="_blank"
                  rel="noreferrer"
                  className="rounded-md border px-1.5 py-0.5 font-mono text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
                  title="Open commit in Gitea"
                >
                  {shortSha(commit.sha)}
                </a>
              }
            />
          ))}
        </div>
      </div>

      {/* Gitea's commit list gives no total, so paging is "was this page full?" rather than a page count. */}
      <div className="flex items-center justify-between border-t px-4 py-2 text-xs">
        <button
          type="button"
          disabled={page === 1}
          onClick={() => setPage((p) => Math.max(1, p - 1))}
          className="inline-flex items-center gap-1 rounded-md border px-2 py-1 transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40"
        >
          <ChevronLeft className="h-3 w-3" /> Newer
        </button>
        <span className="tabular-nums text-muted-foreground">Page {page}</span>
        <button
          type="button"
          disabled={commits.length < 30}
          onClick={() => setPage((p) => p + 1)}
          className="inline-flex items-center gap-1 rounded-md border px-2 py-1 transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-40"
        >
          Older <ChevronRight className="h-3 w-3" />
        </button>
      </div>
    </div>
  );
};

// ── Branches and tags ─────────────────────────────────────────────────────────────────────────────

export const RepoBranchesView = ({ repo, owner, name }: TabProps) => {
  const { data: branches, isLoading, error } = useGiteaBranches({ owner, repo: name });
  const { data: tags } = useGiteaTags({ owner, repo: name });

  if (isLoading) return <Loading label="Loading branches…" />;
  if (error) return <ErrorState title="Could not load branches" error={error} />;

  return (
    <div className="h-full overflow-y-auto">
      <SectionTitle icon={GitBranch} label={`Branches${branches?.length ? ` (${branches.length})` : ''}`} />
      <div className="divide-y">
        {(branches ?? []).map((branch) => (
          <DataRow
            key={branch.name}
            to={giteaRepoPath(owner, name, { tab: 'code', ref: branch.name })}
            lead={<GitBranch className="h-4 w-4 text-muted-foreground" />}
            title={
              <>
                <span className="truncate text-sm font-medium">{branch.name}</span>
                {branch.name === repo.default_branch && (
                  <span className="rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary">
                    default
                  </span>
                )}
                {branch.protected && (
                  <span title="Protected" className="flex shrink-0 items-center">
                    <Shield className="h-3.5 w-3.5 text-warning" aria-label="Protected" />
                  </span>
                )}
              </>
            }
            description={branch.commit?.message ? commitTitle(branch.commit.message) : undefined}
            trail={
              <span className="text-xs text-muted-foreground">
                <RelativeTime value={branch.commit?.timestamp} />
              </span>
            }
          />
        ))}
      </div>

      {!!tags?.length && (
        <>
          <SectionTitle icon={Tag} label={`Tags (${tags.length})`} />
          <div className="divide-y">
            {tags.map((tag) => (
              <Link
                key={tag.name}
                to={giteaRepoPath(owner, name, { tab: 'code', ref: tag.name })}
                className="flex items-center gap-3 px-4 py-2 transition-colors hover:bg-muted/50"
              >
                <Tag className="h-4 w-4 shrink-0 text-muted-foreground" />
                <span className="min-w-0 flex-1 truncate text-sm">{tag.name}</span>
                <span className="shrink-0 font-mono text-xs text-muted-foreground">{shortSha(tag.commit?.sha)}</span>
              </Link>
            ))}
          </div>
        </>
      )}
    </div>
  );
};

// ── Releases ──────────────────────────────────────────────────────────────────────────────────────

export const RepoReleasesView = ({ repo, owner, name }: TabProps) => {
  const { data: releases, isLoading, error } = useGiteaReleases({ owner, repo: name });

  if (isLoading) return <Loading label="Loading releases…" />;
  if (error) return <ErrorState title="Could not load releases" error={error} />;
  if (!releases?.length) {
    return <EmptyState title="No releases" hint="Tags become releases once one is published against them." />;
  }

  return (
    <div className="h-full overflow-y-auto">
      <div className="flex flex-col gap-3 p-4">
        {releases.map((release) => (
          <div key={release.id} className="overflow-hidden rounded-lg border">
            <div className="flex flex-wrap items-center gap-2 border-b bg-muted/40 px-3 py-2">
              <Package className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
              <span className="text-sm font-medium">{release.name || release.tag_name}</span>
              <code className="rounded bg-muted px-1.5 py-0.5 font-mono text-xs">{release.tag_name}</code>
              {release.prerelease && (
                <span className="rounded-full bg-warning/15 px-2 py-0.5 text-xs font-medium text-warning">
                  Pre-release
                </span>
              )}
              {release.draft && (
                <span className="rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground">
                  Draft
                </span>
              )}
              <span className="ml-auto flex items-center gap-2 text-xs text-muted-foreground">
                <RelativeTime value={release.published_at ?? release.created_at} />
                <a href={release.html_url} target="_blank" rel="noreferrer" className="hover:text-foreground">
                  <ExternalLink className="h-3.5 w-3.5" />
                </a>
              </span>
            </div>

            {release.body?.trim() && (
              <div className="px-3 py-2">
                <GiteaMarkdown
                  content={release.body}
                  repoUrl={repo.html_url}
                  refName={release.tag_name}
                  className="text-sm"
                />
              </div>
            )}

            {!!release.assets?.length && (
              <div className="divide-y border-t">
                {release.assets.map((asset) => (
                  <a
                    key={asset.id}
                    href={asset.browser_download_url}
                    target="_blank"
                    rel="noreferrer"
                    className="flex items-center gap-2 px-3 py-2 text-sm transition-colors hover:bg-muted/50"
                  >
                    <Download className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                    <span className="min-w-0 flex-1 truncate">{asset.name}</span>
                    <span className="shrink-0 tabular-nums text-muted-foreground">{formatBytes(asset.size)}</span>
                  </a>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
};

const SectionTitle = ({ icon: Icon, label }: { icon: typeof GitBranch; label: string }) => (
  <div className="flex items-center gap-2 border-b bg-muted/30 px-4 py-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
    <Icon className="h-3.5 w-3.5" />
    {label}
  </div>
);
