import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";

type FileReferenceKind =
  | "default"
  | "css"
  | "html"
  | "json"
  | "markdown"
  | "notebook"
  | "python"
  | "react"
  | "typescript";

interface FileReferenceChipProps {
  path: string;
  display?: "name" | "path";
  active?: boolean;
  className?: string;
  textClassName?: string;
  testId?: string;
}

export function FileReferenceChip({
  path,
  display = "name",
  active = false,
  className,
  textClassName,
  testId = "inline-file-path",
}: FileReferenceChipProps) {
  const { name } = splitFilePath(path);
  const kind = fileKindForPath(path);
  const displayText = display === "path" ? path.replace(/\\/g, "/") : name;
  return (
    <TooltipProvider delayDuration={500} skipDelayDuration={100}>
      <Tooltip>
        <TooltipTrigger asChild>
          <span
            className={cn("not-prose inline-flex max-w-full align-[0.14em]", className)}
          >
            <span
              data-testid={testId}
              aria-label={path}
              className={cn(
                "inline-flex max-w-full items-center gap-1 font-medium leading-[1.1]",
                "text-sky-600 transition-colors hover:text-sky-700",
                "dark:text-sky-300 dark:hover:text-sky-200",
              )}
            >
              <FileReferenceIcon kind={kind} />
              <span
                data-sheen-text={active ? displayText : undefined}
                className={cn(
                  "min-w-0 truncate",
                  active && "streaming-text-sheen",
                  textClassName,
                )}
              >
                {displayText}
              </span>
            </span>
          </span>
        </TooltipTrigger>
        <TooltipContent
          side="top"
          align="center"
          sideOffset={8}
          collisionPadding={12}
          className={cn(
            "max-w-[min(38rem,calc(100vw-2rem))] rounded-[10px]",
            "border-border/60 bg-popover/95 px-2.5 py-1.5",
            "break-all font-mono text-[11px] leading-snug text-popover-foreground",
            "shadow-lg backdrop-blur",
          )}
        >
          {path}
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

export function isLikelyFilePath(value: string): boolean {
  const raw = value.trim();
  if (!raw || raw.includes("\n")) return false;
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(raw)) return false;
  if (!/[\\/]/.test(raw) && !/^(dockerfile|makefile|readme|package-lock\.json)$/i.test(raw)) {
    return false;
  }
  const normalized = raw.replace(/\\/g, "/");
  const name = normalized.split("/").filter(Boolean).pop() ?? normalized;
  if (!name || name === "." || name === "..") return false;
  if (/^(dockerfile|makefile|readme|package-lock\.json)$/i.test(name)) return true;
  return /\.[a-z0-9][a-z0-9_-]{0,12}$/i.test(name);
}

function splitFilePath(path: string): { directory: string; name: string } {
  const normalized = path.replace(/\\/g, "/");
  const slash = normalized.lastIndexOf("/");
  if (slash < 0) return { directory: "", name: path };
  return {
    directory: normalized.slice(0, slash + 1),
    name: normalized.slice(slash + 1) || normalized,
  };
}

function fileKindForPath(path: string): FileReferenceKind {
  const normalized = path.toLowerCase();
  const name = normalized.split(/[\\/]/).pop() ?? normalized;
  const ext = name.includes(".") ? name.split(".").pop() ?? "" : "";
  if (name === "dockerfile") {
    return "default";
  }
  switch (ext) {
    case "py":
    case "pyi":
      return "python";
    case "jsx":
    case "tsx":
      return "react";
    case "ts":
      return "typescript";
    case "html":
    case "htm":
      return "html";
    case "css":
    case "scss":
    case "sass":
      return "css";
    case "json":
    case "jsonl":
      return "json";
    case "md":
    case "mdx":
      return "markdown";
    case "ipynb":
      return "notebook";
    default:
      return "default";
  }
}

function FileReferenceIcon({ kind }: { kind: FileReferenceKind }) {
  if (kind === "react") {
    return (
      <svg
        aria-hidden
        className="h-[0.98em] w-[0.98em] shrink-0 text-sky-500 dark:text-sky-300"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.6"
        strokeLinecap="round"
        strokeLinejoin="round"
      >
        <circle cx="12" cy="12" r="1.9" fill="currentColor" stroke="none" />
        <ellipse cx="12" cy="12" rx="9" ry="3.7" />
        <ellipse cx="12" cy="12" rx="9" ry="3.7" transform="rotate(60 12 12)" />
        <ellipse cx="12" cy="12" rx="9" ry="3.7" transform="rotate(120 12 12)" />
      </svg>
    );
  }
  if (kind === "default") {
    return (
      <svg
        aria-hidden
        className="h-[0.98em] w-[0.98em] shrink-0 text-sky-500 dark:text-sky-300"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.9"
        strokeLinecap="round"
        strokeLinejoin="round"
      >
        <path d="M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7z" />
        <path d="M14 2v5h5" />
      </svg>
    );
  }
  const label = fileKindLabel(kind);
  return (
    <span
      aria-hidden
      className={cn(
        "inline-flex h-[1.05em] min-w-[1.05em] shrink-0 items-center justify-center",
        "rounded-[4px] bg-sky-500/12 px-[0.22em] text-[0.58em] font-bold uppercase leading-none",
        "text-sky-600 dark:bg-sky-400/15 dark:text-sky-300",
      )}
    >
      {label}
    </span>
  );
}

function fileKindLabel(kind: FileReferenceKind): string {
  switch (kind) {
    case "css":
      return "#";
    case "html":
      return "H";
    case "json":
      return "{}";
    case "markdown":
      return "M";
    case "notebook":
      return "N";
    case "python":
      return "PY";
    case "typescript":
      return "TS";
    default:
      return "";
  }
}
