"use client";

import * as React from "react";
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Calendar, GripVertical } from "lucide-react";

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import type { ViewObject } from "@/lib/hooks/use-view-data";
import { usePanelStore } from "@/lib/stores/panel-store";
import { cn } from "@/lib/utils";

function getPriorityValue(object: ViewObject): string {
  const v = object.propertyValues?.find(
    (p) => p.propertyDefinition.name === "Priority",
  )?.value;
  return typeof v === "string" ? v : "—";
}

function getDueDateValue(object: ViewObject): string {
  const v = object.propertyValues?.find(
    (p) => p.propertyDefinition.name === "Due Date",
  )?.value;
  return typeof v === "string" ? v : "—";
}

function formatDueDisplay(iso: string): string {
  if (iso === "—") return "";
  try {
    const d = new Date(iso);
    if (Number.isNaN(d.getTime())) return iso;
    return d.toLocaleDateString(undefined, {
      month: "short",
      day: "numeric",
    });
  } catch {
    return iso;
  }
}

function priorityTone(p: string): string {
  switch (p) {
    case "High":
      return "border-destructive/40 bg-destructive/10 text-destructive";
    case "Medium":
      return "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-400";
    case "Low":
      return "border-muted-foreground/30 bg-muted/80 text-muted-foreground";
    default:
      return "border-border bg-muted/50 text-muted-foreground";
  }
}

function initials(name: string | null): string {
  return (name ?? "?")
    .split(/\s+/)
    .map((p) => p[0])
    .join("")
    .slice(0, 2)
    .toUpperCase();
}

function CardMeta({ object }: { object: ViewObject }) {
  const openDetail = usePanelStore((s) => s.open);
  const priority = getPriorityValue(object);
  const dueRaw = getDueDateValue(object);
  const due = formatDueDisplay(dueRaw);
  const assignees = object.assignees ?? [];
  const shown = assignees.slice(0, 3);
  const extra = assignees.length - shown.length;

  return (
    <div className="flex min-w-0 flex-1 flex-col gap-1.5">
      <button
        type="button"
        onClick={() => openDetail("object-detail", object.id)}
        className="min-w-0 text-left"
      >
        <span className="line-clamp-2 text-sm font-medium leading-snug text-foreground">
          {object.title}
        </span>
      </button>

      <div className="flex flex-wrap items-center gap-2 pl-1">
        <Badge
          variant="outline"
          className={cn(
            "h-5 max-w-[7rem] shrink-0 truncate px-1.5 py-0 text-[10px] font-semibold uppercase tracking-wide",
            priorityTone(priority),
          )}
        >
          {priority}
        </Badge>

        <div className="ml-auto flex min-w-0 items-center gap-2">
          {due && (
            <span className="flex items-center gap-0.5 text-[11px] tabular-nums text-muted-foreground">
              <Calendar className="h-3 w-3 shrink-0 opacity-70" />
              {due}
            </span>
          )}
          <div className="flex -space-x-1.5">
            {shown.map((a) => (
              <Avatar
                key={a.user.id}
                className="h-6 w-6 border-2 border-card text-[9px]"
              >
                <AvatarImage src={a.user.avatarUrl ?? undefined} alt="" />
                <AvatarFallback>{initials(a.user.name)}</AvatarFallback>
              </Avatar>
            ))}
            {extra > 0 && (
              <span className="flex h-6 min-w-[1.5rem] items-center justify-center rounded-full border-2 border-card bg-muted px-1 text-[10px] font-medium text-muted-foreground">
                +{extra}
              </span>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

export interface BoardCardPreviewProps {
  object: ViewObject;
}

/** Used inside DragOverlay — no sortable hooks; matches card visuals while dragging. */
export function BoardCardPreview({ object }: BoardCardPreviewProps) {
  return (
    <div
      className={cn(
        "flex min-h-[80px] max-h-[100px] rounded-lg border border-border/80 bg-card p-2.5 shadow-xl ring-2 ring-primary/25",
        "rotate-2",
      )}
    >
      <div className="flex min-h-0 flex-1 gap-2">
        <span
          className="mt-0.5 shrink-0 cursor-grabbing rounded p-0.5 text-muted-foreground"
          aria-hidden
        >
          <GripVertical className="h-4 w-4" />
        </span>
        <CardMeta object={object} />
      </div>
    </div>
  );
}

export interface BoardCardProps {
  object: ViewObject;
}

export function BoardCard({ object }: BoardCardProps) {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
    isOver,
  } = useSortable({
    id: object.id,
    data: { type: "card", object },
  });

  const style: React.CSSProperties = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <div className="relative">
      {!isDragging && isOver && (
        <div
          className="absolute -top-1 left-0 right-0 z-10 h-0.5 rounded-full bg-primary shadow-[0_0_8px_hsl(var(--primary))]"
          aria-hidden
        />
      )}
      <div
        ref={setNodeRef}
        style={style}
        className={cn(
          "group/card flex min-h-[80px] max-h-[100px] rounded-lg border border-border/80 bg-card p-2.5 shadow-sm transition-[box-shadow,transform,opacity]",
          "hover:shadow-md",
          isDragging && "opacity-40",
        )}
      >
        <div className="flex min-h-0 flex-1 gap-2">
          <button
            type="button"
            className={cn(
              "mt-0.5 shrink-0 cursor-grab touch-none rounded p-0.5 text-muted-foreground opacity-0 transition-opacity hover:bg-muted hover:text-foreground",
              "group-hover/card:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
            )}
            aria-label="Drag to reorder or move"
            {...attributes}
            {...listeners}
          >
            <GripVertical className="h-4 w-4" />
          </button>
          <CardMeta object={object} />
        </div>
      </div>
    </div>
  );
}
