import { useCallback, useEffect, useState } from "react";
import { Save } from "lucide-react";
import { PermissionScope } from "omsorgcore-client-ts";
import OmsorgButton from "../../components/ui/OmsorgButton";
import { MODULE_OPTIONS, ACTION_OPTIONS, SCOPE_OPTIONS, SCOPE_CAPABLE_MODULES } from "./permissionOptions";

function permissionKey(module, action) {
  return `${module}:${action}`;
}

// grants: Map<"module:action", PermissionScope> - Abwesenheit eines Eintrags = kein Zugriff.
export default function RolePermissionMatrix({ roleId, roleName, canEdit }) {
  const [grants, setGrants] = useState(() => new Map());
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState(null);
  const [savedMessage, setSavedMessage] = useState(null);

  const loadRole = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    setSavedMessage(null);
    const result = await window.omsorg.roles.get(roleId);
    if (result.ok) {
      setGrants(new Map(result.data.permissions.map((p) => [permissionKey(p.module, p.action), p.scope ?? PermissionScope.All])));
    } else {
      setError("Rechte konnten nicht geladen werden.");
    }
    setIsLoading(false);
  }, [roleId]);

  useEffect(() => {
    loadRole();
  }, [loadRole]);

  function toggle(module, action) {
    if (!canEdit) return;
    const key = permissionKey(module, action);
    setGrants((prev) => {
      const next = new Map(prev);
      if (next.has(key)) {
        next.delete(key);
      } else {
        next.set(key, PermissionScope.All);
      }
      return next;
    });
  }

  function setScope(module, action, rawValue) {
    if (!canEdit) return;
    const key = permissionKey(module, action);
    setGrants((prev) => {
      const next = new Map(prev);
      if (rawValue === "") {
        next.delete(key);
      } else {
        next.set(key, rawValue);
      }
      return next;
    });
  }

  async function handleSave() {
    setIsSaving(true);
    setError(null);
    setSavedMessage(null);

    const permissions = Array.from(grants.entries()).map(([key, scope]) => {
      const [module, action] = key.split(":");
      return { module, action, scope };
    });

    const result = await window.omsorg.roles.updatePermissions(roleId, { permissions });

    setIsSaving(false);
    if (!result.ok) {
      setError("Rechte konnten nicht gespeichert werden.");
      return;
    }
    setSavedMessage("Gespeichert.");
  }

  if (isLoading) {
    return <p>Lädt...</p>;
  }

  return (
    <div className="settings-permission-matrix">
      <h3>Rechte-Matrix: {roleName}</h3>
      {error && <p className="login-error">{error}</p>}

      <div className="settings-permission-matrix-scroll">
        <table>
          <thead>
            <tr>
              <th></th>
              {ACTION_OPTIONS.map((action) => (
                <th key={action.value}>{action.label}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {MODULE_OPTIONS.map((module) => {
              const scopeCapable = SCOPE_CAPABLE_MODULES.includes(module.value);
              return (
                <tr key={module.value}>
                  <td>{module.label}</td>
                  {ACTION_OPTIONS.map((action) => {
                    const key = permissionKey(module.value, action.value);
                    if (scopeCapable) {
                      return (
                        <td key={action.value}>
                          <select
                            value={grants.get(key) ?? ""}
                            onChange={(e) => setScope(module.value, action.value, e.target.value)}
                            disabled={!canEdit}
                          >
                            <option value="">Kein Zugriff</option>
                            {SCOPE_OPTIONS.map((scope) => (
                              <option key={scope.value} value={scope.value}>
                                {scope.label}
                              </option>
                            ))}
                          </select>
                        </td>
                      );
                    }
                    return (
                      <td key={action.value}>
                        <input
                          type="checkbox"
                          checked={grants.has(key)}
                          onChange={() => toggle(module.value, action.value)}
                          disabled={!canEdit}
                        />
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {canEdit && (
        <div className="settings-permission-matrix-actions">
          <OmsorgButton icon={Save} onClick={handleSave} disabled={isSaving}>
            {isSaving ? "Speichert..." : "Speichern"}
          </OmsorgButton>
          {savedMessage && <span className="debug-sessions-meta">{savedMessage}</span>}
        </div>
      )}
    </div>
  );
}
