import { useEffect, useRef, useState } from "react";
import { ChevronDown, UserCircle, X } from "lucide-react";
import { cn } from "@/lib/utils";
import type { TaskAssignment, ProjectMember } from "@/types";

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function initials(name: string | null | undefined): string {
  if (!name) return "?";
  return name
    .split(" ")
    .slice(0, 2)
    .map((w) => w[0]?.toUpperCase() ?? "")
    .join("");
}

interface AvatarCircleProps {
  name: string | null | undefined;
  className?: string;
}

function AvatarCircle({ name, className }: AvatarCircleProps) {
  return (
    <span
      className={cn(
        "w-6 h-6 rounded-full bg-muted flex items-center justify-center shrink-0",
        className
      )}
      aria-hidden="true"
    >
      <span className="text-[10px] font-medium text-muted-foreground leading-none">
        {initials(name)}
      </span>
    </span>
  );
}

function roleBadge(
  userId: number,
  ownerId: number,
  permission: ProjectMember["permission"]
): { label: string; className: string } {
  if (userId === ownerId)
    return { label: "Owner", className: "text-accent" };
  if (permission === "create_modify")
    return { label: "Editor", className: "text-muted-foreground" };
  return { label: "Viewer", className: "text-muted-foreground/60" };
}

// ---------------------------------------------------------------------------
// AssigneeAvatars — stacked display for TaskRow / KanbanBoard
// ---------------------------------------------------------------------------

export function AssigneeAvatars({
  assignments,
  max = 3,
}: {
  assignments: TaskAssignment[];
  max?: number;
}) {
  const visible = assignments.slice(0, max);
  const overflow = assignments.length - max;
  const allNames = assignments.map((a) => a.user_name ?? "Unknown").join(", ");

  return (
    <span
      className="flex items-center"
      title={allNames}
      aria-label={`Assigned to: ${allNames}`}
    >
      {visible.map((a) => (
        <span
          key={a.user_id}
          className="w-5 h-5 -ml-1.5 first:ml-0 rounded-full bg-muted border border-background flex items-center justify-center shrink-0"
        >
          <span className="text-[9px] font-medium text-muted-foreground leading-none">
            {initials(a.user_name)}
          </span>
        </span>
      ))}
      {overflow > 0 && (
        <span className="w-5 h-5 -ml-1.5 rounded-full bg-muted border border-background flex items-center justify-center shrink-0">
          <span className="text-[9px] font-medium text-muted-foreground leading-none">
            +{overflow}
          </span>
        </span>
      )}
    </span>
  );
}

// ---------------------------------------------------------------------------
// AssignmentPicker
// ---------------------------------------------------------------------------

interface AssignmentPickerProps {
  currentAssignments: TaskAssignment[];
  members: ProjectMember[];
  currentUserId: number;
  ownerId: number;
  onAssign: (userIds: number[]) => void;
  onUnassign: (userId: number) => void;
  disabled?: boolean;
}

export function AssignmentPicker({
  currentAssignments,
  members,
  currentUserId,
  ownerId,
  onAssign,
  onUnassign,
  disabled = false,
}: AssignmentPickerProps) {
  const [open, setOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);

  // Close on outside click
  useEffect(() => {
    if (!open) return;
    function handle(e: MouseEvent) {
      if (
        containerRef.current &&
        !containerRef.current.contains(e.target as Node)
      ) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handle);
    return () => document.removeEventListener("mousedown", handle);
  }, [open]);

  const assignedIds = new Set(currentAssignments.map((a) => a.user_id));

  // Build ordered member list: current user first, then rest alphabetically
  const sortedMembers = [...members].sort((a, b) => {
    if (a.user_id === currentUserId) return -1;
    if (b.user_id === currentUserId) return 1;
    return (a.user_name ?? "").localeCompare(b.user_name ?? "");
  });

  const availableMembers = sortedMembers.filter(
    (m) => !assignedIds.has(m.user_id)
  );

  function handleSelect(userId: number) {
    onAssign([userId]);
    setOpen(false);
  }

  function handleRemove(e: React.MouseEvent, userId: number) {
    e.stopPropagation();
    onUnassign(userId);
  }

  function handleTriggerClick() {
    if (disabled) return;
    setOpen((prev) => !prev);
  }

  function handleTriggerKeyDown(e: React.KeyboardEvent) {
    if (disabled) return;
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      setOpen((prev) => !prev);
    }
    if (e.key === "Escape") setOpen(false);
  }

  const hasAssignees = currentAssignments.length > 0;

  return (
    <div ref={containerRef} className="relative">
      {/* Trigger area */}
      <div
        role="button"
        tabIndex={disabled ? -1 : 0}
        aria-haspopup="listbox"
        aria-expanded={open}
        aria-disabled={disabled}
        onClick={handleTriggerClick}
        onKeyDown={handleTriggerKeyDown}
        className={cn(
          "flex flex-wrap items-center gap-1 min-h-[28px] px-1.5 py-1 rounded-md",
          "border border-transparent transition-colors",
          disabled
            ? "opacity-50 cursor-not-allowed"
            : "cursor-pointer hover:border-border hover:bg-muted/30 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
        )}
      >
        {hasAssignees ? (
          <>
            {currentAssignments.map((a) => (
              <span
                key={a.user_id}
                className="flex items-center gap-1 bg-secondary rounded-full pl-1 pr-1.5 py-0.5"
              >
                <AvatarCircle name={a.user_name} />
                <span className="text-xs text-secondary-foreground leading-none max-w-[80px] truncate">
                  {a.user_id === currentUserId ? "Me" : (a.user_name ?? "Unknown")}
                </span>
                {!disabled && (
                  <button
                    type="button"
                    aria-label={`Remove ${a.user_name ?? "user"}`}
                    onClick={(e) => handleRemove(e, a.user_id)}
                    className="text-muted-foreground hover:text-foreground transition-colors ml-0.5 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-full"
                  >
                    <X className="w-3 h-3" />
                  </button>
                )}
              </span>
            ))}
            {!disabled && availableMembers.length > 0 && (
              <ChevronDown
                className={cn(
                  "w-3.5 h-3.5 text-muted-foreground/60 transition-transform ml-0.5 shrink-0",
                  open && "rotate-180"
                )}
                aria-hidden="true"
              />
            )}
          </>
        ) : (
          <span className="flex items-center gap-1.5 text-muted-foreground/50 text-xs select-none">
            <UserCircle className="w-4 h-4 shrink-0" aria-hidden="true" />
            Assign...
            <ChevronDown
              className={cn(
                "w-3.5 h-3.5 transition-transform",
                open && "rotate-180"
              )}
              aria-hidden="true"
            />
          </span>
        )}
      </div>

      {/* Dropdown */}
      {open && availableMembers.length > 0 && (
        <ul
          role="listbox"
          aria-label="Available members"
          className="border border-border bg-card shadow-lg rounded-lg absolute z-50 top-full left-0 mt-1 min-w-[180px] max-w-[240px] py-1 overflow-hidden"
        >
          {availableMembers.map((m) => {
            const badge = roleBadge(m.user_id, ownerId, m.permission);
            const displayName =
              m.user_id === currentUserId
                ? "Me"
                : (m.user_name ?? "Unknown");

            return (
              <li key={m.user_id}>
                <button
                  type="button"
                  role="option"
                  aria-selected={false}
                  onClick={() => handleSelect(m.user_id)}
                  className="w-full flex items-center gap-2 px-3 py-1.5 text-sm hover:bg-muted/50 transition-colors text-left focus-visible:outline-none focus-visible:bg-muted/50"
                >
                  <AvatarCircle name={m.user_name} />
                  <span className="flex-1 truncate text-foreground">
                    {displayName}
                  </span>
                  <span className={cn("text-[11px] shrink-0", badge.className)}>
                    {badge.label}
                  </span>
                </button>
              </li>
            );
          })}
        </ul>
      )}

      {/* Empty state when all members assigned */}
      {open && availableMembers.length === 0 && (
        <div className="border border-border bg-card shadow-lg rounded-lg absolute z-50 top-full left-0 mt-1 min-w-[180px] py-2 px-3">
          <p className="text-xs text-muted-foreground">All members assigned</p>
        </div>
      )}
    </div>
  );
}
