import { Circle, CircleDot, GitMerge, GitPullRequest, Plus, Search } from 'lucide-react';
import { useState } from 'react';
import { Link, useParams, useSearchParams } from 'react-router-dom';
import type { PullRequestDetail } from '@/client/models/PullRequestDetail';
import { Pagination } from '@/components/repo/Pagination';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Spinner } from '@/components/ui/spinner';
import { useRepoPulls } from '@/hooks/repo/useRepoPulls';
import { cn, timeAgo } from '@/lib/utils';

const LIMIT = 20;

export function RepoPullsPage() {
  const { workspaceName = '', repoName = '' } = useParams();
  const [stateFilter, setStateFilter] = useState('Open');
  const [search, setSearch] = useState('');
  const [params, setParams] = useSearchParams();
  const offset = Number(params.get('offset') ?? '0');

  const setOffset = (n: number) => {
    const next = new URLSearchParams(params);
    if (n <= 0) next.delete('offset');
    else next.set('offset', String(n));
    setParams(next, { replace: true });
  };

  const { data: prs, isLoading } = useRepoPulls(workspaceName, repoName, {
    state: stateFilter === 'All' ? undefined : stateFilter,
    offset,
    limit: LIMIT,
  });

  const list = prs ?? [];
  const filtered = search
    ? list.filter(
        (pr) =>
          pr.title.toLowerCase().includes(search.toLowerCase()) ||
          String(pr.number).includes(search),
      )
    : list;

  const tabs = [
    { key: 'Open', icon: Circle, color: 'text-green-500' },
    { key: 'Closed', icon: CircleDot, color: 'text-red-500' },
    { key: 'Merged', icon: GitMerge, color: 'text-purple-500' },
    { key: 'All', icon: GitPullRequest, color: 'text-muted-foreground' },
  ];

  return (
    <div>
      <div className="mb-3 flex items-center justify-between">
        <p className="text-[12px] text-muted-foreground">
          Showing pull requests
        </p>
        <Link to={`/${workspaceName}/repos/${repoName}/pulls/new`}>
          <Button size="sm">
            <Plus className="size-3.5" />
            New pull request
          </Button>
        </Link>
      </div>
      <div className="overflow-hidden rounded-lg border border-border bg-card shadow-sm">
        <div className="flex items-center gap-2 border-b border-border bg-muted/40 px-3 py-2">
          <nav className="flex items-center gap-0.5">
            {tabs.map((tab) => (
              <button
                key={tab.key}
                type="button"
                className={cn(
                  'flex items-center gap-1.5 rounded-lg px-2.5 py-1 text-[12px] font-medium transition-colors',
                  stateFilter === tab.key
                    ? 'bg-card text-foreground shadow-sm ring-1 ring-border'
                    : 'text-muted-foreground hover:bg-background/60 hover:text-foreground',
                )}
                onClick={() => {
                  setStateFilter(tab.key);
                  setOffset(0);
                }}
              >
                <tab.icon className={cn('size-3', tab.color)} />
                {tab.key}
              </button>
            ))}
          </nav>
          <div className="ml-auto relative">
            <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
            <Input
              className="h-8 w-52 pl-7 text-[12px]"
              placeholder="Filter pull requests..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
          </div>
        </div>

        {isLoading ? (
          <div className="flex items-center gap-2 p-6 text-[13px] text-muted-foreground">
            <Spinner />
          </div>
        ) : filtered.length > 0 ? (
          <>
            <div>
              {filtered.map((pr) => (
                <PullRow key={pr.id} pr={pr} workspaceName={workspaceName} repoName={repoName} />
              ))}
            </div>
            <Pagination
              offset={offset}
              limit={LIMIT}
              hasMore={list.length >= LIMIT}
              onPrev={() => setOffset(Math.max(0, offset - LIMIT))}
              onNext={() => setOffset(offset + LIMIT)}
            />
          </>
        ) : (
          <div className="py-12 text-center">
            <GitPullRequest className="mx-auto size-5 text-muted-foreground/20" />
            <p className="mt-3 text-[13px] text-muted-foreground">
              {stateFilter === 'Open'
                ? 'No open pull requests'
                : stateFilter === 'Closed'
                  ? 'No closed pull requests'
                  : 'No pull requests yet'}
            </p>
          </div>
        )}
      </div>
    </div>
  );
}

function PullRow({
  pr,
  workspaceName,
  repoName,
}: {
  pr: PullRequestDetail;
  workspaceName?: string;
  repoName?: string;
}) {
  const isMerged = !!pr.merged_at;
  const isClosed = pr.state === 'Closed' || isMerged;

  return (
    <Link
      to={`/${workspaceName ?? ''}/repos/${repoName ?? ''}/pulls/${pr.number}`}
      className="flex items-start gap-3 border-b border-border px-4 py-2.5 last:border-b-0 transition-colors hover:bg-muted/40"
    >
      {isMerged ? (
        <GitMerge className="mt-0.5 size-4 shrink-0 text-purple-500" />
      ) : isClosed ? (
        <CircleDot className="mt-0.5 size-4 shrink-0 text-red-500" />
      ) : (
        <Circle className="mt-0.5 size-4 shrink-0 text-green-500" />
      )}
      <div className="min-w-0 flex-1">
        <div className="flex items-baseline gap-1.5 flex-wrap">
          <span className="text-[13px] font-semibold text-foreground">{pr.title}</span>
          <span className="text-[11px] text-muted-foreground/60">#{pr.number}</span>
          {pr.draft && (
            <span className="rounded border border-border bg-muted/30 px-1.5 py-0.5 text-[11px] text-muted-foreground">
              Draft
            </span>
          )}
        </div>
        <div className="mt-0.5 flex items-center gap-2 text-[11px] text-muted-foreground">
          <span>
            {pr.source_branch} → {pr.target_branch}
          </span>
          <span>opened {timeAgo(pr.created_at)}</span>
        </div>
      </div>
    </Link>
  );
}
