import {
  ArrowLeft,
  Circle,
  CircleCheck,
  CircleDot,
  FileCode,
  GitBranch,
  GitMerge,
  GitPullRequest,
  MessageSquare,
  Send,
} from 'lucide-react';
import { useState } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';

import { Spinner } from '@/components/ui/spinner';
import { useClosePr } from '@/hooks/pull-request/useClosePr';
import { useCreateReview } from '@/hooks/pull-request/useCreateReview';
import { useMergePr } from '@/hooks/pull-request/useMergePr';
import { usePrDetail } from '@/hooks/pull-request/usePrDetail';
import { usePrFiles } from '@/hooks/pull-request/usePrFiles';
import { usePrReviews } from '@/hooks/pull-request/usePrReviews';
import { useReopenPr } from '@/hooks/pull-request/useReopenPr';
import { cn, timeAgo } from '@/lib/utils';

export function RepoPrDetailPage() {
  const { workspaceName = '', repoName = '', prNumber } = useParams();
  const navigate = useNavigate();
  const number = Number(prNumber);

  const { data: pr, isLoading, error } = usePrDetail(workspaceName, repoName, number);
  const { data: files } = usePrFiles(workspaceName, repoName, number);
  const { data: reviews } = usePrReviews(workspaceName, repoName, number);

  const mergePr = useMergePr(workspaceName, repoName, number);
  const closePr = useClosePr(workspaceName, repoName, number);
  const reopenPr = useReopenPr(workspaceName, repoName, number);
  const createReview = useCreateReview();

  const [commentBody, setCommentBody] = useState('');
  const [activeTab, setActiveTab] = useState<'files' | 'reviews'>('files');

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

  if (error || !pr) {
    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">
          <GitPullRequest className="size-7 text-muted-foreground/40" />
        </div>
        <h2 className="mt-5 text-lg font-semibold text-foreground">Pull request not found</h2>
        <p className="mt-2 max-w-sm text-[13px] text-muted-foreground">
          This pull request doesn't exist or you don't have permission to view it.
        </p>
        <Link
          to={`/${workspaceName}/repos/${repoName}/pulls`}
          className="mt-4 text-[13px] text-primary hover:underline"
        >
          Back to pull requests
        </Link>
      </div>
    );
  }

  const isMerged = !!pr.merged_at;
  const isClosed = pr.state === 'Closed' || isMerged;
  const isOpen = !isClosed;

  const handleMerge = () => {
    if (confirm('Merge this pull request?')) {
      mergePr.mutate(
        {},
        { onSuccess: () => navigate(`/${workspaceName}/repos/${repoName}/pulls`) },
      );
    }
  };

  const handleClose = () => {
    if (confirm('Close this pull request?')) {
      closePr.mutate();
    }
  };

  const handleReopen = () => {
    reopenPr.mutate();
  };

  const handleComment = () => {
    if (!commentBody.trim()) return;
    createReview.mutate(
      {
        number,
        body: commentBody.trim(),
        state: 'Commented',
      },
      {
        onSuccess: () => setCommentBody(''),
      },
    );
  };

  const handleApprove = () => {
    createReview.mutate({
      number,
      body: commentBody.trim() || undefined,
      state: 'Approved',
    });
    setCommentBody('');
  };

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

      <div>
        <div className="flex items-start gap-3">
          <div className="mt-1 shrink-0">
            {isMerged ? (
              <GitMerge className="size-6 text-purple-500" />
            ) : isClosed ? (
              <CircleDot className="size-6 text-red-500" />
            ) : (
              <Circle className="size-6 text-green-500" />
            )}
          </div>
          <div className="min-w-0 flex-1">
            <h1 className="text-xl font-semibold text-foreground">
              {pr.title}
              <span className="ml-2 text-[14px] font-normal text-muted-foreground">
                #{pr.number}
              </span>
            </h1>
            <div className="mt-2 flex items-center gap-3 text-[13px] text-muted-foreground">
              <span
                className={cn(
                  'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-[12px] font-medium',
                  isMerged
                    ? 'bg-purple-500/10 text-purple-600'
                    : isClosed
                      ? 'bg-red-500/10 text-red-600'
                      : 'bg-green-500/10 text-green-600',
                )}
              >
                {isMerged ? 'Merged' : isClosed ? 'Closed' : 'Open'}
              </span>
              {pr.draft && (
                <span className="rounded border border-border bg-muted/30 px-2 py-0.5 text-[11px] text-muted-foreground">
                  Draft
                </span>
              )}
              {pr.author && (
                <span>
                  opened by <span className="font-medium text-foreground">{pr.author.username}</span>
                </span>
              )}
              <span>{timeAgo(pr.created_at)}</span>
            </div>
          </div>
        </div>
      </div>

      <div className="flex items-center gap-3 rounded-xl border border-border bg-card p-4">
        <GitBranch className="size-4 text-muted-foreground" />
        <span className="text-[13px] font-medium text-foreground">{pr.source_branch}</span>
        <span className="text-muted-foreground">→</span>
        <span className="text-[13px] font-medium text-foreground">{pr.target_branch}</span>
      </div>

      {pr.body && (
        <div className="rounded-xl border border-border bg-card p-5">
          <div className="prose prose-sm max-w-none text-[14px] text-foreground whitespace-pre-wrap">
            {pr.body}
          </div>
        </div>
      )}

      <div className="flex items-center gap-1 border-b border-border">
        <button
          type="button"
          onClick={() => setActiveTab('files')}
          className={cn(
            'flex items-center gap-1.5 border-b-2 px-4 py-2.5 text-[13px] font-medium transition-colors',
            activeTab === 'files'
              ? 'border-primary text-foreground'
              : 'border-transparent text-muted-foreground hover:text-foreground',
          )}
        >
          <FileCode className="size-3.5" />
          Files changed
          {files && files.length > 0 && (
            <span className="ml-1 rounded-full bg-muted px-2 py-0.5 text-[11px]">
              {files.length}
            </span>
          )}
        </button>
        <button
          type="button"
          onClick={() => setActiveTab('reviews')}
          className={cn(
            'flex items-center gap-1.5 border-b-2 px-4 py-2.5 text-[13px] font-medium transition-colors',
            activeTab === 'reviews'
              ? 'border-primary text-foreground'
              : 'border-transparent text-muted-foreground hover:text-foreground',
          )}
        >
          <MessageSquare className="size-3.5" />
          Reviews
          {reviews && reviews.length > 0 && (
            <span className="ml-1 rounded-full bg-muted px-2 py-0.5 text-[11px]">
              {reviews.length}
            </span>
          )}
        </button>
      </div>

      {activeTab === 'files' && (
        <div className="space-y-2">
          {files && files.length > 0 ? (
            files.map((file) => (
              <div
                key={file.id}
                className="flex items-center gap-3 rounded-lg border border-border bg-card px-4 py-2.5"
              >
                <FileCode className="size-4 shrink-0 text-muted-foreground" />
                <span className="min-w-0 flex-1 truncate text-[13px] text-foreground">
                  {file.path}
                </span>
                <span
                  className={cn(
                    'text-[12px] font-medium',
                    file.status === 'Added'
                      ? 'text-green-600'
                      : file.status === 'Deleted'
                        ? 'text-red-600'
                        : file.status === 'Renamed'
                          ? 'text-amber-600'
                          : 'text-muted-foreground',
                  )}
                >
                  {file.status}
                </span>
                <span className="text-[12px] text-green-600">+{file.additions}</span>
                <span className="text-[12px] text-red-600">-{file.deletions}</span>
              </div>
            ))
          ) : (
            <div className="py-8 text-center text-[13px] text-muted-foreground">
              No files changed
            </div>
          )}
        </div>
      )}

      {activeTab === 'reviews' && (
        <div className="space-y-4">
          {reviews && reviews.length > 0 ? (
            reviews.map((review) => (
              <div key={review.id} className="rounded-xl border border-border bg-card p-4">
                <div className="mb-3 flex items-center gap-2">
                  <div className="flex size-7 items-center justify-center rounded-full bg-muted text-[11px] font-semibold text-muted-foreground">
                    {(review.author.display_name ?? review.author.username)
                      .slice(0, 2)
                      .toUpperCase()}
                  </div>
                  <span className="text-[13px] font-medium text-foreground">
                    {review.author.display_name ?? review.author.username}
                  </span>
                  <ReviewStateBadge state={review.state} />
                  <span className="text-[12px] text-muted-foreground">
                    {timeAgo(review.created_at)}
                  </span>
                </div>
                {review.body && (
                  <div className="text-[14px] text-foreground whitespace-pre-wrap">
                    {review.body}
                  </div>
                )}
              </div>
            ))
          ) : (
            <div className="py-8 text-center text-[13px] text-muted-foreground">No reviews yet</div>
          )}
        </div>
      )}

      <div className="rounded-xl border border-border bg-card p-4">
        <textarea
          placeholder="Leave a comment..."
          value={commentBody}
          onChange={(e) => setCommentBody(e.target.value)}
          rows={4}
          className="w-full resize-none rounded-lg border border-border bg-background px-3 py-2 text-[14px] text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
        />
        <div className="mt-3 flex items-center justify-between">
          <p className="text-[12px] text-muted-foreground">Markdown is supported</p>
          <div className="flex items-center gap-2">
            {isOpen && (
              <button
                type="button"
                className="inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-[5px] text-[13px] font-medium text-foreground transition-colors hover:bg-muted"
                onClick={handleApprove}
                disabled={createReview.isPending}
              >
                <CircleCheck className="size-3.5 text-purple-500" />
                Approve
              </button>
            )}
            <button
              type="button"
              disabled={!commentBody.trim() || createReview.isPending}
              onClick={handleComment}
              className="inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-[5px] text-[13px] font-medium text-primary-foreground transition-colors hover:bg-primary/85 disabled:opacity-50"
            >
              <Send className="size-3.5" />
              Comment
            </button>
          </div>
        </div>
      </div>

      <div className="flex items-center gap-3">
        {isOpen && (
          <>
            <button
              type="button"
              className="inline-flex items-center gap-1.5 rounded-md bg-green-600 px-3 py-[5px] text-[13px] font-medium text-white transition-colors hover:bg-green-700 disabled:opacity-50"
              onClick={handleMerge}
              disabled={mergePr.isPending}
            >
              <GitMerge className="size-3.5" />
              {mergePr.isPending ? 'Merging...' : 'Merge'}
            </button>
            <button
              type="button"
              className="inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-[5px] text-[13px] font-medium text-foreground transition-colors hover:bg-muted"
              onClick={handleClose}
              disabled={closePr.isPending}
            >
              <CircleDot className="size-3.5 text-red-500" />
              Close PR
            </button>
          </>
        )}
        {isClosed && !isMerged && (
          <button
            type="button"
            className="inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-[5px] text-[13px] font-medium text-foreground transition-colors hover:bg-muted"
            onClick={handleReopen}
            disabled={reopenPr.isPending}
          >
            <Circle className="size-3.5 text-green-500" />
            Reopen PR
          </button>
        )}
      </div>
    </div>
  );
}

function ReviewStateBadge({ state }: { state: string }) {
  const config: Record<string, { label: string; cls: string }> = {
    Approved: { label: 'Approved', cls: 'bg-green-500/10 text-green-600' },
    ChangesRequested: { label: 'Changes requested', cls: 'bg-amber-500/10 text-amber-600' },
    Commented: { label: 'Commented', cls: 'bg-muted text-muted-foreground' },
    Dismissed: { label: 'Dismissed', cls: 'bg-muted text-muted-foreground' },
    Pending: { label: 'Pending', cls: 'bg-blue-500/10 text-blue-600' },
  };
  const { label, cls } = config[state] ?? { label: state, cls: 'bg-muted text-muted-foreground' };

  return (
    <span
      className={cn(
        'inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-medium',
        cls,
      )}
    >
      {label}
    </span>
  );
}
