"use client";

import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react";
import { createPortal } from "react-dom";
import { AllocationStatus } from "@capakraken/shared";
import { trpc } from "~/lib/trpc/client.js";
import { useInvalidateTimeline } from "~/hooks/useInvalidatePlanningViews.js";
import { ProjectCombobox } from "~/components/ui/ProjectCombobox.js";

const ENTITY_COMBOBOX_OVERLAY_SELECTOR = "[data-entity-combobox-overlay='true']";

interface BatchAssignPopoverProps {
  resourceIds: string[];
  startDate: Date;
  endDate: Date;
  onClose: () => void;
  onCreated: () => void;
}

function toDateDisplay(d: Date): string {
  return d.toLocaleDateString("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  });
}

export function BatchAssignPopover({
  resourceIds,
  startDate,
  endDate,
  onClose,
  onCreated,
}: BatchAssignPopoverProps) {
  const ref = useRef<HTMLDivElement>(null);
  const invalidateTimeline = useInvalidateTimeline();

  const [selectedProjectId, setSelectedProjectId] = useState<string | null>(
    null,
  );
  const [hoursPerDay, setHoursPerDay] = useState(8);

  const batchMutation = trpc.timeline.batchQuickAssign.useMutation({
    onSuccess: () => {
      invalidateTimeline();
      onCreated();
      onClose();
    },
  });

  // Close on outside click
  useEffect(() => {
    function handlePointerDown(event: PointerEvent) {
      const target = event.target;
      if (!(target instanceof Node)) {
        return;
      }
      if (ref.current?.contains(target)) {
        return;
      }
      if (target instanceof Element && target.closest(ENTITY_COMBOBOX_OVERLAY_SELECTOR)) {
        return;
      }
      if (ref.current) {
        onClose();
      }
    }
    document.addEventListener("pointerdown", handlePointerDown, true);
    return () => document.removeEventListener("pointerdown", handlePointerDown, true);
  }, [onClose]);

  // Close on ESC
  useEffect(() => {
    function handleKey(e: KeyboardEvent) {
      if (e.key === "Escape") onClose();
    }
    document.addEventListener("keydown", handleKey);
    return () => document.removeEventListener("keydown", handleKey);
  }, [onClose]);

  function handleAssign() {
    if (!selectedProjectId) return;
    batchMutation.mutate({
      assignments: resourceIds.map((resourceId) => ({
        resourceId,
        projectId: selectedProjectId,
        startDate,
        endDate,
        hoursPerDay,
        role: "Team Member",
        status: AllocationStatus.PROPOSED,
      })),
    });
  }

  const canAssign =
    !!selectedProjectId && resourceIds.length > 0 && hoursPerDay > 0;

  const popover = (
    <div
      ref={ref}
      className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[9998] w-[360px] bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-2xl dark:shadow-black/40 overflow-hidden"
    >
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-3 bg-gray-50 dark:bg-gray-900 border-b border-gray-100 dark:border-gray-700">
        <span className="text-sm font-semibold text-gray-700 dark:text-gray-200">
          Batch Assign
        </span>
        <button
          type="button"
          onClick={onClose}
          className="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 text-lg leading-none"
        >
          &times;
        </button>
      </div>

      <div className="p-4 space-y-3">
        {/* Info line */}
        <div className="text-xs text-gray-600 dark:text-gray-400 space-y-0.5">
          <p>
            Assigning to{" "}
            <span className="font-medium text-gray-800 dark:text-gray-200">
              {resourceIds.length}
            </span>{" "}
            resource{resourceIds.length !== 1 ? "s" : ""}
          </p>
          <p>
            {toDateDisplay(startDate)} &ndash; {toDateDisplay(endDate)}
          </p>
        </div>

        {/* Project picker */}
        <div>
          <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
            Project
          </label>
          <ProjectCombobox
            value={selectedProjectId}
            onChange={setSelectedProjectId}
            placeholder="Search project…"
            className="w-full"
          />
        </div>

        {/* Hours per day */}
        <div>
          <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
            Hours / day
          </label>
          <div className="flex items-center gap-2">
            <input
              type="number"
              min={0.5}
              max={24}
              step={0.5}
              value={hoursPerDay}
              onChange={(e) => setHoursPerDay(parseFloat(e.target.value))}
              className="w-24 border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 rounded-lg px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-sky-400 dark:focus:ring-sky-500"
            />
            <div className="flex gap-1">
              {[4, 6, 8].map((h) => (
                <button
                  key={h}
                  type="button"
                  onClick={() => setHoursPerDay(h)}
                  className={clsx(
                    "px-2 py-1 rounded text-xs font-medium border transition-colors",
                    hoursPerDay === h
                      ? "bg-sky-600 text-white border-sky-600 dark:bg-sky-600 dark:border-sky-600"
                      : "border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700",
                  )}
                >
                  {h}h
                </button>
              ))}
            </div>
          </div>
        </div>

        {/* Error */}
        {batchMutation.isError && (
          <p className="text-xs text-red-600 dark:text-red-400">
            {batchMutation.error.message}
          </p>
        )}

        {/* Actions */}
        <div className="flex gap-2 pt-1">
          <button
            type="button"
            onClick={handleAssign}
            disabled={!canAssign || batchMutation.isPending}
            className={clsx(
              "flex-1 py-2 rounded-lg text-sm font-medium transition-colors",
              "bg-sky-600 text-white hover:bg-sky-700 dark:bg-sky-600 dark:hover:bg-sky-700",
              "disabled:opacity-40 disabled:cursor-not-allowed",
            )}
          >
            {batchMutation.isPending
              ? "Assigning\u2026"
              : `Assign All (${resourceIds.length})`}
          </button>
          <button
            type="button"
            onClick={onClose}
            className="flex-1 py-2 rounded-lg text-sm font-medium border border-gray-200 dark:border-gray-600 text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700"
          >
            Cancel
          </button>
        </div>
      </div>
    </div>
  );

  return typeof document === "undefined" ? popover : createPortal(popover, document.body);
}
