import { useEffect, useState } from "react";

import { FormActions } from "./EmployeeForm";
import { useAuth } from "../../app/AuthContext";
import ModalPortal from "../../components/ui/ModalPortal";

const PIN_VALIDITY_OPTIONS = [1, 3, 7, 14];
const DEFAULT_PIN_VALIDITY_DAYS = 7;

function suggestUsername(employee) {
  const first = (employee.firstName ?? "").trim().toLowerCase();
  const last = (employee.lastName ?? "").trim().toLowerCase();
  return `${first}.${last}`.replace(/\s+/g, "");
}

function errorMessage(result) {
  if (result.status === 403) {
    return "Keine Berechtigung, Accounts anzulegen.";
  }
  if (result.status === 404) {
    return "Mitarbeiter oder Rolle nicht gefunden.";
  }
  if (result.status === 409) {
    return typeof result.data === "string" ? result.data : "Dieser Mitarbeiter oder Username ist bereits vergeben.";
  }
  if (result.status === 400) {
    return typeof result.data === "string" ? result.data : "Eingaben prüfen.";
  }
  return "Account konnte nicht angelegt werden.";
}

export default function CreateUserAccountDialog({ employee, onClose, onCreated }) {
  const { passwordMinLength } = useAuth();
  const [username, setUsername] = useState(() => suggestUsername(employee));
  const [roles, setRoles] = useState([]);
  const [roleId, setRoleId] = useState("");
  const [mode, setMode] = useState("Invite");
  const [pinValidityDays, setPinValidityDays] = useState(DEFAULT_PIN_VALIDITY_DAYS);
  const [initialPassword, setInitialPassword] = useState("");
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function loadRoles() {
      const result = await window.omsorg.roles.list();
      if (result.ok) {
        const data = result.data ?? [];
        setRoles(data);
        if (data.length > 0) {
          setRoleId(data[0].id);
        }
      }
    }
    loadRoles();
  }, []);

  async function handleSubmit(event) {
    event.preventDefault();

    if (!username.trim()) {
      setError("Username ist erforderlich.");
      return;
    }

    if (!roleId) {
      setError("Rolle ist erforderlich.");
      return;
    }

    if (mode === "Direct" && initialPassword.trim().length < passwordMinLength) {
      setError(`Initiales Passwort muss mindestens ${passwordMinLength} Zeichen lang sein.`);
      return;
    }

    setIsSaving(true);
    setError(null);

    const result = await window.omsorg.users.create({
      employeeId: employee.id,
      username: username.trim(),
      roleId,
      mode,
      initialPassword: mode === "Direct" ? initialPassword : null,
      pinValidityDays: mode === "Invite" ? pinValidityDays : null,
    });

    setIsSaving(false);

    if (!result.ok) {
      setError(errorMessage(result));
      return;
    }

    onCreated(result.data);
  }

  return (
    <ModalPortal>
      <div className="modal-overlay" role="dialog" aria-modal="true" aria-label="Account anlegen">
        <div className="modal-panel">
          <h2>Account für {employee.firstName} {employee.lastName} anlegen</h2>

          <form onSubmit={handleSubmit}>
            <label className="form-field">
              <span>Username</span>
              <input
                type="text"
                value={username}
                onChange={(event) => setUsername(event.target.value)}
              />
            </label>

            <label className="form-field">
              <span>Rolle</span>
              <select value={roleId} onChange={(event) => setRoleId(event.target.value)}>
                {roles.map((role) => (
                  <option key={role.id} value={role.id}>
                    {role.name}
                  </option>
                ))}
              </select>
            </label>

            <fieldset className="form-field">
              <legend>Zugang</legend>

              <label>
                <input
                  type="radio"
                  name="mode"
                  value="Invite"
                  checked={mode === "Invite"}
                  onChange={() => setMode("Invite")}
                />
                Einladung per Mail (Mitarbeiter setzt eigenes Passwort)
              </label>

              <label>
                <input
                  type="radio"
                  name="mode"
                  value="Direct"
                  checked={mode === "Direct"}
                  onChange={() => setMode("Direct")}
                />
                Passwort direkt vergeben (muss beim ersten Login geändert werden)
              </label>
            </fieldset>

            {mode === "Invite" && (
              <label className="form-field">
                <span>PIN gültig für</span>
                <select
                  value={pinValidityDays}
                  onChange={(event) => setPinValidityDays(Number(event.target.value))}
                >
                  {PIN_VALIDITY_OPTIONS.map((days) => (
                    <option key={days} value={days}>
                      {days} {days === 1 ? "Tag" : "Tage"}
                      {days === DEFAULT_PIN_VALIDITY_DAYS ? " (Standard)" : ""}
                    </option>
                  ))}
                </select>
              </label>
            )}

            {mode === "Direct" && (
              <label className="form-field">
                <span>Initiales Passwort</span>
                <input
                  type="text"
                  value={initialPassword}
                  onChange={(event) => setInitialPassword(event.target.value)}
                  placeholder={`Mindestens ${passwordMinLength} Zeichen`}
                />
              </label>
            )}

            {error && <p className="login-error form-error">{error}</p>}

            <FormActions onCancel={onClose} isSaving={isSaving} submitLabel="Anlegen" />
          </form>
        </div>
      </div>
    </ModalPortal>
  );
}
