"use client";

import { useState } from "react";
import type { RoleWithResourceCount } from "@nexus/shared";
import { trpc } from "~/lib/trpc/client.js";
import { RoleModal } from "./RoleModal.js";
import { FilterChips } from "~/components/ui/FilterChips.js";
import { SortableColumnHeader } from "~/components/ui/SortableColumnHeader.js";
import { useTableSort } from "~/hooks/useTableSort.js";
import { useViewPrefs } from "~/hooks/useViewPrefs.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";

export function RolesClient() {
  const [search, setSearch] = useState("");
  const [showInactive, setShowInactive] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [editRole, setEditRole] = useState<RoleWithResourceCount | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<RoleWithResourceCount | null>(null);
  const [actionError, setActionError] = useState<string | null>(null);

  const utils = trpc.useUtils();

  const { data: roles, isLoading } = trpc.role.list.useQuery(
    { isActive: showInactive ? undefined : true, search: search || undefined },
    { placeholderData: (prev) => prev, staleTime: 60_000 },
  );

  const deactivateMutation = trpc.role.deactivate.useMutation({
    onSuccess: async () => {
      await utils.role.list.invalidate();
    },
    onError: (err) => setActionError(err.message),
  });

  const activateMutation = trpc.role.update.useMutation({
    onSuccess: async () => {
      await utils.role.list.invalidate();
    },
    onError: (err) => setActionError(err.message),
  });

  const deleteMutation = trpc.role.delete.useMutation({
    onSuccess: async () => {
      await utils.role.list.invalidate();
      setConfirmDelete(null);
    },
    onError: (err) => {
      setActionError(err.message);
      setConfirmDelete(null);
    },
  });

  function openCreate() {
    setEditRole(null);
    setModalOpen(true);
  }

  function openEdit(role: RoleWithResourceCount) {
    setEditRole(role);
    setModalOpen(true);
  }

  const roleList = (roles ?? []) as unknown as RoleWithResourceCount[];

  const rolesViewPrefs = useViewPrefs("roles");
  const { sorted, sortField, sortDir, toggle } = useTableSort(roleList, {
    initialField: rolesViewPrefs.savedSort?.field ?? null,
    initialDir: rolesViewPrefs.savedSort?.dir ?? null,
    onSortChange: (field, dir) => {
      rolesViewPrefs.setSavedSort(field && dir ? { field, dir } : null);
    },
  });

  function clearAll() {
    setSearch("");
    setShowInactive(false);
  }

  const chips = [
    ...(search ? [{ label: `Search: "${search}"`, onRemove: () => setSearch("") }] : []),
    ...(showInactive
      ? [{ label: "Inactive included", onRemove: () => setShowInactive(false) }]
      : []),
  ];

  return (
    <div className="app-page mx-auto max-w-6xl space-y-5">
      <div className="app-page-header gap-4">
        <div>
          <h1 className="app-page-title">Roles</h1>
          <p className="app-page-subtitle mt-1">Manage role definitions and resource assignments</p>
        </div>
        <button
          type="button"
          onClick={openCreate}
          className="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-brand-700"
        >
          New Role
        </button>
      </div>

      <div className="app-toolbar flex flex-wrap items-center gap-3">
        <input
          type="text"
          placeholder="Search roles…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="app-input w-64"
        />
        <label className="flex cursor-pointer items-center gap-2 rounded-xl border border-gray-200 bg-gray-50 px-3 py-2 text-sm text-gray-600 dark:border-gray-700 dark:bg-gray-900/70 dark:text-gray-300">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={(e) => setShowInactive(e.target.checked)}
            className="rounded border-gray-300"
          />
          Show inactive
        </label>
      </div>

      {chips.length > 0 && (
        <div className="mb-3">
          <FilterChips chips={chips} onClearAll={clearAll} />
        </div>
      )}

      {actionError && (
        <div className="flex items-center justify-between rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/30 dark:text-red-300">
          {actionError}
          <button
            type="button"
            onClick={() => setActionError(null)}
            className="text-red-400 hover:text-red-600 text-lg leading-none"
          >
            &times;
          </button>
        </div>
      )}

      <div className="app-data-table">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-gray-200 dark:border-gray-700">
              <SortableColumnHeader
                label="Name"
                field="name"
                sortField={sortField}
                sortDir={sortDir}
                onSort={toggle}
                tooltip="Role name (e.g. 3D Artist, Producer). Shown in timeline bars and staffing views."
              />
              <th className="text-left px-4 py-3 font-medium text-gray-600 dark:text-gray-400 text-xs uppercase tracking-wider">
                <span className="inline-flex items-center gap-0.5">
                  Description
                  <InfoTooltip content="Optional description of the role's responsibilities and typical work." />
                </span>
              </th>
              <SortableColumnHeader
                label="Resources"
                field="resourceRoles"
                sortField={sortField}
                sortDir={sortDir}
                onSort={(f) => toggle(f, (r) => r._count.resourceRoles)}
                align="center"
                tooltip="Number of resources that currently have this role assigned (active assignments only)."
              />
              <SortableColumnHeader
                label="Allocations"
                field="allocations"
                sortField={sortField}
                sortDir={sortDir}
                onSort={(f) => toggle(f, (r) => r._count.allocations)}
                align="center"
                tooltip="Total number of planning entries that use this role, including open-demand compatibility rows."
              />
              <SortableColumnHeader
                label="Status"
                field="isActive"
                sortField={sortField}
                sortDir={sortDir}
                onSort={(f) => toggle(f, (r) => (r.isActive ? 0 : 1))}
                align="center"
                tooltip="Active roles are available for assignment. Inactive roles are hidden from pickers but existing assignments remain."
              />
              <th className="text-right px-4 py-3 font-medium text-gray-600 dark:text-gray-400 text-xs uppercase tracking-wider">
                Actions
              </th>
            </tr>
          </thead>
          <tbody>
            {isLoading && (
              <tr>
                <td colSpan={6} className="py-12 text-center text-gray-400">
                  Loading…
                </td>
              </tr>
            )}
            {!isLoading && sorted.length === 0 && (
              <tr>
                <td colSpan={6} className="py-12 text-center text-gray-400">
                  No roles found. Create one to get started.
                </td>
              </tr>
            )}
            {sorted.map((role) => (
              <tr
                key={role.id}
                className="border-b border-gray-100 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/30 transition-colors"
              >
                <td className="px-4 py-3">
                  <div className="flex items-center gap-2">
                    <div
                      className="w-3 h-3 rounded-full flex-shrink-0"
                      style={{ backgroundColor: role.color ?? "#6366f1" }}
                    />
                    <span className="font-medium text-gray-900 dark:text-gray-100">
                      {role.name}
                    </span>
                  </div>
                </td>
                <td className="px-4 py-3 text-gray-500 dark:text-gray-400 max-w-xs truncate">
                  {role.description ?? <span className="italic text-gray-300">—</span>}
                </td>
                <td className="px-4 py-3 text-center">
                  <span className="inline-flex items-center justify-center w-8 h-6 rounded bg-gray-100 dark:bg-gray-800 text-xs font-medium text-gray-600 dark:text-gray-400">
                    {role._count.resourceRoles}
                  </span>
                </td>
                <td className="px-4 py-3 text-center">
                  <span className="inline-flex items-center justify-center w-8 h-6 rounded bg-gray-100 dark:bg-gray-800 text-xs font-medium text-gray-600 dark:text-gray-400">
                    {role._count.allocations}
                  </span>
                </td>
                <td className="px-4 py-3 text-center">
                  <span
                    className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${
                      role.isActive
                        ? "bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400"
                        : "bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400"
                    }`}
                  >
                    {role.isActive ? "Active" : "Inactive"}
                  </span>
                </td>
                <td className="px-4 py-3">
                  <div className="flex items-center justify-end gap-2">
                    <button
                      type="button"
                      onClick={() => openEdit(role)}
                      className="text-xs text-brand-600 hover:text-brand-800 font-medium"
                    >
                      Edit
                    </button>
                    {role.isActive && (
                      <button
                        type="button"
                        onClick={() => {
                          setActionError(null);
                          deactivateMutation.mutate({ id: role.id });
                        }}
                        disabled={deactivateMutation.isPending}
                        className="text-xs text-gray-500 hover:text-gray-700"
                      >
                        Deactivate
                      </button>
                    )}
                    {!role.isActive && (
                      <button
                        type="button"
                        onClick={() => {
                          setActionError(null);
                          activateMutation.mutate({ id: role.id, data: { isActive: true } });
                        }}
                        disabled={activateMutation.isPending}
                        className="text-xs text-green-600 hover:text-green-800 font-medium"
                      >
                        Enable
                      </button>
                    )}
                    <button
                      type="button"
                      onClick={() => {
                        setConfirmDelete(role);
                        setActionError(null);
                      }}
                      className="app-action-delete"
                    >
                      Delete
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {modalOpen && (
        <RoleModal
          role={editRole}
          onClose={() => setModalOpen(false)}
          onSuccess={() => setModalOpen(false)}
        />
      )}

      {confirmDelete && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/55 px-4 backdrop-blur-sm">
          <div className="w-full max-w-sm rounded-3xl border border-gray-200 bg-white p-6 shadow-2xl dark:border-gray-700 dark:bg-gray-900">
            <h3 className="mb-2 text-lg font-semibold text-gray-900 dark:text-gray-100">
              Delete Role
            </h3>
            <p className="mb-4 text-sm text-gray-600 dark:text-gray-400">
              Are you sure you want to delete <strong>{confirmDelete.name}</strong>?
              {(confirmDelete._count.resourceRoles > 0 || confirmDelete._count.allocations > 0) && (
                <span className="block mt-1 text-amber-600">
                  This role is assigned to {confirmDelete._count.resourceRoles} resource(s) and{" "}
                  {confirmDelete._count.allocations} allocation(s). Deletion will be blocked.
                </span>
              )}
            </p>
            <div className="flex justify-end gap-3">
              <button
                type="button"
                onClick={() => setConfirmDelete(null)}
                className="rounded-xl px-4 py-2 text-sm font-medium text-gray-600 transition hover:bg-gray-100 hover:text-gray-800 dark:text-gray-300 dark:hover:bg-gray-800"
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={() => deleteMutation.mutate({ id: confirmDelete.id })}
                disabled={deleteMutation.isPending}
                className="rounded-xl bg-red-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-red-700 disabled:opacity-50"
              >
                {deleteMutation.isPending ? "Deleting…" : "Delete"}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
