"use client";

import { useMemo, useState } from "react";

type Permission = {
  id: string;
  code: string;
  name: string;
  module: string;
};

export default function PermissionPicker({
  permissions,
}: {
  permissions: Permission[];
}) {
  const [search, setSearch] = useState("");
  const [selected, setSelected] = useState<string[]>([]);

  const groups = useMemo(() => {
    const query = search.trim().toLowerCase();
    const result = new Map<string, Permission[]>();

    for (const permission of permissions) {
      const searchable = [
        permission.name,
        permission.code,
        permission.module,
      ]
        .join(" ")
        .toLowerCase();

      if (query && !searchable.includes(query)) {
        continue;
      }

      const group = permission.module || "GENERAL";

      result.set(group, [
        ...(result.get(group) ?? []),
        permission,
      ]);
    }

    return [...result.entries()].sort(([a], [b]) =>
      a.localeCompare(b),
    );
  }, [permissions, search]);

  function toggle(code: string, checked: boolean) {
    setSelected((current) =>
      checked
        ? [...new Set([...current, code])]
        : current.filter((item) => item !== code),
    );
  }

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div>
          <h3 className="text-base font-bold text-slate-900">
            Assign Permissions
          </h3>
          <p className="mt-1 text-sm text-slate-500">
            Select only the permissions this role requires.
          </p>
        </div>

        <span
          aria-live="polite"
          className="rounded-full bg-blue-50 px-4 py-2 text-sm font-bold text-blue-700"
        >
          {selected.length} / {permissions.length} selected
        </span>
      </div>

      <label className="block">
        <span className="sr-only">Search permissions</span>
        <input
          type="search"
          value={search}
          onChange={(event) => setSearch(event.target.value)}
          placeholder="Search by permission name, code or module..."
          className="w-full rounded-xl border border-slate-300 bg-white px-4 py-3 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
        />
      </label>

      {permissions.length === 0 ? (
        <p className="rounded-xl bg-amber-50 p-4 text-sm text-amber-800">
          No permissions are configured. Role creation is unavailable.
        </p>
      ) : groups.length === 0 ? (
        <p className="rounded-xl bg-slate-50 p-4 text-sm text-slate-600">
          No permissions match your search.
        </p>
      ) : (
        <div className="grid items-start gap-4 xl:grid-cols-2">
          {groups.map(([module, items]) => {
            const selectedInGroup = items.filter((item) =>
              selected.includes(item.code),
            ).length;

            return (
              <details
                key={module}
                open={search.trim() ? true : undefined}
                className="min-w-0 overflow-hidden rounded-xl border border-slate-200 bg-white"
              >
                <summary className="cursor-pointer bg-slate-50 px-4 py-3 font-bold text-slate-800">
                  <span className="flex flex-wrap items-center justify-between gap-2">
                    <span>{module}</span>
                    <span className="text-xs font-semibold text-slate-500">
                      {selectedInGroup} / {items.length} selected
                    </span>
                  </span>
                </summary>

                <div className="grid gap-2 p-3 sm:grid-cols-2">
                  {items.map((permission) => (
                    <label
                      key={permission.id}
                      className="flex min-w-0 cursor-pointer items-start gap-3 rounded-lg border border-slate-200 p-3 transition hover:border-blue-300 hover:bg-blue-50/40"
                    >
                      <input
                        type="checkbox"
                        name="permissionCodes"
                        value={permission.code}
                        checked={selected.includes(permission.code)}
                        onChange={(event) =>
                          toggle(
                            permission.code,
                            event.target.checked,
                          )
                        }
                        className="mt-1 h-4 w-4 shrink-0 accent-blue-700"
                      />

                      <span className="min-w-0">
                        <span className="block text-sm font-semibold text-slate-800">
                          {permission.name}
                        </span>
                        <span className="mt-1 block break-all text-xs text-slate-500">
                          {permission.code}
                        </span>
                      </span>
                    </label>
                  ))}
                </div>
              </details>
            );
          })}
        </div>
      )}

      <p className="text-xs text-slate-500">
        Permission selection is submitted only when you click
        Create Role. Searching does not change your selections.
      </p>
    </div>
  );
}
