"use client";

import type { ReactNode } from "react";
import {
  CheckSquare,
  FileText,
  Folder,
  FolderKanban,
  LayoutDashboard,
  PenLine,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

export type SearchResultItem = {
  id: string;
  type: string;
  title: string;
  status: string | null;
  parentId: string | null;
  workspaceId: string | null;
  descriptionSnippet: string | null;
  parentBreadcrumb: string | null;
};

const TYPE_STYLES: Record<
  string,
  { Icon: typeof CheckSquare; className: string }
> = {
  task: {
    Icon: CheckSquare,
    className:
      "text-teal-600 dark:text-teal-400 bg-teal-500/12 border-teal-500/25",
  },
  document: {
    Icon: FileText,
    className:
      "text-sky-600 dark:text-sky-400 bg-sky-500/12 border-sky-500/25",
  },
  project: {
    Icon: FolderKanban,
    className:
      "text-amber-600 dark:text-amber-400 bg-amber-500/12 border-amber-500/25",
  },
  whiteboard: {
    Icon: PenLine,
    className:
      "text-violet-600 dark:text-violet-400 bg-violet-500/12 border-violet-500/25",
  },
  group: {
    Icon: Folder,
    className:
      "text-orange-600 dark:text-orange-400 bg-orange-500/12 border-orange-500/25",
  },
  workspace: {
    Icon: LayoutDashboard,
    className:
      "text-emerald-600 dark:text-emerald-400 bg-emerald-500/12 border-emerald-500/25",
  },
};

function escapeRegExp(s: string): string {
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}

export function highlightText(text: string, query: string): ReactNode {
  const q = query.trim();
  if (!q) return text;
  const re = new RegExp(`(${escapeRegExp(q)})`, "gi");
  const parts = text.split(re);
  return parts.map((part, i) => {
    if (part.toLowerCase() === q.toLowerCase()) {
      return (
        <mark
          key={i}
          className="rounded-sm bg-amber-200/90 px-0.5 font-medium text-foreground dark:bg-amber-500/35"
        >
          {part}
        </mark>
      );
    }
    return <span key={i}>{part}</span>;
  });
}

function formatStatus(status: string | null): string {
  if (!status) return "";
  return status.replace(/_/g, " ");
}

export function SearchResultRow({
  object,
  query,
  onClick,
  active,
  onMouseEnter,
}: {
  object: SearchResultItem;
  query: string;
  onClick: () => void;
  active: boolean;
  onMouseEnter?: () => void;
}) {
  const style = TYPE_STYLES[object.type] ?? {
    Icon: Folder,
    className:
      "text-muted-foreground bg-muted/80 border-border",
  };
  const Icon = style.Icon;

  return (
    <button
      type="button"
      onClick={onClick}
      onMouseEnter={onMouseEnter}
      className={cn(
        "flex h-10 w-full min-w-0 items-center gap-2.5 rounded-lg border border-transparent px-2.5 text-left text-sm transition-colors",
        active
          ? "border-border bg-muted/90 shadow-sm dark:bg-muted/50"
          : "hover:bg-muted/60 dark:hover:bg-muted/40",
      )}
    >
      <span
        className={cn(
          "flex size-8 shrink-0 items-center justify-center rounded-md border",
          style.className,
        )}
      >
        <Icon className="size-4" />
      </span>
      <span className="min-w-0 flex-1">
        <span className="flex min-w-0 items-center gap-2">
          <span className="truncate font-medium leading-tight text-foreground">
            {highlightText(object.title, query)}
          </span>
          {object.status ? (
            <Badge
              variant="secondary"
              className="h-5 shrink-0 px-1.5 text-[10px] font-medium capitalize"
            >
              {formatStatus(object.status)}
            </Badge>
          ) : null}
        </span>
        {object.parentBreadcrumb ? (
          <span className="mt-0.5 block truncate text-[11px] text-muted-foreground">
            {object.parentBreadcrumb}
          </span>
        ) : null}
        {object.descriptionSnippet ? (
          <span className="mt-0.5 line-clamp-1 text-[11px] leading-snug text-muted-foreground">
            {highlightText(object.descriptionSnippet, query)}
          </span>
        ) : null}
      </span>
    </button>
  );
}
