import * as React from "react";
import { MoreVertical, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { useThemeVars } from "@/lib/theme-provider";
import { formatCurrency } from "@/lib/format-currency";
import { Badge } from "@/components/ui/badge";
import { buttonVariants } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { LeadCard, OpportunityCard } from "@/components/ui/opportunity-card";
import type { OpportunityCardProps } from "@/components/ui/opportunity-card";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";

/**
 * KanbanColumn — WealthX DS (L4 Section)
 *
 * Kanban column wrapper for the Pipeline board.
 * Renders the stage header (name, count, total value, growth chip) and
 * a scrollable list of OpportunityCard items.
 *
 * **Does NOT include:**
 * - Drag-and-drop (react-dnd) — handled by the app's KanbanBoard wrapper.
 * - Infinite scroll logic — the app passes `loaderRef` and manages IntersectionObserver.
 *
 * Data source: `Stage` from `loan-crm.ts` via `useInfiniteColumnOpportunities`.
 */

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface KanbanColumnStage {
  id: string;
  name: string;
  /** Number of opportunities currently in this stage. */
  count: number;
  /** Total loan value across all opportunities in this stage. */
  totalValue: number;
  /**
   * Growth metric for the column (e.g. new opps this week).
   * Positive → success color; negative/zero → destructive color.
   */
  growth?: number | null;
  /**
   * Optional top-border accent color.
   * Pass a CSS variable string: `"var(--color-destructive)"`.
   * Defaults to `"var(--color-border)"`.
   */
  accentColor?: string | null;
  /**
   * Optional color for the stage count number in the column header.
   * Pass a CSS variable string: `"var(--color-destructive)"`.
   * Defaults to `text-muted-foreground`.
   */
  countColor?: string | null;
}

export interface KanbanColumnProps {
  // ── Column data ──────────────────────────────────────────────
  stage: KanbanColumnStage;
  /** Opportunity cards to render in this column. */
  opportunities: OpportunityCardProps[];

  // ── Column visual states (controlled by parent DnD) ─────────
  /** Whether this column is currently being dragged. Reduces opacity. */
  isDragging?: boolean;
  /**
   * Whether a card is hovering over this column and can be dropped.
   * Shows a drop-target highlight.
   */
  isDropTarget?: boolean;
  /**
   * Whether this is a fixed/system column (Leads, On Hold, High Priority).
   * Fixed columns show no Delete option in the menu.
   */
  isDefault?: boolean;

  // ── Async / loading state ────────────────────────────────────
  /** Shows a full-column skeleton/spinner on initial load. */
  isLoading?: boolean;
  /** Shows a small spinner at the bottom while fetching the next page. */
  isLoadingMore?: boolean;
  /** Whether there are more opportunities to load. */
  hasMore?: boolean;
  /**
   * Ref for the loader sentinel element at the column bottom.
   * Attach an IntersectionObserver in the app to call `fetchNextPage()` when visible.
   */
  loaderRef?: React.Ref<HTMLDivElement>;

  // ── Column actions ───────────────────────────────────────────
  onEditColumn?: () => void;
  /** Only shown for non-default columns. */
  onDeleteColumn?: () => void;
  /**
   * When provided, renders a `+` icon button in the column header.
   * Intended for the Leads column — opens the Add Lead flow.
   */
  onAddLead?: () => void;

  // ── Card callbacks (forwarded to each OpportunityCard) ───────
  onTaskToggle?: (opportunityId: string, taskId: string) => void;
  onMarkAsDone?: (opportunityId: string) => void;
  onMoveToNextStage?: (opportunityId: string) => void;
  onSendLoanApplication?: (opportunityId: string) => void;
  /** Fires when clicking the non-interactive card body. */
  onCardClick?: (opportunityId: string) => void;
  onViewDetails?: (opportunityId: string) => void;
  onChangePriority?: (opportunityId: string) => void;
  onPutOnHold?: (opportunityId: string) => void;
  onPlaceBack?: (opportunityId: string) => void;
  /** When true, every card in this column renders in on-hold mode. */
  isOnHoldColumn?: boolean;
  onDeleteOpportunity?: (opportunityId: string) => void;
  onSendToAI?: (opp: OpportunityCardProps) => void;
  /** Fires when a broker activates/re-syncs a CRM target on a card (BUILD-2228). */
  onSyncCrmTarget?: (opportunityId: string, targetId: string) => void;
  /** Fires when a card is dropped onto this column (HTML5 DnD). */
  onCardDrop?: (cardId: string) => void;
  /** Opportunity ID currently being submitted — disables that card's actions. */
  submittingOpportunityId?: string | null;

  className?: string;
}

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

function growthColor(growth: number): string {
  // Use darkened text tokens — full-saturation tokens (#4CAF50, #F44336) fail 4.5:1 on white bg
  return growth > 0
    ? "var(--color-success-text)"
    : "var(--color-destructive-text)";
}

// ---------------------------------------------------------------------------
// KanbanColumn
// ---------------------------------------------------------------------------

export function KanbanColumn({
  stage,
  opportunities,
  isDragging = false,
  isDropTarget = false,
  isDefault = false,
  isLoading = false,
  isLoadingMore = false,
  hasMore = false,
  loaderRef,
  onEditColumn,
  onDeleteColumn,
  onAddLead,
  onTaskToggle,
  onMarkAsDone,
  onMoveToNextStage,
  onSendLoanApplication,
  onCardClick,
  onViewDetails,
  onChangePriority,
  onPutOnHold,
  onPlaceBack,
  isOnHoldColumn,
  onDeleteOpportunity,
  onSendToAI,
  onSyncCrmTarget,
  onCardDrop,
  submittingOpportunityId,
  className,
}: KanbanColumnProps) {
  const themeVars = useThemeVars();
  const accentColor = stage.accentColor ?? "var(--color-border)";
  const hasMenu = onEditColumn || (!isDefault && onDeleteColumn);

  // ── HTML5 drag-and-drop drop-zone state ──────────────────────
  const [isDragOver, setIsDragOver] = React.useState(false);

  function handleDragOver(e: React.DragEvent<HTMLDivElement>) {
    if (!onCardDrop) return;
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
    setIsDragOver(true);
  }

  function handleDragLeave(e: React.DragEvent<HTMLDivElement>) {
    // Only clear when leaving the column entirely (not entering a child)
    if (!e.currentTarget.contains(e.relatedTarget as Node)) {
      setIsDragOver(false);
    }
  }

  function handleDrop(e: React.DragEvent<HTMLDivElement>) {
    if (!onCardDrop) return;
    e.preventDefault();
    setIsDragOver(false);
    const cardId = e.dataTransfer.getData("text/plain");
    if (cardId) onCardDrop(cardId);
  }

  return (
    <div
      className={cn(
        "flex w-[292px] shrink-0 flex-col bg-muted/40",
        isDragging && "opacity-50",
        isDropTarget && "ring-2 ring-primary ring-inset",
        className,
      )}
      style={{
        ...(themeVars as React.CSSProperties),
        borderTop: `2px solid ${accentColor}`,
      }}
      data-slot="kanban-column"
    >
      {/* ── Header ── */}
      <div className="flex flex-col gap-2 border-b border-border bg-background px-3 py-3">
        {/* Title row */}
        <div className="flex items-center justify-between gap-2">
          <h2 className="text-sm font-semibold text-foreground">
            <span
              className={cn(!stage.countColor && "text-muted-foreground")}
              style={stage.countColor ? { color: stage.countColor } : undefined}
            >
              {stage.count}
            </span>{" "}
            {stage.name}
          </h2>

          <div className="flex items-center gap-0.5">
            {onAddLead && (
              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger
                    render={
                      <button
                        className={cn(
                          buttonVariants({ variant: "ghost", size: "icon" }),
                          "size-7 shrink-0",
                        )}
                        onClick={onAddLead}
                        aria-label="Add lead"
                      >
                        <Plus className="size-4" />
                      </button>
                    }
                  />
                  <TooltipContent>Add lead</TooltipContent>
                </Tooltip>
              </TooltipProvider>
            )}

            {hasMenu && (
              <DropdownMenu>
                <DropdownMenuTrigger
                  className={cn(
                    buttonVariants({ variant: "ghost", size: "icon" }),
                    "-mr-1 size-7 shrink-0",
                  )}
                  aria-label="Column actions"
                >
                  <MoreVertical className="size-4" />
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  {onEditColumn && (
                    <DropdownMenuItem onClick={onEditColumn}>
                      Edit column settings
                    </DropdownMenuItem>
                  )}
                  {!isDefault && onDeleteColumn && (
                    <>
                      {onEditColumn && <DropdownMenuSeparator />}
                      <DropdownMenuItem
                        onClick={onDeleteColumn}
                        className="text-destructive focus:text-destructive"
                      >
                        Delete column
                      </DropdownMenuItem>
                    </>
                  )}
                </DropdownMenuContent>
              </DropdownMenu>
            )}
          </div>
        </div>

        {/* Stats row */}
        <div className="flex items-center justify-between gap-2">
          {stage.growth != null ? (
            <Badge
              variant="outline"
              style={{ color: growthColor(stage.growth) }}
            >
              {stage.growth > 0 ? "+" : ""}
              {stage.growth}
            </Badge>
          ) : (
            <span />
          )}
          <span className="text-sm font-bold tabular-nums text-foreground">
            {formatCurrency(stage.totalValue)}
          </span>
        </div>
      </div>

      {/* ── Body ── */}
      <div
        className={cn(
          "flex flex-1 flex-col gap-2 overflow-y-auto p-2",
          isDragOver && "ring-2 ring-primary ring-inset bg-primary/5",
        )}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
      >
        {/* Drop target hint — shown at top when a card is dragged over */}
        {(isDropTarget || isDragOver) && (
          <div className="border border-dashed border-primary/40 bg-primary/5 px-3 py-2 text-center text-xs text-primary">
            Drop here → {stage.name}
          </div>
        )}

        {isLoading ? (
          <div className="flex flex-1 items-center justify-center py-8">
            <Spinner className="size-5 text-muted-foreground" />
          </div>
        ) : opportunities.length === 0 ? (
          <div className="flex flex-1 items-center justify-center py-8">
            <p className="text-xs text-muted-foreground">
              No opportunities in this stage
            </p>
          </div>
        ) : (
          <>
            {opportunities.map((opp) =>
              onSendLoanApplication ? (
                <LeadCard
                  key={opp.id}
                  id={opp.id}
                  customerName={opp.customerName}
                  customerPhone={opp.customerPhone}
                  customerEmail={opp.customerEmail}
                  loanApplicationUrl={opp.loanApplicationUrl}
                  onSendLoanApplication={() => onSendLoanApplication(opp.id)}
                  onDelete={
                    onDeleteOpportunity
                      ? () => onDeleteOpportunity(opp.id)
                      : undefined
                  }
                  onSendToAI={onSendToAI ? () => onSendToAI(opp) : undefined}
                  isSubmitting={submittingOpportunityId === opp.id}
                />
              ) : (
                <OpportunityCard
                  key={opp.id}
                  {...opp}
                  draggable={!!onCardDrop}
                  onDragStart={
                    onCardDrop
                      ? (e) => {
                          e.dataTransfer.setData("text/plain", opp.id);
                          e.dataTransfer.effectAllowed = "move";
                        }
                      : undefined
                  }
                  onCardClick={
                    onCardClick ? () => onCardClick(opp.id) : undefined
                  }
                  onTaskToggle={
                    onTaskToggle
                      ? (taskId) => onTaskToggle(opp.id, taskId)
                      : undefined
                  }
                  onMarkAsDone={
                    onMarkAsDone ? () => onMarkAsDone(opp.id) : undefined
                  }
                  onMoveToNextStage={
                    onMoveToNextStage
                      ? () => onMoveToNextStage(opp.id)
                      : undefined
                  }
                  onViewDetails={
                    onViewDetails ? () => onViewDetails(opp.id) : undefined
                  }
                  onChangePriority={
                    onChangePriority
                      ? () => onChangePriority(opp.id)
                      : undefined
                  }
                  isOnHold={isOnHoldColumn}
                  onPutOnHold={
                    onPutOnHold ? () => onPutOnHold(opp.id) : undefined
                  }
                  onPlaceBack={
                    onPlaceBack ? () => onPlaceBack(opp.id) : undefined
                  }
                  onDelete={
                    onDeleteOpportunity
                      ? () => onDeleteOpportunity(opp.id)
                      : undefined
                  }
                  onSendToAI={onSendToAI}
                  onSyncCrmTarget={
                    onSyncCrmTarget
                      ? (targetId) => onSyncCrmTarget(opp.id, targetId)
                      : undefined
                  }
                  isSubmitting={submittingOpportunityId === opp.id}
                />
              ),
            )}

            {/* Infinite-scroll loader sentinel */}
            {hasMore && (
              <div
                ref={loaderRef}
                className="flex min-h-[50px] items-center justify-center"
              >
                {isLoadingMore && (
                  <Spinner className="size-5 text-muted-foreground" />
                )}
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}
