import { useEffect, useState } from "react";
import {
  GitFork,
  Loader2,
  Star,
  Clock,
  Lock,
  Globe,
} from "lucide-react";
import { api } from "@/client";
import RepoDrawer from "./repo-drawer";
import type { RepoLinkMatch } from "./repo-link-parser";

type RepoEmbedData = {
  name: string;
  description: string | null;
  default_branch: string;
  visibility: string;
  updated_at: string;
  language: string | null;
  star_count: number;
  fork_count: number;
  topics: string[];
};

function languageColor(lang: string): string {
  const map: Record<string, string> = {
    Rust: "#DEA584", TypeScript: "#3178C6", JavaScript: "#F7DF1E",
    Python: "#3572A5", Go: "#00ADD8", Java: "#B07219",
    Kotlin: "#A97BFF", Swift: "#F05138", C: "#555555",
    "C++": "#F34B7D", "C#": "#178600", Ruby: "#701516",
    Zig: "#EC915C", Elixir: "#6E4A7E", Haskell: "#5E5086",
    CSS: "#563D7C", HTML: "#E34C26", Shell: "#89E051",
    PHP: "#4F5D95", Dart: "#00B4AB", Scala: "#C22D40",
    R: "#198CE7", Lua: "#000080", Vue: "#41B883",
    Svelte: "#FF3E00", MDX: "#FCB32C", Dockerfile: "#384D54",
    Makefile: "#427819", Markdown: "#083FA1", Nix: "#7E7EFF",
    OCaml: "#3BE133", "Objective-C": "#438EFF", Perl: "#0298C3",
    Erlang: "#B83998", CMake: "#DA3434", PowerShell: "#012456",
    SQL: "#E38C00", Solidity: "#AA6746", Terraform: "#7B42BC",
  };
  return map[lang] ?? "#6B7280";
}

function formatCount(n: number): string {
  if (n === 0) return "";
  if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;
  return n.toString();
}

function timeAgo(iso: string): string {
  const diff = Date.now() - new Date(iso).getTime();
  const days = Math.floor(diff / 86400000);
  if (days < 1) return "today";
  if (days === 1) return "yesterday";
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months}mo ago`;
  return `${Math.floor(months / 12)}y ago`;
}

export default function RepoEmbedCard({ link }: { link: RepoLinkMatch }) {
  const [data, setData] = useState<RepoEmbedData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(false);

    api
      .get<RepoEmbedData>(
        `/api/v1/workspace/${link.workspace}/repos/${link.repo}/embed-card`,
      )
      .then((res) => {
        if (!cancelled) setData(res.data);
      })
      .catch(() => {
        if (!cancelled) setError(true);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => {
      cancelled = true;
    };
  }, [link.workspace, link.repo]);

  return (
    <RepoDrawer repo={link.repo} workspace={link.workspace}>
      <div
        className="mt-2 block max-w-[420px] cursor-pointer rounded-xl border border-border/30 bg-muted/[0.03] p-4 transition-[background-color,border-color,color,opacity,box-shadow,transform] duration-200 hover:border-primary/20 hover:bg-muted/[0.08] hover:shadow-sm"
      >
        {loading ? (
          <div className="flex items-center gap-2 py-2 text-[13px] text-muted-foreground/50">
            <Loader2 className="size-4 animate-spin" />
            Loading repo info…
          </div>
        ) : error || !data ? (
          <div className="flex items-center gap-2 py-2">
            <div className="grid size-8 shrink-0 place-items-center rounded-lg bg-muted/40">
              <div className="grid size-7 place-items-center rounded-md bg-gradient-to-br from-primary/30 to-primary/10 text-[10px] font-bold text-primary/70">
                {link.repo.charAt(0).toUpperCase()}
              </div>
            </div>
            <div className="min-w-0 flex-1">
              <p className="text-[13px] font-semibold text-foreground/70">
                {link.workspace}/
                <span className="text-primary/80">{link.repo}</span>
              </p>
            </div>
          </div>
        ) : (
          <>
            <div className="flex items-start gap-3">
              <div className="grid size-8 shrink-0 place-items-center rounded-lg bg-muted/40">
                <div className="grid size-7 place-items-center rounded-md bg-gradient-to-br from-primary/30 to-primary/10 text-[10px] font-bold text-primary/70">
                  {data.name.charAt(0).toUpperCase()}
                </div>
              </div>
              <div className="min-w-0 flex-1">
                <p className="text-[13px] font-semibold text-foreground/90">
                  {link.workspace}/
                  <span className="text-primary/80">{link.repo}</span>
                </p>
                {data.description && (
                  <p className="mt-0.5 line-clamp-2 text-[12px] leading-relaxed text-muted-foreground/60">
                    {data.description}
                  </p>
                )}
              </div>
            </div>

            <div className="mt-3 flex flex-wrap items-center gap-3 text-[11px] text-muted-foreground/50">
              {data.language && (
                <span className="inline-flex items-center gap-1.5">
                  <span
                    className="inline-block size-2.5 rounded-full"
                    style={{ backgroundColor: languageColor(data.language) }}
                  />
                  {data.language}
                </span>
              )}
              {data.star_count > 0 && (
                <span className="inline-flex items-center gap-1">
                  <Star className="size-3" />
                  {formatCount(data.star_count)}
                </span>
              )}
              {data.fork_count > 0 && (
                <span className="inline-flex items-center gap-1">
                  <GitFork className="size-3" />
                  {formatCount(data.fork_count)}
                </span>
              )}
              <span className="inline-flex items-center gap-1">
                {data.visibility === "private" ? (
                  <Lock className="size-3" />
                ) : (
                  <Globe className="size-3" />
                )}
                {data.visibility === "private" ? "private" : "public"}
              </span>
              <span className="inline-flex items-center gap-1">
                <Clock className="size-3" />
                {data.updated_at ? timeAgo(data.updated_at) : ""}
              </span>
            </div>

            {data.topics.length > 0 && (
              <div className="mt-2.5 flex flex-wrap gap-1.5">
                {data.topics.slice(0, 5).map((t) => (
                  <span
                    className="inline-block rounded-full bg-primary/[0.06] px-2 py-0.5 text-[10px] font-medium text-primary/70"
                    key={t}
                  >
                    {t}
                  </span>
                ))}
              </div>
            )}
          </>
        )}
      </div>
    </RepoDrawer>
  );
}
