"use client";

import { useRef, useState } from "react";
import { useFocusTrap } from "~/hooks/useFocusTrap.js";
import { trpc } from "~/lib/trpc/client.js";
import { DateInput } from "~/components/ui/DateInput.js";

type Mode = "single" | "group";

const TARGET_TYPES = [
  { value: "all", label: "All Users" },
  { value: "role", label: "By Role" },
  { value: "project", label: "By Project" },
  { value: "orgUnit", label: "By Org Unit" },
] as const;

const ROLES = ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"] as const;

const PRIORITY_OPTIONS = [
  { value: "LOW", label: "Low" },
  { value: "NORMAL", label: "Normal" },
  { value: "HIGH", label: "High" },
  { value: "URGENT", label: "Urgent" },
] as const;

const CHANNEL_OPTIONS = [
  { value: "in_app", label: "In-App" },
  { value: "email", label: "Email" },
  { value: "both", label: "Both" },
] as const;

interface CreateTaskModalProps {
  onClose: () => void;
  onSuccess: () => void;
}

export function CreateTaskModal({ onClose, onSuccess }: CreateTaskModalProps) {
  const [mode, setMode] = useState<Mode>("single");
  const [userId, setUserId] = useState("");
  const [userSearch, setUserSearch] = useState("");
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const [priority, setPriority] = useState("NORMAL");
  const [dueDate, setDueDate] = useState("");
  const [dueTime, setDueTime] = useState("09:00");
  const [channel, setChannel] = useState("in_app");
  const [link, setLink] = useState("");
  const [targetType, setTargetType] = useState<string>("all");
  const [targetValue, setTargetValue] = useState("");
  const [serverError, setServerError] = useState<string | null>(null);
  const [result, setResult] = useState<{ recipientCount?: number; taskId?: string } | null>(null);

  const panelRef = useRef<HTMLDivElement>(null);
  useFocusTrap(panelRef, true);

  const utils = trpc.useUtils();

  const { data: users = [] } = trpc.user.listAssignable.useQuery(undefined, {
    staleTime: 60_000,
  });

  const filteredUsers = userSearch.trim()
    ? users.filter(
        (u) =>
          (u.name ?? "").toLowerCase().includes(userSearch.toLowerCase()) ||
          u.email.toLowerCase().includes(userSearch.toLowerCase()),
      )
    : users;

  const createTaskMutation = trpc.notification.createTask.useMutation({
    onSuccess: async (data) => {
      await utils.notification.listTasks.invalidate();
      await utils.notification.list.invalidate();
      await utils.notification.taskCounts.invalidate();
      await utils.notification.unreadCount.invalidate();
      const id = (data as { id?: string }).id;
      setResult(id !== undefined ? { taskId: id } : {});
    },
    onError: (err) => setServerError(err.message),
  });

  const createBroadcastMutation = trpc.notification.createBroadcast.useMutation({
    onSuccess: async (data) => {
      await utils.notification.listBroadcasts.invalidate();
      await utils.notification.list.invalidate();
      await utils.notification.taskCounts.invalidate();
      await utils.notification.unreadCount.invalidate();
      const count = (data as { recipientCount?: number }).recipientCount ?? 0;
      setResult({ recipientCount: count });
    },
    onError: (err) => setServerError(err.message),
  });

  const isPending = createTaskMutation.isPending || createBroadcastMutation.isPending;

  function buildDueDate(): Date | undefined {
    if (!dueDate) return undefined;
    const [hours, minutes] = dueTime.split(":").map(Number);
    const d = new Date(dueDate + "T00:00:00");
    d.setHours(hours ?? 9, minutes ?? 0, 0, 0);
    return d;
  }

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setServerError(null);

    if (!title.trim()) {
      setServerError("Title is required.");
      return;
    }

    if (mode === "single") {
      if (!userId) {
        setServerError("Please select a recipient.");
        return;
      }
      const due = buildDueDate();
      createTaskMutation.mutate({
        userId,
        title: title.trim(),
        ...(body.trim() ? { body: body.trim() } : {}),
        priority: priority as "LOW" | "NORMAL" | "HIGH" | "URGENT",
        ...(due !== undefined ? { dueDate: due } : {}),
        channel: channel as "in_app" | "email" | "both",
        ...(link.trim() ? { link: link.trim() } : {}),
      });
    } else {
      createBroadcastMutation.mutate({
        title: title.trim(),
        ...(body.trim() ? { body: body.trim() } : {}),
        targetType: targetType as "all" | "role" | "project" | "orgUnit",
        ...(targetType !== "all" && targetValue.trim() ? { targetValue: targetValue.trim() } : {}),
        priority: priority as "LOW" | "NORMAL" | "HIGH" | "URGENT",
        channel: channel as "in_app" | "email" | "both",
        ...(link.trim() ? { link: link.trim() } : {}),
        category: "TASK",
      });
    }
  }

  function handleCloseResult() {
    onSuccess();
    onClose();
  }

  const inputClass =
    "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 text-sm dark:bg-gray-900 dark:text-gray-100";
  const labelClass = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1";

  // After successful send, show result
  if (result) {
    const isGroup = mode === "group";
    return (
      <div
        className="fixed inset-0 bg-black/50 z-50 flex items-start justify-center overflow-y-auto py-8"
        onClick={(e) => {
          if (e.target === e.currentTarget) handleCloseResult();
        }}
      >
        <div
          ref={panelRef}
          className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg mx-4"
          onKeyDown={(e) => { if (e.key === "Escape") handleCloseResult(); }}
        >
          <div className="px-6 py-8 text-center">
            <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/30">
              <svg className="h-6 w-6 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
              </svg>
            </div>
            <h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">Task Created</h3>
            <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">
              {isGroup
                ? `Task sent to ${result.recipientCount ?? 0} recipient${(result.recipientCount ?? 0) !== 1 ? "s" : ""}`
                : "Task has been assigned successfully"}
            </p>
            <button
              type="button"
              onClick={handleCloseResult}
              className="mt-6 px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 text-sm font-medium"
            >
              Close
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div
      className="fixed inset-0 bg-black/50 z-50 flex items-start justify-center overflow-y-auto py-8"
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
    >
      <div
        ref={panelRef}
        className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg mx-4"
        onKeyDown={(e) => { if (e.key === "Escape") onClose(); }}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-100">Create Task</h2>
          <button
            type="button"
            onClick={onClose}
            className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors text-xl leading-none"
            aria-label="Close"
          >
            &times;
          </button>
        </div>

        <form onSubmit={handleSubmit} className="px-6 py-5 space-y-4">
          {/* Mode toggle */}
          <div className="flex rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
            <button
              type="button"
              onClick={() => setMode("single")}
              className={`flex-1 px-4 py-2 text-sm font-medium transition-colors ${
                mode === "single"
                  ? "bg-brand-600 text-white"
                  : "bg-white dark:bg-gray-900 text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800"
              }`}
            >
              Single User
            </button>
            <button
              type="button"
              onClick={() => setMode("group")}
              className={`flex-1 px-4 py-2 text-sm font-medium transition-colors ${
                mode === "group"
                  ? "bg-brand-600 text-white"
                  : "bg-white dark:bg-gray-900 text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800"
              }`}
            >
              Group
            </button>
          </div>

          {/* Recipient (single mode) */}
          {mode === "single" && (
            <div>
              <label htmlFor="task-user" className={labelClass}>
                Recipient <span className="text-red-500">*</span>
              </label>
              <input
                id="task-user-search"
                type="text"
                value={userSearch}
                onChange={(e) => setUserSearch(e.target.value)}
                className={inputClass}
                placeholder="Search by name or email..."
              />
              {userId && (
                <div className="mt-1 flex items-center gap-2">
                  <span className="text-xs text-gray-500 dark:text-gray-400">
                    Selected: {users.find((u) => u.id === userId)?.name ?? users.find((u) => u.id === userId)?.email ?? userId}
                  </span>
                  <button
                    type="button"
                    onClick={() => setUserId("")}
                    className="text-xs text-red-500 hover:text-red-700"
                  >
                    Clear
                  </button>
                </div>
              )}
              {userSearch.trim() && filteredUsers.length > 0 && (
                <div className="mt-1 max-h-40 overflow-y-auto rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900">
                  {filteredUsers.slice(0, 20).map((u) => (
                    <button
                      key={u.id}
                      type="button"
                      onClick={() => {
                        setUserId(u.id);
                        setUserSearch("");
                      }}
                      className={`w-full text-left px-3 py-2 text-sm hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors ${
                        u.id === userId ? "bg-brand-50 dark:bg-brand-900/20" : ""
                      }`}
                    >
                      <span className="font-medium text-gray-900 dark:text-gray-100">
                        {u.name ?? "Unnamed"}
                      </span>
                      <span className="ml-2 text-gray-400 dark:text-gray-500">{u.email}</span>
                    </button>
                  ))}
                </div>
              )}
              {userSearch.trim() && filteredUsers.length === 0 && (
                <p className="mt-1 text-xs text-gray-400 dark:text-gray-500">No users found.</p>
              )}
            </div>
          )}

          {/* Target (group mode) */}
          {mode === "group" && (
            <>
              <div>
                <label htmlFor="task-target" className={labelClass}>
                  Target Audience
                </label>
                <select
                  id="task-target"
                  value={targetType}
                  onChange={(e) => { setTargetType(e.target.value); setTargetValue(""); }}
                  className={inputClass}
                >
                  {TARGET_TYPES.map((t) => (
                    <option key={t.value} value={t.value}>{t.label}</option>
                  ))}
                </select>
              </div>

              {targetType === "role" && (
                <div>
                  <label htmlFor="task-role" className={labelClass}>
                    Role
                  </label>
                  <select
                    id="task-role"
                    value={targetValue}
                    onChange={(e) => setTargetValue(e.target.value)}
                    className={inputClass}
                  >
                    <option value="">Select a role...</option>
                    {ROLES.map((r) => (
                      <option key={r} value={r}>{r}</option>
                    ))}
                  </select>
                </div>
              )}

              {targetType === "project" && (
                <div>
                  <label htmlFor="task-project" className={labelClass}>
                    Project ID
                  </label>
                  <input
                    id="task-project"
                    type="text"
                    value={targetValue}
                    onChange={(e) => setTargetValue(e.target.value)}
                    className={inputClass}
                    placeholder="Project ID..."
                  />
                </div>
              )}

              {targetType === "orgUnit" && (
                <div>
                  <label htmlFor="task-orgunit" className={labelClass}>
                    Org Unit ID
                  </label>
                  <input
                    id="task-orgunit"
                    type="text"
                    value={targetValue}
                    onChange={(e) => setTargetValue(e.target.value)}
                    className={inputClass}
                    placeholder="Org Unit ID..."
                  />
                </div>
              )}
            </>
          )}

          {/* Title */}
          <div>
            <label htmlFor="task-title" className={labelClass}>
              Title <span className="text-red-500">*</span>
            </label>
            <input
              id="task-title"
              type="text"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              maxLength={200}
              className={inputClass}
              required
              placeholder="Task title..."
            />
          </div>

          {/* Body */}
          <div>
            <label htmlFor="task-body" className={labelClass}>
              Description (optional)
            </label>
            <textarea
              id="task-body"
              value={body}
              onChange={(e) => setBody(e.target.value)}
              rows={3}
              maxLength={2000}
              className={`${inputClass} resize-none`}
              placeholder="Task details..."
            />
          </div>

          {/* Priority + Channel */}
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label htmlFor="task-priority" className={labelClass}>
                Priority
              </label>
              <select
                id="task-priority"
                value={priority}
                onChange={(e) => setPriority(e.target.value)}
                className={inputClass}
              >
                {PRIORITY_OPTIONS.map((p) => (
                  <option key={p.value} value={p.value}>{p.label}</option>
                ))}
              </select>
            </div>
            <div>
              <label htmlFor="task-channel" className={labelClass}>
                Channel
              </label>
              <select
                id="task-channel"
                value={channel}
                onChange={(e) => setChannel(e.target.value)}
                className={inputClass}
              >
                {CHANNEL_OPTIONS.map((c) => (
                  <option key={c.value} value={c.value}>{c.label}</option>
                ))}
              </select>
            </div>
          </div>

          {/* Due Date + Time */}
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label htmlFor="task-due-date" className={labelClass}>
                Due Date (optional)
              </label>
              <DateInput
                id="task-due-date"
                value={dueDate}
                onChange={setDueDate}
                className={inputClass}
              />
            </div>
            <div>
              <label htmlFor="task-due-time" className={labelClass}>
                Due Time
              </label>
              <input
                id="task-due-time"
                type="time"
                value={dueTime}
                onChange={(e) => setDueTime(e.target.value)}
                className={inputClass}
                disabled={!dueDate}
              />
            </div>
          </div>

          {/* Link */}
          <div>
            <label htmlFor="task-link" className={labelClass}>
              Link (optional)
            </label>
            <input
              id="task-link"
              type="text"
              value={link}
              onChange={(e) => setLink(e.target.value)}
              className={inputClass}
              placeholder="/some/page or https://..."
            />
          </div>

          {/* Server error */}
          {serverError && (
            <div className="rounded-lg bg-red-50 border border-red-200 px-4 py-3 text-sm text-red-700 dark:bg-red-900/20 dark:border-red-800 dark:text-red-300">
              {serverError}
            </div>
          )}

          {/* Footer */}
          <div className="flex items-center justify-end gap-3 pt-2">
            <button
              type="button"
              onClick={onClose}
              disabled={isPending}
              className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 disabled:opacity-50"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={isPending}
              className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 text-sm font-medium disabled:opacity-50"
            >
              {isPending ? "Creating..." : "Create Task"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
