import { ArrowLeft, Calendar, GitCommit, User } from 'lucide-react';
import { Link, useParams } from 'react-router-dom';

import { Spinner } from '@/components/ui/spinner';
import { useGitCommit } from '@/hooks/repo/useGitCommit';
import { useGitDiff } from '@/hooks/repo/useGitDiff';
import { timeAgo } from '@/lib/utils';

export function RepoCommitDetailPage() {
  const { workspaceName = '', repoName = '', commitSha = '' } = useParams();

  const { data: commit, isLoading: loadingCommit } = useGitCommit(
    workspaceName,
    repoName,
    commitSha,
  );

  const parentSha = commit?.parent_oids?.[0]?.hex;
  const { data: diff, isLoading: loadingDiff } = useGitDiff(
    workspaceName,
    repoName,
    parentSha || null,
    commitSha,
  );

  if (loadingCommit) {
    return (
      <div className="flex items-center justify-center py-12">
        <Spinner />
      </div>
    );
  }

  if (!commit) {
    return (
      <div className="py-12 text-center">
        <GitCommit className="mx-auto size-5 text-muted-foreground/20" />
        <p className="mt-3 text-[13px] text-muted-foreground">Commit not found</p>
        <Link
          to={`/${workspaceName}/repos/${repoName}/commits`}
          className="mt-2 inline-block text-[13px] text-primary hover:underline"
        >
          Back to commits
        </Link>
      </div>
    );
  }

  const author = commit.author?.identity;
  const authoredDate = commit.authored_at
    ? new Date(commit.authored_at.seconds * 1000).toISOString()
    : null;

  return (
    <div className="space-y-6">
      <Link
        to={`/${workspaceName}/repos/${repoName}/commits`}
        className="inline-flex items-center gap-1.5 text-[13px] text-muted-foreground hover:text-foreground"
      >
        <ArrowLeft className="size-3.5" />
        Back to commits
      </Link>

      <div className="rounded-xl border border-border bg-card p-5">
        <h1 className="text-xl font-semibold text-foreground">{commit.subject}</h1>
        {commit.body && (
          <pre className="mt-3 whitespace-pre-wrap text-[13px] text-muted-foreground">
            {commit.body}
          </pre>
        )}

        <div className="mt-4 flex flex-wrap items-center gap-4 text-[12px] text-muted-foreground">
          {author && (
            <span className="flex items-center gap-1.5">
              <User className="size-3.5" />
              <span className="font-medium text-foreground">{author.name}</span>
              <span>{'<'}{author.email}{'>'}</span>
            </span>
          )}
          {authoredDate && (
            <span className="flex items-center gap-1.5">
              <Calendar className="size-3.5" />
              {timeAgo(authoredDate)}
            </span>
          )}
          <code className="rounded bg-muted px-2 py-0.5 text-[11px]">
            {commit.abbreviated_oid}
          </code>
          {commit.parent_oids.length > 0 && (
            <span className="text-[11px]">
              parent{' '}
              {commit.parent_oids.map((p, i) => (
                <Link
                  key={i}
                  to={`/${workspaceName}/repos/${repoName}/commits/${p.hex.slice(0, 7)}`}
                  className="rounded bg-muted px-1.5 py-0.5 font-mono hover:bg-muted/80"
                >
                  {p.hex.slice(0, 7)}
                </Link>
              ))}
            </span>
          )}
        </div>

        {commit.stats && (
          <div className="mt-3 flex items-center gap-3 text-[12px]">
            <span className="text-green-600">+{commit.stats.additions}</span>
            <span className="text-red-600">-{commit.stats.deletions}</span>
            <span className="text-muted-foreground">{commit.stats.changed_files} files changed</span>
          </div>
        )}
      </div>

      {loadingDiff ? (
        <div className="flex items-center justify-center py-8">
          <Spinner />
        </div>
      ) : diff?.files && diff.files.length > 0 ? (
        <div className="space-y-3">
          {diff.stats && (
            <div className="flex items-center gap-3 text-[12px] text-muted-foreground">
              <span>{diff.stats.changed_files} files changed</span>
              <span className="text-green-600">+{diff.stats.additions}</span>
              <span className="text-red-600">-{diff.stats.deletions}</span>
            </div>
          )}
          {diff.files.map((file, fileIdx) => (
            <div
              key={fileIdx}
              className="overflow-hidden rounded-lg border border-border"
            >
              <div className="flex items-center gap-2 border-b border-border bg-muted/30 px-4 py-2">
                <span className="text-[13px] font-medium text-foreground">{file.new_path}</span>
                <span className="text-[11px] text-green-600">+{file.additions}</span>
                <span className="text-[11px] text-red-600">-{file.deletions}</span>
                {file.binary && (
                  <span className="text-[10px] text-muted-foreground">Binary</span>
                )}
              </div>
              {!file.binary && (
                <div className="overflow-x-auto">
                  {file.hunks.map((hunk, hunkIdx) => (
                    <div key={hunkIdx}>
                      <div className="bg-blue-500/5 px-4 py-1 text-[11px] text-muted-foreground">
                        {hunk.header}
                      </div>
                      {hunk.lines.map((line, lineIdx) => {
                        const lineContent = new TextDecoder().decode(
                          new Uint8Array(line.content),
                        );
                        const isAdd = line.type === 1;
                        const isDel = line.type === 2;
                        return (
                          <div
                            key={lineIdx}
                            className={`flex border-b border-border/30 last:border-b-0 ${
                              isAdd
                                ? 'bg-green-500/10'
                                : isDel
                                  ? 'bg-red-500/10'
                                  : ''
                            }`}
                          >
                            <span className="w-10 shrink-0 select-none px-2 text-right text-[11px] text-muted-foreground/50">
                              {line.old_line > 0 ? line.old_line : ''}
                            </span>
                            <span className="w-10 shrink-0 select-none px-2 text-right text-[11px] text-muted-foreground/50">
                              {line.new_line > 0 ? line.new_line : ''}
                            </span>
                            <pre className="flex-1 px-2 text-[12px]">{lineContent}</pre>
                          </div>
                        );
                      })}
                    </div>
                  ))}
                </div>
              )}
            </div>
          ))}
        </div>
      ) : (
        <div className="py-8 text-center text-[13px] text-muted-foreground">
          No file changes in this commit
        </div>
      )}
    </div>
  );
}
