"use client";

import type { ActivityEvent, ActivityEventType } from "@/lib/activity";
import { formatRelativeTime } from "@/lib/utils";

// ============================================================================
// Event type icons (inline SVG for each category)
// ============================================================================

function EventIcon({ type, className }: { type: ActivityEventType; className?: string }) {
  const cls = className || "w-3.5 h-3.5 shrink-0";

  switch (type) {
    case "node-created":
      return (
        <svg className={`${cls} text-emerald-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="8" cy="8" r="6" />
          <line x1="8" y1="5" x2="8" y2="11" />
          <line x1="5" y1="8" x2="11" y2="8" />
        </svg>
      );
    case "node-closed":
      return (
        <svg className={`${cls} text-zinc-400`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="8" cy="8" r="6" />
          <polyline points="5.5,8 7.5,10 10.5,6" />
        </svg>
      );
    case "node-status-changed":
      return (
        <svg className={`${cls} text-amber-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M3 8h10M10 5l3 3-3 3" />
        </svg>
      );
    case "node-priority-changed":
      return (
        <svg className={`${cls} text-amber-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M8 3v7M5 6l3-3 3 3M4 13h8" />
        </svg>
      );
    case "node-title-changed":
      return (
        <svg className={`${cls} text-amber-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M3 4h10M3 8h6M3 12h8" />
        </svg>
      );
    case "node-owner-changed":
      return (
        <svg className={`${cls} text-amber-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="6" cy="6" r="2.5" />
          <path d="M1.5 13c0-2 1.8-3.5 4.5-3.5M10 9l2 2 3-3" />
        </svg>
      );
    case "node-assignee-changed":
      return (
        <svg className={`${cls} text-violet-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="6" cy="6" r="2.5" />
          <path d="M1.5 13c0-2 1.8-3.5 4.5-3.5M10 8l2 2 2-2M12 10V5" />
        </svg>
      );
    case "link-added":
      return (
        <svg className={`${cls} text-blue-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M6.5 9.5l3-3M4 11a2.5 2.5 0 003.5 0l1-1M8.5 6a2.5 2.5 0 013.5 0l0 0" />
        </svg>
      );
    case "link-removed":
      return (
        <svg className={`${cls} text-red-400`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M4 11a2.5 2.5 0 003.5 0l1-1M8.5 6a2.5 2.5 0 013.5 0l0 0" />
          <line x1="3" y1="3" x2="13" y2="13" strokeWidth="1.5" />
        </svg>
      );
    case "comment-added":
    case "reply-added":
      return (
        <svg className={`${cls} text-blue-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <path d="M2 4.5a1.5 1.5 0 011.5-1.5h9A1.5 1.5 0 0114 4.5v5a1.5 1.5 0 01-1.5 1.5H5L2 14V4.5z" />
        </svg>
      );
    case "task-claimed":
      return (
        <svg className={`${cls} text-emerald-500`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="8" cy="5.5" r="2.5" />
          <path d="M3 13.5c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5" />
        </svg>
      );
    case "task-unclaimed":
      return (
        <svg className={`${cls} text-red-400`} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
          <circle cx="8" cy="5.5" r="2.5" />
          <path d="M3 13.5c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5" />
          <line x1="11" y1="3" x2="13" y2="5" />
        </svg>
      );
    case "like-added":
      return (
        <svg className={`${cls} text-rose-400`} viewBox="0 0 16 16" fill="currentColor">
          <path d="M8 13.7l-.6-.5C4 10.2 2 8.3 2 6a3 3 0 016-1 3 3 0 016 1c0 2.3-2 4.2-5.4 7.2l-.6.5z" />
        </svg>
      );
  }
}

// ============================================================================
// Event type -> accent color for left border/indicator
// ============================================================================

function getEventAccentColor(type: ActivityEventType): string {
  switch (type) {
    case "node-created":
    case "task-claimed":
      return "bg-emerald-400";
    case "node-closed":
      return "bg-zinc-300";
    case "node-status-changed":
    case "node-priority-changed":
    case "node-title-changed":
    case "node-owner-changed":
      return "bg-amber-400";
    case "node-assignee-changed":
      return "bg-violet-400";
    case "link-added":
    case "comment-added":
    case "reply-added":
      return "bg-blue-400";
    case "link-removed":
    case "task-unclaimed":
      return "bg-red-300";
    case "like-added":
      return "bg-rose-300";
  }
}

// ============================================================================
// Event description text
// ============================================================================

function describeEvent(event: ActivityEvent): string {
  switch (event.type) {
    case "node-created": {
      const typeLabel = event.meta?.issueType || "task";
      return `created a ${typeLabel}`;
    }
    case "node-closed":
      return `closed this${event.detail && event.detail !== "Closed" ? ` (${event.detail})` : ""}`;
    case "node-status-changed":
      return event.detail ? `changed status ${event.detail}` : "changed status";
    case "node-priority-changed":
      return `changed priority ${event.detail || ""}`.trim();
    case "node-title-changed":
      return "updated the title";
    case "node-owner-changed":
      return `changed owner ${event.detail || ""}`.trim();
    case "node-assignee-changed": {
      const to = event.meta?.to;
      const from = event.meta?.from;
      if (to && !from) return `assigned ${to}`;
      if (!to && from) return `unassigned ${from}`;
      if (to) return `reassigned to ${to}`;
      return "changed assignee";
    }
    case "link-added":
      return `added a dependency on ${event.meta?.target || ""}`;
    case "link-removed":
      return `removed dependency on ${event.meta?.target || ""}`;
    case "comment-added":
      return event.detail ? `commented: "${event.detail}"` : "commented";
    case "reply-added":
      return event.detail ? `replied: "${event.detail}"` : "replied";
    case "task-claimed":
      return "claimed this task";
    case "task-unclaimed":
      return "unclaimed this task";
    case "like-added":
      return event.detail || "liked a comment";
    default:
      return event.detail || "updated";
  }
}

// ============================================================================
// Compact variant (single-line, for overlay) — with left accent bar
// ============================================================================

function CompactItem({
  event,
  onNodeClick,
  onHandleClick,
}: {
  event: ActivityEvent;
  onNodeClick?: (nodeId: string) => void;
  onHandleClick?: (handle: string) => void;
}) {
  return (
    <div className="flex items-center gap-2 py-2 px-3 group hover:bg-zinc-50/60 dark:hover:bg-zinc-800/60 transition-colors">
      {/* Left accent dot */}
      <div className={`w-1 h-1 rounded-full shrink-0 ${getEventAccentColor(event.type)}`} />

      {/* Icon */}
      <EventIcon type={event.type} className="w-3 h-3 shrink-0" />

      {/* Content */}
      <div className="flex-1 min-w-0 text-[11px] text-zinc-600 dark:text-zinc-400 truncate">
        {event.actor ? (
          <>
            <button
              onClick={() => onHandleClick?.(event.actor!.handle)}
              className="font-medium text-zinc-800 dark:text-zinc-200 hover:text-emerald-600 dark:hover:text-emerald-400 transition-colors"
            >
              {event.actor.handle}
            </button>
            {" "}
          </>
        ) : onNodeClick ? (
          <>
            <button
              onClick={() => onNodeClick(event.nodeId)}
              className="font-medium text-zinc-700 dark:text-zinc-300 hover:text-emerald-600 dark:hover:text-emerald-400 transition-colors"
            >
              {event.nodeId}
            </button>
            {" "}
          </>
        ) : null}
        <span className="text-zinc-500 dark:text-zinc-400">{describeEvent(event)}</span>
      </div>

      {/* Timestamp */}
      <span className="text-[10px] text-zinc-400 dark:text-zinc-500 shrink-0 tabular-nums opacity-0 group-hover:opacity-100 transition-opacity">
        {formatRelativeTime(new Date(event.time).toISOString())}
      </span>
    </div>
  );
}

// ============================================================================
// Full variant (rich, for panel) — with left accent bar and richer layout
// ============================================================================

function FullItem({
  event,
  onNodeClick,
  onHandleClick,
}: {
  event: ActivityEvent;
  onNodeClick?: (nodeId: string) => void;
  onHandleClick?: (handle: string) => void;
}) {
  return (
    <div className="flex gap-3 py-3 px-4 hover:bg-zinc-50/50 dark:hover:bg-zinc-800/50 transition-colors group">
      {/* Left accent bar */}
      <div className={`w-0.5 self-stretch rounded-full shrink-0 ${getEventAccentColor(event.type)}`} />

      {/* Avatar or icon */}
      <div className="mt-0.5 shrink-0">
        {event.actor?.avatar ? (
          /* eslint-disable-next-line @next/next/no-img-element */
          <img
            src={event.actor.avatar}
            alt={event.actor.handle}
            className="w-7 h-7 rounded-full ring-1 ring-zinc-100 dark:ring-zinc-700"
          />
        ) : event.actor ? (
          <div className="w-7 h-7 rounded-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center text-[11px] font-medium text-zinc-500 dark:text-zinc-400">
            {event.actor.handle.charAt(0).toUpperCase()}
          </div>
        ) : (
          <div className="w-7 h-7 rounded-full bg-zinc-50 dark:bg-zinc-800 flex items-center justify-center">
            <EventIcon type={event.type} className="w-3.5 h-3.5" />
          </div>
        )}
      </div>

      {/* Content */}
      <div className="flex-1 min-w-0">
        {/* Actor + action text */}
        <div className="flex items-baseline gap-1.5 text-[12px] leading-snug">
          {event.actor && (
            <button
              onClick={() => onHandleClick?.(event.actor!.handle)}
              className="font-semibold text-zinc-800 dark:text-zinc-200 hover:text-emerald-600 dark:hover:text-emerald-400 transition-colors"
            >
              {event.actor.handle}
            </button>
          )}
          <span className="text-zinc-500 dark:text-zinc-400">{describeEvent(event)}</span>
        </div>

        {/* Node ID pill + title */}
        <div className="flex items-center gap-1.5 mt-1">
          {onNodeClick && (
            <button
              onClick={() => onNodeClick(event.nodeId)}
              className="inline-flex items-center px-1.5 py-0.5 text-[10px] font-mono font-medium text-emerald-700 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-950 rounded-md hover:bg-emerald-100 dark:hover:bg-emerald-900 transition-colors"
            >
              {event.nodeId}
            </button>
          )}
          {event.nodeTitle && (
            <span className="text-[11px] text-zinc-400 dark:text-zinc-500 truncate">
              {event.nodeTitle}
            </span>
          )}
        </div>
      </div>

      {/* Timestamp */}
      <span className="text-[10px] text-zinc-400 dark:text-zinc-500 shrink-0 tabular-nums mt-0.5">
        {formatRelativeTime(new Date(event.time).toISOString())}
      </span>
    </div>
  );
}

// ============================================================================
// Exported component
// ============================================================================

export function ActivityItem({
  event,
  variant = "compact",
  onNodeClick,
  onHandleClick,
}: {
  event: ActivityEvent;
  variant?: "compact" | "full";
  onNodeClick?: (nodeId: string) => void;
  onHandleClick?: (handle: string) => void;
}) {
  if (variant === "compact") {
    return <CompactItem event={event} onNodeClick={onNodeClick} onHandleClick={onHandleClick} />;
  }
  return <FullItem event={event} onNodeClick={onNodeClick} onHandleClick={onHandleClick} />;
}
