"use client";

import { useEffect, useState } from "react";
import { Table, TextField, SelectField, useToast } from "@nexarch/shl";
import type { TableColumn } from "@nexarch/shl";
import {
  ApiError,
  Assignment,
  Role,
  RoleInfo,
  assignRole,
  fetchRoleHistory,
  fetchRoles,
} from "../../lib/api";

export default function RolesPage() {
  const { push } = useToast();
  const [roles, setRoles] = useState<RoleInfo[] | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);

  const [targetUserId, setTargetUserId] = useState("");
  const [targetRole, setTargetRole] = useState<Role>("user");
  const [assignError, setAssignError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const [historyUserId, setHistoryUserId] = useState("");
  const [history, setHistory] = useState<Assignment[] | null>(null);

  useEffect(() => {
    fetchRoles()
      .then(setRoles)
      .catch(() => setLoadError("Rollen konnten nicht geladen werden. Sind Sie als Tenant-Admin angemeldet?"));
  }, []);

  async function onAssign(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setAssignError(null);
    setSubmitting(true);
    try {
      await assignRole(targetUserId, targetRole);
      push("Rolle zugewiesen.", "success");
    } catch (err) {
      // Akzeptanzkriterium 2: die Backend-Meldung bei Selbst-Eskalation wird
      // unveraendert angezeigt, keine eigene Interpretation im Frontend.
      setAssignError(err instanceof ApiError ? err.message : "Rolle konnte nicht zugewiesen werden.");
    } finally {
      setSubmitting(false);
    }
  }

  async function onLoadHistory(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    try {
      setHistory(await fetchRoleHistory(historyUserId));
    } catch {
      setHistory([]);
    }
  }

  const historyColumns: TableColumn<Assignment>[] = [
    { key: "role", header: "Rolle", render: (a) => a.Role },
    { key: "grantedBy", header: "Vergeben von", render: (a) => a.GrantedBy },
  ];

  if (loadError) {
    return (
      <main style={{ maxWidth: 640, margin: "40px auto", padding: "0 16px" }}>
        <p role="alert">{loadError}</p>
      </main>
    );
  }

  return (
    <main style={{ maxWidth: 640, margin: "40px auto", padding: "0 16px" }}>
      <h1>Rollen &amp; Rechte</h1>

      <section aria-labelledby="rollen-heading">
        <h2 id="rollen-heading">Rollen und Grundrechte</h2>
        {roles?.map((r) => (
          <div key={r.role} style={{ marginBottom: 12 }}>
            <strong>{roleLabel(r.role)}</strong>
            <ul>
              {r.permissions.map((p) => (
                <li key={p}>{p}</li>
              ))}
            </ul>
          </div>
        ))}
      </section>

      <section aria-labelledby="zuweisen-heading">
        <h2 id="zuweisen-heading">Rolle zuweisen</h2>
        <form onSubmit={onAssign} noValidate>
          <TextField
            label="Benutzer-ID"
            required
            value={targetUserId}
            onChange={(e) => setTargetUserId(e.target.value)}
          />
          <SelectField label="Rolle" value={targetRole} onChange={(e) => setTargetRole(e.target.value as Role)}>
            <option value="user">Benutzer</option>
            <option value="tenant_admin">Tenant-Admin</option>
          </SelectField>
          {assignError && (
            <p role="alert" style={{ color: "var(--shl-color-danger)" }}>
              {assignError}
            </p>
          )}
          <button type="submit" disabled={submitting}>
            {submitting ? "Wird zugewiesen…" : "Zuweisen"}
          </button>
        </form>
      </section>

      <section aria-labelledby="verlauf-heading">
        <h2 id="verlauf-heading">Nachvollziehbarkeit (Audit-Verlauf)</h2>
        <p>Zeigt jede Rollenzuweisung eines Benutzers chronologisch — wer wann welche Rolle vergeben hat.</p>
        <form onSubmit={onLoadHistory} noValidate>
          <TextField
            label="Benutzer-ID"
            required
            value={historyUserId}
            onChange={(e) => setHistoryUserId(e.target.value)}
          />
          <button type="submit">Verlauf anzeigen</button>
        </form>
        {history && (
          <Table
            columns={historyColumns}
            rows={history}
            rowKey={(a) => `${a.UserID}-${a.Role}-${a.GrantedBy}`}
            caption="Rollenzuweisungs-Verlauf"
          />
        )}
      </section>
    </main>
  );
}

function roleLabel(role: Role): string {
  return role === "tenant_admin" ? "Tenant-Admin" : "Benutzer";
}
