import { pullRequestList, pullRequestSummary } from "@/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useQuery } from "@tanstack/react-query";
import { GitMerge, GitPullRequest, Loader2, Search } from "lucide-react";
import { useMemo, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import type { PullRequestResponse } from "@/client";

const getRelativeTime = (dateString: string | null | undefined) => {
  if (!dateString) return "";
  const date = new Date(dateString);
  const now = new Date();
  const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
  if (diffInSeconds < 60) return "just now";
  if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} minutes ago`;
  if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} hours ago`;
  if (diffInSeconds < 2592000) return `${Math.floor(diffInSeconds / 86400)} days ago`;
  if (diffInSeconds < 31536000) return `${Math.floor(diffInSeconds / 2592000)} months ago`;
  return `${Math.floor(diffInSeconds / 31536000)} years ago`;
};

const getStatusIcon = (status: string) => {
  const s = status?.toLowerCase();
  if (s === "open") return <GitPullRequest className="h-5 w-5 text-green-600" />;
  if (s === "merged") return <GitMerge className="h-5 w-5 text-purple-600" />;
  return <GitPullRequest className="h-5 w-5 text-red-600" />;
};

const getStatusColor = (status: string) => {
  const s = status?.toLowerCase();
  if (s === "open") return "text-green-600 bg-green-500/10 border border-green-500/20";
  if (s === "merged") return "text-purple-600 bg-purple-500/10 border border-purple-500/20";
  if (s === "closed") return "text-red-600 bg-red-500/10 border border-red-500/20";
  return "text-muted-foreground bg-muted border border-border";
};

export const RepoPullRequests = () => {
  const { namespace, repoName } = useParams<{ namespace: string; repoName: string }>();
  const navigate = useNavigate();
  const [searchQuery, setSearchQuery] = useState("");
  const [statusFilter, setStatusFilter] = useState<"all" | "open" | "merged" | "closed">("all");

  const { data, isLoading, isFetching, error } = useQuery({
    queryKey: ["repo-pull-requests", namespace, repoName, statusFilter],
    queryFn: async () => {
      if (!namespace || !repoName) return null;
      const resp = await pullRequestList({
        path: { namespace, repo: repoName },
        query: {
          status: statusFilter !== "all" ? statusFilter : undefined,
          page: 1,
          per_page: 100,
        },
      });
      return resp.data?.data ?? null;
    },
    enabled: !!namespace && !!repoName,
    staleTime: 30 * 1000,
  });

  const { data: summaryData } = useQuery({
    queryKey: ["repo-pull-requests-summary", namespace, repoName],
    queryFn: async () => {
      if (!namespace || !repoName) return null;
      const resp = await pullRequestSummary({
        path: { namespace, repo: repoName },
      });
      return resp.data?.data ?? null;
    },
    enabled: !!namespace && !!repoName,
    staleTime: 60 * 1000,
  });

  const pullRequests = data?.pull_requests ?? [];

  const statusCounts = useMemo(() => {
    if (summaryData) {
      return {
        all: summaryData.total,
        open: summaryData.open,
        merged: summaryData.merged,
        closed: summaryData.closed,
      };
    }
    const counts = { all: 0, open: 0, merged: 0, closed: 0 };
    pullRequests.forEach((pr: PullRequestResponse) => {
      counts.all++;
      const s = pr.status?.toLowerCase() || "open";
      if (s === "open") counts.open++;
      else if (s === "merged") counts.merged++;
      else if (s === "closed") counts.closed++;
    });
    if (data?.total) counts.all = data.total;
    return counts;
  }, [pullRequests, data, summaryData]);

  const filteredPRs = useMemo(() => {
    if (!searchQuery.trim()) return pullRequests;
    const q = searchQuery.toLowerCase();
    return pullRequests.filter(
      (pr: PullRequestResponse) =>
        pr.title?.toLowerCase().includes(q) ||
        pr.author?.toLowerCase().includes(q) ||
        pr.number?.toString().includes(q) ||
        pr.head?.toLowerCase().includes(q) ||
        pr.base?.toLowerCase().includes(q)
    );
  }, [pullRequests, searchQuery]);

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <Loader2 className="h-6 w-6 animate-spin" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="p-6">
        <div className="rounded-md border border-red-300 bg-red-50 dark:bg-red-950/30 p-4">
          <h2 className="text-lg font-semibold text-red-600 dark:text-red-400 mb-2">
            Error loading pull requests
          </h2>
          <p className="text-sm text-red-500">{(error as Error).message}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="p-6 pt-0 max-w-5xl mx-auto space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between py-4">
        <div className="flex items-center gap-2">
          <GitPullRequest className="h-5 w-5 text-muted-foreground" />
          <span className="text-lg font-semibold">Pull Requests</span>
          <span className="text-sm text-muted-foreground">({statusCounts.all})</span>
          {isFetching && <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />}
        </div>
        <Button onClick={() => navigate(`/repository/${namespace}/${repoName}/pull-requests/new`)}>
          <GitMerge className="h-4 w-4 mr-2" />
          New pull request
        </Button>
      </div>

      {/* Status tabs + search */}
      <div className="flex flex-wrap items-center gap-3">
        <div className="inline-flex rounded-lg bg-muted p-[3px]">
          {(["all", "open", "merged", "closed"] as const).map((s) => (
            <button
              key={s}
              onClick={() => setStatusFilter(s)}
              className={`px-3 py-1 text-sm rounded-md transition-colors ${
                statusFilter === s
                  ? "bg-background text-foreground shadow-sm"
                  : "text-muted-foreground hover:text-foreground"
              }`}
            >
              {s.charAt(0).toUpperCase() + s.slice(1)}
              <span className="ml-1 text-xs">({statusCounts[s]})</span>
            </button>
          ))}
        </div>

        <div className="relative flex-1 max-w-md">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input
            placeholder="Search pull requests..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="pl-9"
          />
        </div>
      </div>

      {/* PR list */}
      <div className="border rounded-lg bg-card">
        {filteredPRs.length === 0 ? (
          <div className="p-12 text-center">
            <GitPullRequest className="h-12 w-12 mx-auto text-muted-foreground/50 mb-4" />
            <h3 className="text-lg font-medium mb-2">
              {searchQuery ? "No pull requests match your search" : "No pull requests"}
            </h3>
            <p className="text-muted-foreground mb-4">
              {searchQuery ? "Try a different search term" : "Create a pull request to get started"}
            </p>
            {!searchQuery && (
              <Button onClick={() => navigate(`/repository/${namespace}/${repoName}/pull-requests/new`)}>
                Create pull request
              </Button>
            )}
          </div>
        ) : (
          <div className="divide-y">
            {filteredPRs.map((pr: PullRequestResponse) => (
              <div
                key={`${pr.repo}-${pr.number}`}
                className="group flex gap-3 p-4 hover:bg-muted/50 cursor-pointer transition-colors"
                onClick={() => navigate(`/repository/${namespace}/${repoName}/pull-requests/${pr.number}`)}
              >
                {/* Status icon */}
                <div className="mt-0.5 flex-shrink-0">{getStatusIcon(pr.status ?? "")}</div>

                {/* Content */}
                <div className="flex-1 min-w-0">
                  <div className="flex flex-wrap items-start gap-x-3 gap-y-1">
                    <span className="font-medium truncate">{pr.title}</span>
                    <span
                      className={`flex-shrink-0 px-2 py-0.5 rounded-full text-xs font-medium ${getStatusColor(pr.status ?? "")}`}
                    >
                      {pr.status}
                    </span>
                  </div>

                  <div className="flex flex-wrap items-center gap-x-3 gap-y-1 mt-1 text-sm text-muted-foreground">
                    <span className="font-medium">{pr.author}</span>
                    <span>{getRelativeTime(pr.created_at)}</span>
                  </div>

                  {/* Branch info */}
                  <div className="flex items-center gap-2 mt-2 text-sm text-muted-foreground">
                    <span className="font-mono text-xs bg-muted px-1.5 py-0.5 rounded border border-border truncate max-w-[120px]">
                      {pr.head}
                    </span>
                    <span className="text-muted-foreground/50">→</span>
                    <span className="font-mono text-xs bg-muted px-1.5 py-0.5 rounded border border-border">
                      {pr.base}
                    </span>
                    <span className="ml-auto text-xs text-muted-foreground">#{pr.number}</span>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};
