"use client";

import { clsx } from "clsx";
import { useEffect, useRef, useState } from "react";
import { AllocationStatus } from "@planarchy/shared";
import { trpc } from "~/lib/trpc/client.js";
import { useInvalidateTimeline } from "~/hooks/useInvalidatePlanningViews.js";

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 [search, setSearch] = useState("");
  const [selectedProjectId, setSelectedProjectId] = useState<string | null>(
    null,
  );
  const [hoursPerDay, setHoursPerDay] = useState(8);
  const [dropdownOpen, setDropdownOpen] = useState(true);

  const { data: projectsData } = trpc.project.list.useQuery(
    { search, limit: 20 },
    { staleTime: 30_000 },
  );

  const projects = (projectsData?.projects ?? []) as Array<{
    id: string;
    name: string;
  }>;
  const selectedProject = projects.find((p) => p.id === selectedProjectId);

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

  // Close on outside click
  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        onClose();
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [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;

  return (
    <div
      ref={ref}
      className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[60] 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>
          {selectedProject && !dropdownOpen ? (
            <div
              className="flex items-center gap-2 border border-sky-300 dark:border-sky-700 rounded-lg px-3 py-2 cursor-pointer bg-sky-50 dark:bg-sky-950/30"
              onClick={() => {
                setDropdownOpen(true);
                setSearch("");
              }}
            >
              <span className="text-sm text-gray-800 dark:text-gray-200 truncate flex-1">
                {selectedProject.name}
              </span>
              <span className="text-xs text-gray-400 dark:text-gray-500">
                &#9662;
              </span>
            </div>
          ) : (
            <div className="relative">
              <input
                autoFocus
                type="text"
                placeholder="Search projects\u2026"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                onFocus={() => setDropdownOpen(true)}
                className="w-full border border-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-sky-400 dark:focus:ring-sky-500"
              />
              {dropdownOpen && projects.length > 0 && (
                <div className="absolute top-full left-0 right-0 z-50 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-lg dark:shadow-black/40 mt-1 max-h-44 overflow-y-auto">
                  {projects.map((p) => (
                    <button
                      key={p.id}
                      type="button"
                      onClick={() => {
                        setSelectedProjectId(p.id);
                        setDropdownOpen(false);
                        setSearch("");
                      }}
                      className="w-full text-left px-3 py-2 hover:bg-gray-50 dark:hover:bg-gray-700 flex items-center gap-2 border-b border-gray-50 dark:border-gray-700 last:border-0"
                    >
                      <span className="text-sm text-gray-800 dark:text-gray-200 truncate">
                        {p.name}
                      </span>
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}
        </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>
  );
}
