import { FormEvent, useEffect, useMemo, useState } from "react";

import {
  canManageTenantAccounts,
  getDefaultStaffPermissions,
  tenantPermissionOptions,
  type TenantPermission,
} from "../config/workspace";
import { usePortalSession } from "../context/PortalSessionContext";
import {
  createTenantUser,
  deleteTenantUser,
  fetchTenantUsers,
  type TenantStaffUser,
  type TenantStaffUserRequest,
  updateCurrentUserPassword,
  updateTenantUser
} from "../lib/api";
import { portalRuntimeConfig } from "../config/runtime";

const emptyCreateForm: TenantStaffUserRequest = {
  name: "",
  username: "",
  email: "",
  phone_number: "",
  password: "",
  permissions: getDefaultStaffPermissions(),
};

const emptyEditForm: TenantStaffUserRequest = {
  name: "",
  username: "",
  email: "",
  phone_number: "",
  password: "",
  permissions: [],
};

const emptySelfPasswordForm = {
  current_password: "",
  new_password: "",
  confirm_password: "",
};

function roleLabel(role: string): string {
  if (role === "owner") {
    return "Admin locale";
  }
  if (role === "staff") {
    return "Sotto-account";
  }
  return role;
}

function permissionLabel(permission: string): string {
  return tenantPermissionOptions.find((option) => option.key === permission)?.label ?? permission;
}

export function AccountPage() {
  const { currentUser, tenantContext } = usePortalSession();
  const [users, setUsers] = useState<TenantStaffUser[]>([]);
  const [selectedUserId, setSelectedUserId] = useState<string | null>(null);
  const [createForm, setCreateForm] = useState<TenantStaffUserRequest>(emptyCreateForm);
  const [editForm, setEditForm] = useState<TenantStaffUserRequest>(emptyEditForm);
  const [loading, setLoading] = useState(true);
  const [createBusy, setCreateBusy] = useState(false);
  const [saveBusy, setSaveBusy] = useState(false);
  const [deleteBusy, setDeleteBusy] = useState(false);
  const [selfPasswordBusy, setSelfPasswordBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [selfPasswordForm, setSelfPasswordForm] = useState(emptySelfPasswordForm);

  const canManage = canManageTenantAccounts(currentUser?.role);
  const ownerAccount = useMemo(
    () => users.find((user) => user.role === "owner") ?? null,
    [users]
  );
  const staffUsers = useMemo(
    () => users.filter((user) => user.role === "staff"),
    [users]
  );
  const selectedUser = useMemo(
    () => staffUsers.find((user) => user.id === selectedUserId) ?? null,
    [selectedUserId, staffUsers]
  );

  async function loadUsers(preferredUserId?: string | null) {
    const nextUsers = await fetchTenantUsers(portalRuntimeConfig.apiHubBaseUrl);
    setUsers(nextUsers);
    const nextStaffUsers = nextUsers.filter((user) => user.role === "staff");
    setSelectedUserId((current) => preferredUserId ?? current ?? nextStaffUsers[0]?.id ?? null);
  }

  useEffect(() => {
    if (!tenantContext) {
      return;
    }
    if (!canManage) {
      setLoading(false);
      return;
    }

    let cancelled = false;
    async function bootstrap() {
      try {
        await loadUsers();
      } catch (nextError) {
        if (!cancelled) {
          setError(nextError instanceof Error ? nextError.message : "Account del locale non disponibili.");
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    void bootstrap();
    return () => {
      cancelled = true;
    };
  }, [canManage, tenantContext]);

  useEffect(() => {
    if (!selectedUser) {
      setEditForm(emptyEditForm);
      return;
    }

    setEditForm({
      name: selectedUser.name ?? "",
      username: selectedUser.username ?? "",
      email: selectedUser.email,
      phone_number: selectedUser.phone_number ?? "",
      password: "",
      permissions: selectedUser.permissions ?? []
    });
  }, [selectedUser]);

  function toggleCreatePermission(permission: TenantPermission) {
    setCreateForm((current) => ({
      ...current,
      permissions: current.permissions.includes(permission)
        ? current.permissions.filter((item) => item !== permission)
        : [...current.permissions, permission]
    }));
  }

  function toggleEditPermission(permission: TenantPermission) {
    setEditForm((current) => ({
      ...current,
      permissions: current.permissions.includes(permission)
        ? current.permissions.filter((item) => item !== permission)
        : [...current.permissions, permission]
    }));
  }

  async function handleCreateSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setCreateBusy(true);
    setError(null);
    setSuccess(null);

    try {
      const created = await createTenantUser(portalRuntimeConfig.apiHubBaseUrl, createForm);
      await loadUsers(created.id);
      setCreateForm(emptyCreateForm);
      setSuccess(`Sotto-account ${created.name ?? created.email} creato.`);
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : "Creazione sotto-account non riuscita.");
    } finally {
      setCreateBusy(false);
    }
  }

  async function handleUpdateSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!selectedUser) {
      return;
    }

    setSaveBusy(true);
    setError(null);
    setSuccess(null);

    try {
      const updated = await updateTenantUser(portalRuntimeConfig.apiHubBaseUrl, selectedUser.id, editForm);
      await loadUsers(updated.id);
      setSuccess(`Sotto-account ${updated.name ?? updated.email} aggiornato.`);
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : "Aggiornamento sotto-account non riuscito.");
    } finally {
      setSaveBusy(false);
    }
  }

  async function handleDeleteSelected() {
    if (!selectedUser) {
      return;
    }
    const confirmed = window.confirm(`Vuoi eliminare il sotto-account ${selectedUser.name ?? selectedUser.email}?`);
    if (!confirmed) {
      return;
    }

    setDeleteBusy(true);
    setError(null);
    setSuccess(null);

    try {
      await deleteTenantUser(portalRuntimeConfig.apiHubBaseUrl, selectedUser.id);
      await loadUsers(null);
      setSuccess("Sotto-account eliminato.");
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : "Eliminazione sotto-account non riuscita.");
    } finally {
      setDeleteBusy(false);
    }
  }

  async function handleSelfPasswordSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setError(null);
    setSuccess(null);

    const currentPassword = selfPasswordForm.current_password.trim();
    const newPassword = selfPasswordForm.new_password.trim();
    const confirmPassword = selfPasswordForm.confirm_password.trim();

    if (!currentPassword) {
      setError("Inserisci la password attuale.");
      return;
    }
    if (!newPassword) {
      setError("Inserisci una nuova password.");
      return;
    }
    if (newPassword.length < 8) {
      setError("La nuova password deve avere almeno 8 caratteri.");
      return;
    }
    if (newPassword !== confirmPassword) {
      setError("La conferma password non coincide.");
      return;
    }

    setSelfPasswordBusy(true);
    try {
      await updateCurrentUserPassword(portalRuntimeConfig.apiHubBaseUrl, {
        current_password: currentPassword,
        new_password: newPassword
      });
      setSelfPasswordForm(emptySelfPasswordForm);
      setSuccess("Password aggiornata.");
    } catch (nextError) {
      setError(nextError instanceof Error ? nextError.message : "Cambio password non riuscito.");
    } finally {
      setSelfPasswordBusy(false);
    }
  }

  if (loading) {
    return (
      <section className="panel narrow-panel stack-md">
        <p className="eyebrow">Account</p>
        <h2 className="page-title">Carico gli accessi del locale</h2>
        <p className="muted-copy">Sto recuperando admin e sotto-account del team.</p>
      </section>
    );
  }

  return (
    <section className="stack-lg">
      {canManage ? (
        <section className="stats-grid">
          <article className="stat-card">
            <span>Admin locale</span>
            <strong>{ownerAccount ? 1 : 0}</strong>
            <small>{ownerAccount?.email ?? "Non configurato"}</small>
          </article>
          <article className="stat-card">
            <span>Sotto-account</span>
            <strong>{staffUsers.length}</strong>
            <small>La Home resta disponibile. Assistente e strumenti dipendono dai permessi che assegni</small>
          </article>
          <article className="stat-card">
            <span>Locale</span>
            <strong>{tenantContext?.venues[0]?.name ?? tenantContext?.tenant.name}</strong>
            <small>Gli account creati restano dentro questo tenant</small>
          </article>
        </section>
      ) : null}

      {error ? <p className="auth-error">{error}</p> : null}
      {success ? <div className="callout"><strong>Operazione completata</strong>{success}</div> : null}

      <section className="admin-layout">
        <section className="panel stack-md">
          <div className="panel-heading">
            <div>
              <p className="eyebrow">Profilo</p>
              <h3>Accesso corrente</h3>
            </div>
          </div>

          <div className="stack-sm">
            <p><strong>{currentUser?.name ?? currentUser?.email}</strong></p>
            <p className="muted-copy">{currentUser?.email}</p>
            <p className="muted-copy">{currentUser?.username}</p>
            <p className="muted-copy">{roleLabel(currentUser?.role ?? "")}</p>
            <p className="muted-copy">
              {canManage
                ? "Da qui puoi gestire anche i sotto-account del locale."
                : "Qui puoi aggiornare solo i dati del tuo accesso personale."}
            </p>
          </div>
        </section>

        <section className="panel stack-md">
          <div className="panel-heading">
            <div>
              <p className="eyebrow">Sicurezza</p>
              <h3>Cambia password</h3>
            </div>
          </div>

          <form className="mock-form" onSubmit={handleSelfPasswordSubmit}>
            <label className="field">
              <span>Password attuale</span>
              <input
                type="password"
                value={selfPasswordForm.current_password}
                onChange={(event) =>
                  setSelfPasswordForm((current) => ({ ...current, current_password: event.target.value }))
                }
                required
                minLength={1}
                disabled={selfPasswordBusy}
              />
            </label>

            <div className="auth-inline-grid">
              <label className="field">
                <span>Nuova password</span>
                <input
                  type="password"
                  value={selfPasswordForm.new_password}
                  onChange={(event) =>
                    setSelfPasswordForm((current) => ({ ...current, new_password: event.target.value }))
                  }
                  required
                  minLength={8}
                  disabled={selfPasswordBusy}
                />
              </label>
              <label className="field">
                <span>Conferma nuova password</span>
                <input
                  type="password"
                  value={selfPasswordForm.confirm_password}
                  onChange={(event) =>
                    setSelfPasswordForm((current) => ({ ...current, confirm_password: event.target.value }))
                  }
                  required
                  minLength={8}
                  disabled={selfPasswordBusy}
                />
              </label>
            </div>

            <button type="submit" className="button-primary" disabled={selfPasswordBusy}>
              {selfPasswordBusy ? "Aggiornamento in corso" : "Aggiorna password"}
            </button>
          </form>
        </section>
      </section>

      {canManage ? (
        <>

          <section className="admin-layout">
            <section className="panel stack-md">
              <div className="panel-heading">
                <div>
                  <p className="eyebrow">Admin locale</p>
                  <h3>Accesso principale</h3>
                </div>
              </div>

              {ownerAccount ? (
                <div className="stack-sm">
                  <p><strong>{ownerAccount.name ?? ownerAccount.email}</strong></p>
                  <p className="muted-copy">{ownerAccount.email}</p>
                  <p className="muted-copy">{ownerAccount.username}</p>
                  <p className="muted-copy">{roleLabel(ownerAccount.role)}</p>
                </div>
              ) : (
                <p className="muted-copy">Nessun admin principale trovato per questo locale.</p>
              )}
            </section>

            <section className="panel stack-md">
              <div className="panel-heading">
                <div>
                  <p className="eyebrow">Nuovo sotto-account</p>
                  <h3>Crea accesso per un dipendente</h3>
                </div>
              </div>

              <form className="mock-form" onSubmit={handleCreateSubmit}>
                <div className="auth-inline-grid">
                  <label className="field">
                    <span>Nome dipendente</span>
                    <input
                      type="text"
                      value={createForm.name}
                      onChange={(event) => setCreateForm((current) => ({ ...current, name: event.target.value }))}
                      required
                      minLength={2}
                      disabled={createBusy}
                    />
                  </label>
                  <label className="field">
                    <span>Username</span>
                    <input
                      type="text"
                      value={createForm.username}
                      onChange={(event) => setCreateForm((current) => ({ ...current, username: event.target.value }))}
                      required
                      minLength={3}
                      disabled={createBusy}
                    />
                  </label>
                </div>

                <div className="auth-inline-grid">
                  <label className="field">
                    <span>Email</span>
                    <input
                      type="email"
                      value={createForm.email}
                      onChange={(event) => setCreateForm((current) => ({ ...current, email: event.target.value }))}
                      required
                      disabled={createBusy}
                    />
                  </label>
                  <label className="field">
                    <span>Telefono</span>
                    <input
                      type="text"
                      value={createForm.phone_number}
                      onChange={(event) => setCreateForm((current) => ({ ...current, phone_number: event.target.value }))}
                      disabled={createBusy}
                    />
                  </label>
                </div>

                <label className="field">
                  <span>Password iniziale</span>
                  <input
                    type="password"
                    value={createForm.password}
                    onChange={(event) => setCreateForm((current) => ({ ...current, password: event.target.value }))}
                    required
                    minLength={8}
                    disabled={createBusy}
                  />
                </label>

                <div className="stack-sm">
                  <p className="muted-copy">
                    La Home del locale resta sempre disponibile. Qui decidi se abilitare l&apos;Assistente e a quali
                    moduli o attivita puo accedere il dipendente.
                  </p>
                  <div className="auth-inline-grid">
                    {tenantPermissionOptions.map((option) => (
                      <label key={option.key} className="field checkbox-field">
                        <span className="checkbox-row">
                          <input
                            type="checkbox"
                            checked={createForm.permissions.includes(option.key)}
                            onChange={() => toggleCreatePermission(option.key)}
                            disabled={createBusy}
                          />
                          <strong>{option.label}</strong>
                        </span>
                        <small>{option.description}</small>
                      </label>
                    ))}
                  </div>
                </div>

                <button type="submit" className="button-primary" disabled={createBusy}>
                  {createBusy ? "Creazione in corso" : "Crea sotto-account"}
                </button>
              </form>
            </section>
          </section>

          <section className="admin-layout">
            <section className="panel stack-md">
              <div className="panel-heading">
                <div>
                  <p className="eyebrow">Team</p>
                  <h3>Sotto-account attivi</h3>
                </div>
                <p>{staffUsers.length} profili</p>
              </div>

              <div className="admin-tenant-list">
                {staffUsers.length ? (
                  staffUsers.map((user) => (
                    <article key={user.id} className={`admin-tenant-card${selectedUserId === user.id ? " is-selected" : ""}`}>
                      <button type="button" className="admin-tenant-select" onClick={() => setSelectedUserId(user.id)}>
                        <strong>{user.name ?? user.email}</strong>
                        <span>{user.email}</span>
                        <small>{roleLabel(user.role)}</small>
                        <small>
                          {user.permissions.length
                            ? user.permissions.map(permissionLabel).join(", ")
                            : "Solo Home"}
                        </small>
                      </button>
                    </article>
                  ))
                ) : (
                  <p className="muted-copy">Non hai ancora creato sotto-account per il team.</p>
                )}
              </div>
            </section>

            <section className="panel stack-md">
              <div className="panel-heading">
                <div>
                  <p className="eyebrow">Modifica sotto-account</p>
                  <h3>Dati e password</h3>
                </div>
              </div>

              {selectedUser ? (
                <form className="mock-form" onSubmit={handleUpdateSubmit}>
                  <div className="auth-inline-grid">
                    <label className="field">
                      <span>Nome dipendente</span>
                      <input
                        type="text"
                        value={editForm.name}
                        onChange={(event) => setEditForm((current) => ({ ...current, name: event.target.value }))}
                        required
                        minLength={2}
                        disabled={saveBusy || deleteBusy}
                      />
                    </label>
                    <label className="field">
                      <span>Username</span>
                      <input
                        type="text"
                        value={editForm.username}
                        onChange={(event) => setEditForm((current) => ({ ...current, username: event.target.value }))}
                        required
                        minLength={3}
                        disabled={saveBusy || deleteBusy}
                      />
                    </label>
                  </div>

                  <div className="auth-inline-grid">
                    <label className="field">
                      <span>Email</span>
                      <input
                        type="email"
                        value={editForm.email}
                        onChange={(event) => setEditForm((current) => ({ ...current, email: event.target.value }))}
                        required
                        disabled={saveBusy || deleteBusy}
                      />
                    </label>
                    <label className="field">
                      <span>Telefono</span>
                      <input
                        type="text"
                        value={editForm.phone_number}
                        onChange={(event) => setEditForm((current) => ({ ...current, phone_number: event.target.value }))}
                        disabled={saveBusy || deleteBusy}
                      />
                    </label>
                  </div>

                  <label className="field">
                    <span>Nuova password</span>
                    <input
                      type="password"
                      value={editForm.password}
                      onChange={(event) => setEditForm((current) => ({ ...current, password: event.target.value }))}
                      minLength={8}
                      placeholder="Lascia vuoto per non cambiarla"
                      disabled={saveBusy || deleteBusy}
                    />
                  </label>

                  <div className="stack-sm">
                    <p className="muted-copy">
                      Se il dipendente prova a usare l&apos;Assistente o ad aprire una funzione non autorizzata, vedra
                      un avviso che lo invita a chiedere l&apos;abilitazione all&apos;amministratore.
                    </p>
                    <div className="auth-inline-grid">
                      {tenantPermissionOptions.map((option) => (
                        <label key={option.key} className="field checkbox-field">
                          <span className="checkbox-row">
                            <input
                              type="checkbox"
                              checked={editForm.permissions.includes(option.key)}
                              onChange={() => toggleEditPermission(option.key)}
                              disabled={saveBusy || deleteBusy}
                            />
                            <strong>{option.label}</strong>
                          </span>
                          <small>{option.description}</small>
                        </label>
                      ))}
                    </div>
                  </div>

                  <div className="inline-actions">
                    <button type="submit" className="button-primary" disabled={saveBusy || deleteBusy}>
                      {saveBusy ? "Salvataggio in corso" : "Salva sotto-account"}
                    </button>
                    <button
                      type="button"
                      className="button-secondary"
                      onClick={() => void handleDeleteSelected()}
                      disabled={saveBusy || deleteBusy}
                    >
                      {deleteBusy ? "Eliminazione in corso" : "Elimina sotto-account"}
                    </button>
                  </div>
                </form>
              ) : (
                <p className="muted-copy">Seleziona un sotto-account dalla lista per modificarlo.</p>
              )}
            </section>
          </section>
        </>
      ) : null}
    </section>
  );
}
