/* global React, Icon */
const {
  useEffect: useEffectUsers,
  useMemo: useMemoUsers,
  useState: useStateUsers,
} = React;

function UsersPage() {
  const [currentUser, setCurrentUser] = useStateUsers(null);
  const [users, setUsers] = useStateUsers([]);
  const [workspaceOptions, setWorkspaceOptions] = useStateUsers([]);
  const [loading, setLoading] = useStateUsers(true);
  const [saving, setSaving] = useStateUsers(false);
  const [error, setError] = useStateUsers('');
  const [notice, setNotice] = useStateUsers('');
  const [editingUser, setEditingUser] = useStateUsers(null);
  const [deleteTarget, setDeleteTarget] = useStateUsers(null);

  const emptyForm = {
    fullName: '',
    email: '',
    password: '',
    role: 'user',
    createWorkspaceName: '',
    assignedWorkspaceIds: [],
  };

  const [form, setForm] = useStateUsers(emptyForm);
  const [editForm, setEditForm] = useStateUsers({
    fullName: '',
    role: 'user',
    password: '',
    assignedWorkspaceIds: [],
  });

  const currentRole = String(currentUser?.role || 'user').toLowerCase();
  const canManage = currentRole === 'owner' || currentRole === 'admin';
  const roleOptions = currentRole === 'owner' ? ['admin', 'user'] : ['user'];

  const sortedWorkspaceOptions = useMemoUsers(() => (
    Array.isArray(workspaceOptions) ? workspaceOptions : []
  ), [workspaceOptions]);

  useEffectUsers(() => {
    let isMounted = true;

    async function loadData() {
      setLoading(true);
      setError('');
      setNotice('');

      try {
        const authData = await fetchJson('/api/auth/me');
        const usersData = await fetchJson('/api/users');

        if (!isMounted) return;

        setCurrentUser(authData.user || null);
        setUsers(Array.isArray(usersData.users) ? usersData.users : []);
        setWorkspaceOptions(Array.isArray(usersData.workspaces) ? usersData.workspaces : []);
      } catch (err) {
        if (isMounted) {
          setError(err.message || 'Unable to load users.');
        }
      } finally {
        if (isMounted) {
          setLoading(false);
        }
      }
    }

    loadData();

    return () => {
      isMounted = false;
    };
  }, []);

  const refreshUsers = async () => {
    const data = await fetchJson('/api/users');
    setUsers(Array.isArray(data.users) ? data.users : []);
    setWorkspaceOptions(Array.isArray(data.workspaces) ? data.workspaces : []);
  };

  const updateForm = (key, value) => {
    setForm(prev => ({
      ...prev,
      [key]: value,
    }));
  };

  const updateEditForm = (key, value) => {
    setEditForm(prev => ({
      ...prev,
      [key]: value,
    }));
  };

  const toggleFormWorkspace = workspaceId => {
    setForm(prev => ({
      ...prev,
      assignedWorkspaceIds: toggleId(prev.assignedWorkspaceIds, workspaceId),
    }));
  };

  const toggleEditWorkspace = workspaceId => {
    setEditForm(prev => ({
      ...prev,
      assignedWorkspaceIds: toggleId(prev.assignedWorkspaceIds, workspaceId),
    }));
  };

  const createUser = async event => {
    event.preventDefault();
    setSaving(true);
    setError('');
    setNotice('');

    try {
      await fetchJson('/api/users', {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
        },
        body: JSON.stringify(form),
      });

      setForm(emptyForm);
      setNotice('User created successfully.');
      await refreshUsers();
    } catch (err) {
      setError(err.message || 'Unable to create user.');
    } finally {
      setSaving(false);
    }
  };

  const openEditUser = user => {
    setEditingUser(user);
    setError('');
    setNotice('');
    setEditForm({
      fullName: user.fullName || '',
      role: normalizeRole(user.role),
      password: '',
      assignedWorkspaceIds: Array.isArray(user.assignedWorkspaceIds) ? user.assignedWorkspaceIds : [],
    });
  };

  const submitEditUser = async event => {
    event.preventDefault();

    if (!editingUser) return;

    setSaving(true);
    setError('');
    setNotice('');

    try {
      await fetchJson(`/api/users/${encodeURIComponent(editingUser.userId)}`, {
        method: 'PATCH',
        headers: {
          'content-type': 'application/json',
        },
        body: JSON.stringify(editForm),
      });

      setEditingUser(null);
      setNotice('User updated successfully.');
      await refreshUsers();
    } catch (err) {
      setError(err.message || 'Unable to update user.');
    } finally {
      setSaving(false);
    }
  };

  const confirmDeleteUser = async () => {
    if (!deleteTarget) return;

    setSaving(true);
    setError('');
    setNotice('');

    try {
      await fetchJson(`/api/users/${encodeURIComponent(deleteTarget.userId)}`, {
        method: 'DELETE',
      });

      setDeleteTarget(null);
      setNotice('User deleted successfully.');
      await refreshUsers();
    } catch (err) {
      setError(err.message || 'Unable to delete user.');
    } finally {
      setSaving(false);
    }
  };

  if (!loading && !canManage) {
    return (
      <div className="view">
        <div className="view-head">
          <div>
            <h1>Users</h1>
            <div className="sub">You do not have permission to manage users.</div>
          </div>
        </div>
      </div>
    );
  }

  const isEditingSelf = editingUser && currentUser?.userId === editingUser.userId;

  return (
    <div className="view users-page">
      <div className="view-head">
        <div>
          <h1>Users</h1>
          <div className="sub">Create users, assign workspaces, and manage role-based access.</div>
        </div>
      </div>

      {error && <div className="users-alert error">{error}</div>}
      {notice && <div className="users-alert success">{notice}</div>}

      <div className="users-layout">
        <form className="card users-form-card" onSubmit={createUser}>
          <div className="users-card-head">
            <div>
              <h2>Create user</h2>
              <p>Add an Admin or User and control their workspace access.</p>
            </div>
          </div>

          <div className="form-grid">
            <label className="field">
              <span>Name</span>
              <input
                value={form.fullName}
                onChange={event => updateForm('fullName', event.target.value)}
                placeholder="User name"
                required
              />
            </label>

            <label className="field">
              <span>Email</span>
              <input
                type="email"
                value={form.email}
                onChange={event => updateForm('email', event.target.value)}
                placeholder="user@example.com"
                required
              />
            </label>

            <label className="field">
              <span>Temporary password</span>
              <input
                type="text"
                value={form.password}
                onChange={event => updateForm('password', event.target.value)}
                placeholder="At least 8 chars, A-z, 0-9, symbol"
                required
              />
            </label>

            <label className="field">
              <span>Role</span>
              <select value={form.role} onChange={event => updateForm('role', event.target.value)}>
                {roleOptions.map(role => (
                  <option key={role} value={role}>{formatRole(role)}</option>
                ))}
              </select>
            </label>
          </div>

          <label className="field users-full-field">
            <span>Create dedicated workspace</span>
            <input
              value={form.createWorkspaceName}
              onChange={event => updateForm('createWorkspaceName', event.target.value)}
              placeholder="Example: XYZ Workspace"
            />
            <small>If this is filled, this workspace will belong to the new user.</small>
          </label>

          <WorkspacePicker
            title="Assign existing workspaces"
            description="Selected workspaces will be available after login."
            workspaces={sortedWorkspaceOptions}
            selectedIds={form.assignedWorkspaceIds}
            onToggle={toggleFormWorkspace}
          />

          <div className="users-actions-row">
            <button className="btn btn-primary" type="submit" disabled={saving}>
              <Icon name="users" size={14}/>Create user
            </button>
          </div>
        </form>

        <div className="card users-table-card">
          <div className="users-card-head table-head">
            <div>
              <h2>Account users</h2>
              <p>Review roles, workspace access, and management actions.</p>
            </div>
          </div>

          <div className="app-table-scroll users-table-wrap">
            <table className="users-table">
              <thead>
                <tr>
                  <th>User</th>
                  <th>Role</th>
                  <th>Workspaces</th>
                  <th>Status</th>
                  <th>Actions</th>
                </tr>
              </thead>
              <tbody>
                {loading ? (
                  <tr>
                    <td colSpan="5" className="users-empty">Loading users…</td>
                  </tr>
                ) : users.length ? (
                  users.map(user => {
                    const editable = canUpdateUserInUi(currentUser, user);
                    const deletable = canDeleteUserInUi(currentUser, user);

                    return (
                      <tr key={user.userId}>
                        <td>
                          <div className="users-name">{user.fullName || 'Unnamed user'}</div>
                          <div className="users-email">{user.email}</div>
                        </td>
                        <td>
                          <span className={`role-pill ${normalizeRole(user.role)}`}>
                            {formatRole(user.role)}
                          </span>
                        </td>
                        <td>
                          <WorkspaceSummary workspaces={user.workspaces} />
                        </td>
                        <td>
                          <span className="pill success">Active</span>
                        </td>
                        <td>
                          <div className="users-row-actions">
                            <button
                                className="btn btn-secondary"
                                type="button"
                                onClick={() => openEditUser(user)}
                                disabled={!editable || saving}
                                >
                                Edit
                                </button>
                                <button
                                  className="btn btn-secondary danger"
                                  type="button"
                                  onClick={() => setDeleteTarget(user)}
                                  disabled={!deletable || saving}
                                  title={!deletable ? getDeleteDisabledReason(currentUser, user) : ''}>
                                  Delete
                              </button>
                          </div>
                        </td>
                      </tr>
                    );
                  })
                ) : (
                  <tr>
                    <td colSpan="5" className="users-empty">No users found.</td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      {editingUser && (
        <div className="users-modal-backdrop" role="presentation">
          <form className="users-modal" onSubmit={submitEditUser}>
            <div className="users-modal-head">
              <div>
                <h2>Edit user</h2>
                <p>{editingUser.email}</p>
              </div>
              <button className="icon-btn" type="button" onClick={() => setEditingUser(null)}>×</button>
            </div>

            <div className="form-grid">
              <label className="field">
                <span>Name</span>
                <input
                  value={editForm.fullName}
                  onChange={event => updateEditForm('fullName', event.target.value)}
                  required
                />
              </label>

              <label className="field">
                <span>Role</span>
                <select
                    value={editForm.role}
                    onChange={event => updateEditForm('role', event.target.value)}
                    disabled={isEditingSelf || currentRole !== 'owner'}
                    >
                  {roleOptions.map(role => (
                    <option key={role} value={role}>{formatRole(role)}</option>
                  ))}
                </select>
              </label>
            </div>

            <label className="field users-full-field">
              <span>Reset password</span>
              <input
                type="text"
                value={editForm.password}
                onChange={event => updateEditForm('password', event.target.value)}
                placeholder="Leave blank to keep current password"
              />
            </label>

            {isEditingSelf ? (
              <div className="users-self-note">
                {getSelfEditNote(currentUser)}
              </div>
            ) : (
              <WorkspacePicker
                title="Workspace access"
                description="Update the workspaces this user can access."
                workspaces={sortedWorkspaceOptions}
                selectedIds={editForm.assignedWorkspaceIds}
                onToggle={toggleEditWorkspace}
              />
            )}

            <div className="users-modal-actions">
              <button className="btn btn-secondary" type="button" onClick={() => setEditingUser(null)}>
                Cancel
              </button>
              <button className="btn btn-primary" type="submit" disabled={saving}>
                Save changes
              </button>
            </div>
          </form>
        </div>
      )}

      {deleteTarget && (
        <div className="users-modal-backdrop" role="presentation">
          <div className="users-modal small">
            <div className="users-modal-head">
              <div>
                <h2>Delete user?</h2>
                <p>{deleteTarget.fullName || deleteTarget.email}</p>
              </div>
              <button className="icon-btn" type="button" onClick={() => setDeleteTarget(null)}>×</button>
            </div>

            <p className="users-delete-copy">
              This will remove the user login access and active sessions. Workspace data will remain available to the account.
            </p>

            <div className="users-modal-actions">
              <button className="btn btn-secondary" type="button" onClick={() => setDeleteTarget(null)}>
                Cancel
              </button>
              <button className="btn btn-secondary danger" type="button" onClick={confirmDeleteUser} disabled={saving}>
                Delete user
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function WorkspacePicker({ title, description, workspaces, selectedIds, onToggle }) {
  return (
    <div className="workspace-picker">
      <div className="workspace-picker-head">
        <div>{title}</div>
        <span>{selectedIds.length} selected</span>
      </div>
      <p>{description}</p>

      <div className="workspace-option-list">
        {workspaces.length ? workspaces.map(workspace => (
          <label key={workspace.workspaceId} className="workspace-option">
            <input
              type="checkbox"
              checked={selectedIds.includes(workspace.workspaceId)}
              onChange={() => onToggle(workspace.workspaceId)}
            />
            <span className="workspace-option-body">
              <span className="workspace-option-title">{workspace.name}</span>
              <span className="workspace-option-meta">
                {workspace.ownerName || 'Unknown user'}
                <small>{formatRole(workspace.ownerRole)}</small>
              </span>
            </span>
          </label>
        )) : (
          <div className="workspace-empty">No workspace available.</div>
        )}
      </div>
    </div>
  );
}

function WorkspaceSummary({ workspaces }) {
  const items = Array.isArray(workspaces) ? workspaces : [];

  if (!items.length) {
    return <span className="users-email">No workspace assigned</span>;
  }

  return (
    <div className="workspace-summary">
      {items.slice(0, 3).map(workspace => (
        <span key={workspace.workspaceId} className="workspace-chip">
          {workspace.name}
          <small>{workspace.ownerName || 'Unknown user'} · {formatRole(workspace.ownerRole)}</small>
        </span>
      ))}
      {items.length > 3 && (
        <span className="workspace-chip muted">+{items.length - 3} more</span>
      )}
    </div>
  );
}

async function fetchJson(url, options = {}) {
  const response = await fetch(url, {
    credentials: 'include',
    cache: 'no-store',
    ...options,
  });
  const data = await response.json().catch(() => ({}));

  if (!response.ok || !data.ok) {
    throw new Error(data.error || 'Request failed.');
  }

  return data;
}

function canUpdateUserInUi(currentUser, targetUser) {
  const currentRole = normalizeRole(currentUser?.role);
  const targetRole = normalizeRole(targetUser?.role);

  if (!currentUser || !targetUser) return false;

  if (currentUser.userId === targetUser.userId) {
    return currentRole === 'owner' || currentRole === 'admin';
  }

  if (currentRole === 'owner') {
    return targetRole !== 'owner';
  }

  if (currentRole === 'admin') {
    return targetRole === 'user';
  }

  return false;
}

function canDeleteUserInUi(currentUser, targetUser) {
  const currentRole = normalizeRole(currentUser?.role);
  const targetRole = normalizeRole(targetUser?.role);

  if (!currentUser || !targetUser) return false;
  if (currentUser.userId === targetUser.userId) return false;
  if (targetRole === 'owner') return false;

  if (currentRole === 'owner') {
    return true;
  }

  if (currentRole === 'admin') {
    return targetRole === 'user';
  }

  return false;
}

function getDeleteDisabledReason(currentUser, targetUser) {
  const targetRole = normalizeRole(targetUser?.role);

  if (!currentUser || !targetUser) {
    return 'Delete is not available.';
  }

  if (currentUser.userId === targetUser.userId) {
    return 'You cannot delete your own account.';
  }

  if (targetRole === 'owner') {
    return 'Owner accounts cannot be deleted here.';
  }

  return 'You do not have permission to delete this user.';
}

function getSelfEditNote(currentUser) {
  const role = normalizeRole(currentUser?.role);

  if (role === 'owner') {
    return 'You can update your name and reset your password. Owner role, account ownership, and default workspace protection cannot be changed from this panel.';
  }

  if (role === 'admin') {
    return 'You can update your name and reset your password. Workspace access and role changes must be managed by the account owner.';
  }

  return 'You can update your name and reset your password.';
}

function toggleId(items, id) {
  const values = Array.isArray(items) ? items : [];
  return values.includes(id)
    ? values.filter(item => item !== id)
    : [...values, id];
}

function normalizeRole(role) {
  const value = String(role || 'user').toLowerCase();
  return ['owner', 'admin', 'user'].includes(value) ? value : 'user';
}

function formatRole(role) {
  const value = normalizeRole(role);
  return value.charAt(0).toUpperCase() + value.slice(1);
}

window.UsersPage = UsersPage;