"use client";

import { useEffect, useReducer, useRef } from "react";
import { AdminUserRow, UpdateAdminUserInput } from "@/actions/admin/users";
import { formatDate } from "@/lib/format-date";
import CreateUserModal from "./CreateUserModal";

type UsersPageProps = {
  initialUsers: AdminUserRow[];
  brands: { id: string; name: string }[];
  currentUser: {
    id: string;
    role: string;
    can_manage_users?: boolean;
  };
  onUserCreated?: (user: AdminUserRow) => void;
};

type PasswordModal = {
  email: string;
  tempPassword: string | null;
  message: string | null;
  loading: boolean;
  error: string | null;
};

const FLAG_LABELS: Record<string, string> = {
  can_manage_products: "Products",
  can_manage_stops: "Stops",
  can_manage_orders: "Orders",
  can_manage_pickup: "Pickup",
  can_manage_messages: "Messages",
  can_manage_refunds: "Refunds",
  can_manage_users: "Users",
  can_manage_water_log: "Water Log",
  can_manage_reports: "Reports",
};

const ALL_FLAGS = Object.keys(FLAG_LABELS);

const roleColors: Record<string, string> = {
  platform_admin: "bg-purple-100 text-purple-700",
  brand_admin: "bg-blue-100 text-blue-700",
  store_employee: "bg-emerald-100 text-emerald-700",
  staff: "bg-stone-100 text-stone-600",
};

function RoleBadge({ role }: { role: string }) {
  return (
    <span className={`rounded-full px-2.5 py-0.5 text-xs font-semibold capitalize ${roleColors[role] ?? "bg-stone-100 text-stone-600"}`}>
      {role.replace("_", " ")}
    </span>
  );
}

type EditingUser = {
  id?: string;
  email?: string;
  password?: string;
  display_name?: string;
  phone_number?: string;
  role: "platform_admin" | "brand_admin" | "store_employee";
  brand_id: string | null;
  flags: Record<string, boolean>;
  active?: boolean;
  isNew: boolean;
};

const defaultFlags: Record<string, boolean> = {
  can_manage_products: false,
  can_manage_stops: false,
  can_manage_orders: false,
  can_manage_pickup: false,
  can_manage_messages: false,
  can_manage_refunds: false,
  can_manage_users: false,
  can_manage_water_log: false,
  can_manage_reports: false,
};

function emptyEditing(isNew: boolean): EditingUser {
  return {
    isNew,
    role: "store_employee",
    brand_id: null,
    display_name: "",
    phone_number: "",
    password: "",
    flags: { ...defaultFlags },
  };
}

function editingFromRow(row: AdminUserRow): EditingUser {
  return {
    id: row.id,
    email: row.email,
    display_name: row.display_name ?? "",
    phone_number: row.phone_number ?? "",
    role: row.role as "platform_admin" | "brand_admin" | "store_employee",
    brand_id: row.brand_id,
    flags: {
      can_manage_products: row.can_manage_products,
      can_manage_stops: row.can_manage_stops,
      can_manage_orders: row.can_manage_orders,
      can_manage_pickup: row.can_manage_pickup,
      can_manage_messages: row.can_manage_messages,
      can_manage_refunds: row.can_manage_refunds,
      can_manage_users: row.can_manage_users,
      can_manage_water_log: row.can_manage_water_log,
      can_manage_reports: row.can_manage_reports,
    },
    active: row.active,
    isNew: false,
  };
}

// ── State / reducer ───────────────────────────────────────────────────────────

type State = {
  users: AdminUserRow[];
  panelOpen: boolean;
  showCreateModal: boolean;
  editing: EditingUser;
  saving: boolean;
  error: string | null;
  deleteConfirmId: string | null;
  actionMenuId: string | null;
  passwordModal: PasswordModal | null;
  success: string | null;
};

type Action =
  | { type: "SET_USERS"; users: AdminUserRow[] }
  | { type: "PREPEND_USER"; user: AdminUserRow }
  | { type: "REPLACE_USER"; user: AdminUserRow }
  | { type: "REMOVE_USER"; id: string }
  | { type: "OPEN_PANEL"; editing: EditingUser }
  | { type: "CLOSE_PANEL" }
  | { type: "OPEN_CREATE_MODAL" }
  | { type: "CLOSE_CREATE_MODAL" }
  | { type: "SET_EDITING"; editing: EditingUser }
  | { type: "SET_SAVING"; value: boolean }
  | { type: "SET_ERROR"; value: string | null }
  | { type: "SET_DELETE_CONFIRM"; id: string | null }
  | { type: "SET_ACTION_MENU"; id: string | null }
  | { type: "SET_PASSWORD_MODAL"; modal: PasswordModal | null }
  | { type: "SET_SUCCESS"; value: string | null }
  | { type: "TOGGLE_MUST_CHANGE_PASSWORD"; id: string };

function initState(initialUsers: AdminUserRow[]): State {
  return {
    users: initialUsers,
    panelOpen: false,
    showCreateModal: false,
    editing: emptyEditing(true),
    saving: false,
    error: null,
    deleteConfirmId: null,
    actionMenuId: null,
    passwordModal: null,
    success: null,
  };
}

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_USERS":
      return { ...state, users: action.users };
    case "PREPEND_USER":
      return { ...state, users: [action.user, ...state.users] };
    case "REPLACE_USER":
      return {
        ...state,
        users: state.users.map((u) => (u.id === action.user.id ? action.user : u)),
      };
    case "REMOVE_USER":
      return { ...state, users: state.users.filter((u) => u.id !== action.id) };
    case "OPEN_PANEL":
      return { ...state, panelOpen: true, editing: action.editing };
    case "CLOSE_PANEL":
      return { ...state, panelOpen: false, editing: emptyEditing(true), error: null };
    case "OPEN_CREATE_MODAL":
      return { ...state, showCreateModal: true };
    case "CLOSE_CREATE_MODAL":
      return { ...state, showCreateModal: false };
    case "SET_EDITING":
      return { ...state, editing: action.editing };
    case "SET_SAVING":
      return { ...state, saving: action.value };
    case "SET_ERROR":
      return { ...state, error: action.value };
    case "SET_DELETE_CONFIRM":
      return { ...state, deleteConfirmId: action.id };
    case "SET_ACTION_MENU":
      return { ...state, actionMenuId: action.id };
    case "SET_PASSWORD_MODAL":
      return { ...state, passwordModal: action.modal };
    case "SET_SUCCESS":
      return { ...state, success: action.value };
    case "TOGGLE_MUST_CHANGE_PASSWORD":
      return {
        ...state,
        users: state.users.map((u) =>
          u.id === action.id ? { ...u, must_change_password: true } : u
        ),
      };
  }
}

// ── Custom hook: action handlers ──────────────────────────────────────────────

type ActionHandlers = {
  handleUserCreated: (user: AdminUserRow) => void;
  openEdit: (row: AdminUserRow) => void;
  closePanel: () => void;
  setRole: (role: EditingUser["role"]) => void;
  setBrand: (brandId: string | null) => void;
  toggleFlag: (flag: string) => void;
  setActive: (active: boolean) => void;
  handleSave: () => Promise<void>;
  handleDelete: (id: string) => Promise<void>;
  handleResetPassword: (email: string) => Promise<void>;
  handleForcePasswordChange: (id: string) => Promise<void>;
  handleSendResetLink: (email: string) => Promise<void>;
  copyTempPassword: () => void;
};

function useUserActions(
  state: State,
  dispatch: (action: Action) => void,
  onUserCreated?: (user: AdminUserRow) => void,
): ActionHandlers {
  const resetLinkLoadingRef = useRef<string | null>(null);

  function handleUserCreated(user: AdminUserRow) {
    dispatch({ type: "PREPEND_USER", user });
    onUserCreated?.(user);
  }

  function openEdit(row: AdminUserRow) {
    dispatch({ type: "OPEN_PANEL", editing: editingFromRow(row) });
    dispatch({ type: "SET_ERROR", value: null });
  }

  function closePanel() {
    dispatch({ type: "CLOSE_PANEL" });
  }

  function setRole(role: EditingUser["role"]) {
    dispatch({ type: "SET_EDITING", editing: { ...state.editing, role } });
  }

  function setBrand(brand_id: string | null) {
    dispatch({ type: "SET_EDITING", editing: { ...state.editing, brand_id } });
  }

  function toggleFlag(flag: string) {
    dispatch({
      type: "SET_EDITING",
      editing: {
        ...state.editing,
        flags: { ...state.editing.flags, [flag]: !state.editing.flags[flag] },
      },
    });
  }

  function setActive(active: boolean) {
    dispatch({ type: "SET_EDITING", editing: { ...state.editing, active } });
  }

  async function handleSave() {
    dispatch({ type: "SET_SAVING", value: true });
    dispatch({ type: "SET_ERROR", value: null });
    try {
      if (state.editing.isNew) {
        const res = await import("@/actions/admin/users").then((m) =>
          m.createAdminUser({
            email: state.editing.email!,
            password: state.editing.password!,
            display_name: state.editing.display_name || undefined,
            phone_number: state.editing.phone_number || undefined,
            role: state.editing.role,
            brand_id: state.editing.brand_id,
            flags: state.editing.flags,
            mustChangePassword: true,
          })
        );
        if (res.error) {
          dispatch({
            type: "SET_ERROR",
            value: formatAuthError(res.error),
          });
          return;
        }
        if (res.user) {
          dispatch({ type: "PREPEND_USER", user: res.user });
          // Surface the temp password — the slide-in panel has no
          // success view. The modal is the primary create flow, but
          // we don't want to silently lose the password here.
          if (res.tempPassword) {
            window.alert(
              `User created. Temporary password (share with the user — it will not be shown again):\n\n${res.tempPassword}`,
            );
          }
        }
      } else {
        const res = await import("@/actions/admin/users").then((m) =>
          m.updateAdminUser({
            id: state.editing.id!,
            role: state.editing.role,
            brand_id: state.editing.brand_id,
            flags: state.editing.flags,
            active: state.editing.active,
            display_name: state.editing.display_name === "" ? null : state.editing.display_name || undefined,
            phone_number: state.editing.phone_number === "" ? null : state.editing.phone_number || undefined,
          })
        );
        if (res.error) {
          dispatch({ type: "SET_ERROR", value: formatAuthError(res.error) });
          return;
        }
        if (res.user) dispatch({ type: "REPLACE_USER", user: res.user });
      }
      closePanel();
    } finally {
      dispatch({ type: "SET_SAVING", value: false });
    }
  }

  async function handleDelete(id: string) {
    const res = await import("@/actions/admin/users").then((m) => m.deleteAdminUser(id));
    if (res.error) {
      dispatch({ type: "SET_ERROR", value: res.error });
      return;
    }
    dispatch({ type: "REMOVE_USER", id });
    dispatch({ type: "SET_DELETE_CONFIRM", id: null });
  }

  async function handleResetPassword(email: string) {
    dispatch({
      type: "SET_PASSWORD_MODAL",
      modal: { email, tempPassword: null, message: null, loading: true, error: null },
    });
    try {
      const { resetAdminPassword } = await import("@/actions/admin/reset-admin");
      const result = await resetAdminPassword(email);
      if (result.success) {
        if (result.method === "reset_link_sent") {
          dispatch({
            type: "SET_PASSWORD_MODAL",
            modal: {
              email,
              tempPassword: null,
              message: result.message,
              loading: false,
              error: null,
            },
          });
        } else {
          dispatch({
            type: "SET_PASSWORD_MODAL",
            modal: {
              email,
              tempPassword: result.tempPassword,
              message: null,
              loading: false,
              error: null,
            },
          });
        }
      } else {
        dispatch({
          type: "SET_PASSWORD_MODAL",
          modal: {
            email,
            tempPassword: null,
            message: null,
            loading: false,
            error: result.error ?? "Failed to reset password",
          },
        });
      }
    } catch (e: unknown) {
      dispatch({
        type: "SET_PASSWORD_MODAL",
        modal: {
          email,
          tempPassword: null,
          message: null,
          loading: false,
          error: e instanceof Error ? e.message : "Error",
        },
      });
    }
  }

  async function handleForcePasswordChange(id: string) {
    try {
      const { setMustChangePassword } = await import("@/actions/admin/users");
      const res = await setMustChangePassword(id);
      if (res.error) throw new Error(res.error);
      dispatch({ type: "TOGGLE_MUST_CHANGE_PASSWORD", id });
    } catch (e: unknown) {
      dispatch({
        type: "SET_ERROR",
        value: e instanceof Error ? e.message : "Failed to require password change",
      });
    }
  }

  async function handleSendResetLink(email: string) {
    resetLinkLoadingRef.current = email;
    dispatch({ type: "SET_ERROR", value: null });
    dispatch({ type: "SET_SUCCESS", value: null });
    try {
      const { sendPasswordResetEmail } = await import("@/actions/admin/users");
      const result = await sendPasswordResetEmail(email);
      resetLinkLoadingRef.current = null;
      if (result.error) throw new Error(result.error);
      dispatch({ type: "SET_SUCCESS", value: `Password-reset email sent to ${email}.` });
    } catch (e: unknown) {
      resetLinkLoadingRef.current = null;
      dispatch({
        type: "SET_ERROR",
        value: e instanceof Error ? e.message : "Failed to send reset email",
      });
    }
  }

  function copyTempPassword() {
    if (state.passwordModal?.tempPassword) {
      navigator.clipboard.writeText(state.passwordModal.tempPassword).catch(() => {});
    }
  }

  return {
    handleUserCreated,
    openEdit,
    closePanel,
    setRole,
    setBrand,
    toggleFlag,
    setActive,
    handleSave,
    handleDelete,
    handleResetPassword,
    handleForcePasswordChange,
    handleSendResetLink,
    copyTempPassword,
  };
}

export default function UsersPage({ initialUsers, brands, currentUser, onUserCreated }: UsersPageProps) {
  const [state, dispatch] = useReducer(reducer, initialUsers, initState);

  // Auto-dismiss the success banner after 6 seconds.
  useEffect(() => {
    if (!state.success) return;
    const t = setTimeout(() => dispatch({ type: "SET_SUCCESS", value: null }), 6000);
    return () => clearTimeout(t);
  }, [state.success]);

  const handlers = useUserActions(state, dispatch, onUserCreated);

  const canManageUsers: boolean =
    currentUser.role === "platform_admin" ||
    (currentUser.role === "brand_admin" && Boolean(currentUser.can_manage_users));

  useEffect(() => {
    if (!state.panelOpen) return;
    function onPointerDown(e: PointerEvent) {
      const dialog = document.querySelector("[data-panel-dialog]") as HTMLDialogElement | null;
      if (!dialog) return;
      const rect = dialog.getBoundingClientRect();
      if (
        e.clientX < rect.left ||
        e.clientX > rect.right ||
        e.clientY < rect.top ||
        e.clientY > rect.bottom
      ) {
        dispatch({ type: "CLOSE_PANEL" });
      }
    }
    document.addEventListener("pointerdown", onPointerDown);
    return () => document.removeEventListener("pointerdown", onPointerDown);
  }, [state.panelOpen, dispatch]);

  const showBrandSelect = state.editing.role === "brand_admin" || state.editing.role === "store_employee";
  const availableRoles: EditingUser["role"][] =
    currentUser.role === "platform_admin"
      ? ["platform_admin", "brand_admin", "store_employee"]
      : ["brand_admin", "store_employee"];

  return (
    <>
      <UsersHeader
        userCount={state.users.length}
        canManageUsers={canManageUsers}
        onCreate={() => dispatch({ type: "OPEN_CREATE_MODAL" })}
      />

      <UsersBanner
        success={state.success}
        error={state.error}
        onDismissSuccess={() => dispatch({ type: "SET_SUCCESS", value: null })}
        onDismissError={() => dispatch({ type: "SET_ERROR", value: null })}
      />

      <UsersTable
        users={state.users}
        currentUser={currentUser}
        canManageUsers={canManageUsers}
        actionMenuId={state.actionMenuId}
        onEdit={handlers.openEdit}
        onToggleActionMenu={(id) =>
          dispatch({ type: "SET_ACTION_MENU", id: state.actionMenuId === id ? null : id })
        }
        onResetPassword={(email) => {
          dispatch({ type: "SET_ACTION_MENU", id: null });
          handlers.handleResetPassword(email);
        }}
        onForcePasswordChange={(id) => {
          dispatch({ type: "SET_ACTION_MENU", id: null });
          handlers.handleForcePasswordChange(id);
        }}
        onSendResetLink={(email) => {
          dispatch({ type: "SET_ACTION_MENU", id: null });
          handlers.handleSendResetLink(email);
        }}
        onRequestDelete={(id) => {
          dispatch({ type: "SET_ACTION_MENU", id: null });
          dispatch({ type: "SET_DELETE_CONFIRM", id });
        }}
      />

      <UsersDeleteConfirm
        onCancel={() => dispatch({ type: "SET_DELETE_CONFIRM", id: null })}
        onConfirm={() => state.deleteConfirmId && handlers.handleDelete(state.deleteConfirmId)}
      />

      <UsersEditPanel
        open={state.panelOpen}
        editing={state.editing}
        saving={state.saving}
        brands={brands}
        availableRoles={availableRoles}
        showBrandSelect={showBrandSelect}
        onClose={handlers.closePanel}
        onSave={handlers.handleSave}
        onChangeEditing={(editing) => dispatch({ type: "SET_EDITING", editing })}
        onRoleChange={handlers.setRole}
        onBrandChange={handlers.setBrand}
        onToggleFlag={handlers.toggleFlag}
        onToggleActive={handlers.setActive}
      />

      <UsersPasswordModal
        modal={state.passwordModal}
        onClose={() => dispatch({ type: "SET_PASSWORD_MODAL", modal: null })}
        onCopy={handlers.copyTempPassword}
      />

      <CreateUserModal
        isOpen={state.showCreateModal}
        onClose={() => dispatch({ type: "CLOSE_CREATE_MODAL" })}
        onSuccess={handlers.handleUserCreated}
        brands={brands}
        currentUser={{
          role: currentUser.role,
        }}
      />
    </>
  );
}

function formatAuthError(rawError: string): string {
  if (rawError === "Not authenticated" || rawError.includes("session") || rawError.includes("authenticated")) {
    return "Your session may have expired. Please log in again.";
  }
  if (rawError.includes("permission") || rawError.includes("Insufficient permissions")) {
    return "You do not have permission to edit this user.";
  }
  return rawError;
}

// ── Sub-components ────────────────────────────────────────────────────────────

function UsersHeader({
  userCount,
  canManageUsers,
  onCreate,
}: {
  userCount: number;
  canManageUsers: boolean;
  onCreate: () => void;
}) {
  return (
    <div className="mb-6 flex items-center justify-between">
      <div>
        <h2 className="text-xl font-semibold text-stone-900">{userCount} user{userCount !== 1 ? "s" : ""}</h2>
      </div>
      {canManageUsers && (
        <button type="button"
          onClick={onCreate}
          className="rounded-lg bg-stone-900 px-4 py-2 text-sm font-medium text-white hover:bg-stone-800"
         aria-label="+ Create User">
          + Create User
        </button>
      )}
    </div>
  );
}

function UsersBanner({
  success,
  error,
  onDismissSuccess,
  onDismissError,
}: {
  success: string | null;
  error: string | null;
  onDismissSuccess: () => void;
  onDismissError: () => void;
}) {
  if (!success && !error) return null;
  return (
    <>
      {success && (
        <div className="mb-4 flex items-start justify-between rounded-lg bg-emerald-50 p-4 text-sm text-emerald-800 gap-3 border border-emerald-200">
          <span>✓ {success}</span>
          <button type="button" onClick={onDismissSuccess} className="text-emerald-500 hover:text-emerald-700 shrink-0" aria-label="Dismiss">
            <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
      )}

      {error && (
        <div className="mb-4 flex items-start justify-between rounded-lg bg-red-50 p-4 text-sm text-red-700 gap-3 border border-red-200">
          <span>{error}</span>
          <button type="button" onClick={onDismissError} className="text-red-400 hover:text-red-600 shrink-0" aria-label="Close">
            <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
      )}
    </>
  );
}

function UsersTable({
  users,
  currentUser,
  canManageUsers,
  actionMenuId,
  onEdit,
  onToggleActionMenu,
  onResetPassword,
  onForcePasswordChange,
  onSendResetLink,
  onRequestDelete,
}: {
  users: AdminUserRow[];
  currentUser: UsersPageProps["currentUser"];
  canManageUsers: boolean;
  actionMenuId: string | null;
  onEdit: (user: AdminUserRow) => void;
  onToggleActionMenu: (id: string) => void;
  onResetPassword: (email: string) => void;
  onForcePasswordChange: (id: string) => void;
  onSendResetLink: (email: string) => void;
  onRequestDelete: (id: string) => void;
}) {
  return (
    <div className="overflow-visible rounded-xl bg-white shadow-sm ring-1 ring-stone-200">
      <table className="w-full text-left text-sm">
        <thead className="bg-stone-50 text-stone-500">
          <tr>
            <th className="px-5 py-4 font-semibold">Name</th>
            <th className="px-5 py-4 font-semibold">Phone</th>
            <th className="px-5 py-4 font-semibold">Role</th>
            <th className="px-5 py-4 font-semibold">Brand</th>
            <th className="px-5 py-4 font-semibold">Status</th>
            <th className="px-5 py-4 font-semibold">Created</th>
            {canManageUsers && <th className="px-5 py-4 font-semibold" aria-label="Actions" />}
          </tr>
        </thead>
        <tbody className="divide-y divide-stone-100">
          {users.map((user) => (
            <UsersTableRow
              key={user.id}
              user={user}
              currentUser={currentUser}
              canManageUsers={canManageUsers}
              actionMenuId={actionMenuId}
              onEdit={onEdit}
              onToggleActionMenu={onToggleActionMenu}
              onResetPassword={onResetPassword}
              onForcePasswordChange={onForcePasswordChange}
              onSendResetLink={onSendResetLink}
              onRequestDelete={onRequestDelete}
            />
          ))}
          {users.length === 0 && (
            <tr>
              <td colSpan={7} className="px-5 py-12 text-center text-stone-400">
                No users found.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
}

function UsersTableRow({
  user,
  currentUser,
  canManageUsers,
  actionMenuId,
  onEdit,
  onToggleActionMenu,
  onResetPassword,
  onForcePasswordChange,
  onSendResetLink,
  onRequestDelete,
}: {
  user: AdminUserRow;
  currentUser: UsersPageProps["currentUser"];
  canManageUsers: boolean;
  actionMenuId: string | null;
  onEdit: (user: AdminUserRow) => void;
  onToggleActionMenu: (id: string) => void;
  onResetPassword: (email: string) => void;
  onForcePasswordChange: (id: string) => void;
  onSendResetLink: (email: string) => void;
  onRequestDelete: (id: string) => void;
}) {
  const menuOpen = actionMenuId === user.id;

  return (
    <tr className="hover:bg-stone-50">
      <td className="px-5 py-4">
        <div className="font-medium text-stone-900">{user.display_name || user.email}</div>
        {user.display_name && user.display_name !== "No Name" && (
          <div className="text-xs text-stone-500">{user.email}</div>
        )}
      </td>
      <td className="px-5 py-4 text-stone-500 text-sm">{user.phone_number ?? "—"}</td>
      <td className="px-5 py-4">
        <RoleBadge role={user.role} />
      </td>
      <td className="px-5 py-4 text-stone-500">{user.brand_name ?? "—"}</td>
      <td className="px-5 py-4">
        <span className={`rounded-full px-2 py-0.5 text-xs font-medium ${user.active ? "bg-emerald-100 text-emerald-700" : "bg-stone-100 text-stone-500"}`}>
          {user.active ? "Active" : "Inactive"}
        </span>
      </td>
      <td className="px-5 py-4 text-stone-400 text-xs">
        {formatDate(new Date(user.created_at))}
      </td>
      {canManageUsers && (
        <td className="px-5 py-4">
          <div className="flex items-center gap-3">
            <button type="button"
              onClick={() => onEdit(user)}
              className="text-xs font-medium text-stone-500 hover:text-stone-900"
             aria-label="Edit">
              Edit
            </button>
            <div className="relative overflow-visible">
              <button type="button"
                onClick={() => onToggleActionMenu(user.id)}
                className="text-base font-medium text-stone-400 hover:text-stone-600 px-2 py-1"
                title="More actions"
               aria-label="More actions">
                ⁝
              </button>
              {menuOpen && (
                <UsersActionMenu
                  user={user}
                  currentUserId={currentUser.id}
                  onResetPassword={onResetPassword}
                  onForcePasswordChange={onForcePasswordChange}
                  onSendResetLink={onSendResetLink}
                  onRequestDelete={onRequestDelete}
                  onClose={() => onToggleActionMenu(user.id)}
                />
              )}
            </div>
          </div>
        </td>
      )}
    </tr>
  );
}

function UsersActionMenu({
  user,
  currentUserId,
  onResetPassword,
  onForcePasswordChange,
  onSendResetLink,
  onRequestDelete,
  onClose,
}: {
  user: AdminUserRow;
  currentUserId: string;
  onResetPassword: (email: string) => void;
  onForcePasswordChange: (id: string) => void;
  onSendResetLink: (email: string) => void;
  onRequestDelete: (id: string) => void;
  onClose: () => void;
}) {
  return (
    <>
      <button type="button" aria-label="Close menu" className="fixed inset-0 z-40 cursor-default bg-transparent border-0 p-0" onClick={onClose} />
      <div className="absolute right-0 z-50 mt-1 w-48 rounded-xl bg-white shadow-xl ring-1 ring-stone-200 border border-stone-100 py-1 text-xs overflow-visible">
        <div className="px-3 py-2 text-[10px] font-semibold uppercase tracking-wider text-stone-400 border-b border-stone-100">
          Actions
        </div>
        <button type="button"
          onClick={() => { onClose(); onResetPassword(user.email); }}
          className="w-full text-left px-3 py-2.5 text-stone-700 hover:bg-stone-50 flex items-center gap-2"
        >
          🔑 Reset Password
        </button>
        <button type="button"
          onClick={() => { onClose(); onForcePasswordChange(user.id); }}
          className="w-full text-left px-3 py-2.5 text-stone-700 hover:bg-stone-50 flex items-center gap-2"
         aria-label="↪ Require Password Change">
          ↪ Require Password Change
        </button>
        <button type="button"
          onClick={() => { onClose(); onSendResetLink(user.email); }}
          className="w-full text-left px-3 py-2.5 text-stone-700 hover:bg-stone-50 flex items-center gap-2"
         aria-label="✉ Send Reset Email">
          ✉ Send Reset Email
        </button>
        {user.id !== currentUserId && (
          <button type="button"
            onClick={() => { onClose(); onRequestDelete(user.id); }}
            className="w-full text-left px-3 py-2.5 text-red-600 hover:bg-red-50 flex items-center gap-2 border-t border-stone-100 mt-1 pt-1"
           aria-label="🗑 Delete">
            🗑 Delete
          </button>
        )}
      </div>
    </>
  );
}

function UsersDeleteConfirm({
  onCancel,
  onConfirm,
}: {
  onCancel: () => void;
  onConfirm: () => void;
}) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
      <div className="w-96 rounded-2xl bg-white p-6 shadow-xl ring-1 ring-stone-200">
        <h3 className="text-lg font-bold text-stone-900">Delete user?</h3>
        <p className="mt-2 text-sm text-stone-600">
          This will remove their admin access. Their auth account will remain active.
        </p>
        <div className="mt-6 flex justify-end gap-3">
          <button type="button"
            onClick={onCancel}
            className="rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium text-stone-600 hover:bg-stone-50"
           aria-label="Cancel">
            Cancel
          </button>
          <button type="button"
            onClick={onConfirm}
            className="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700"
           aria-label="Delete">
            Delete
          </button>
        </div>
      </div>
    </div>
  );
}

function UsersEditPanel({
  open,
  editing,
  saving,
  brands,
  availableRoles,
  showBrandSelect,
  onClose,
  onSave,
  onChangeEditing,
  onRoleChange,
  onBrandChange,
  onToggleFlag,
  onToggleActive,
}: {
  open: boolean;
  editing: EditingUser;
  saving: boolean;
  brands: { id: string; name: string }[];
  availableRoles: EditingUser["role"][];
  showBrandSelect: boolean;
  onClose: () => void;
  onSave: () => void;
  onChangeEditing: (editing: EditingUser) => void;
  onRoleChange: (role: EditingUser["role"]) => void;
  onBrandChange: (brandId: string | null) => void;
  onToggleFlag: (flag: string) => void;
  onToggleActive: (active: boolean) => void;
}) {
  if (!open) return null;

  return (
    <dialog
      ref={(el) => {
        if (el && !el.open) el.showModal();
      }}
      data-panel-dialog
      aria-label={editing.isNew ? "Create user" : "Edit user"}
      className="bg-transparent backdrop:bg-black/20 p-0 border-0 max-w-none max-h-none w-full h-full ml-auto mr-0"
    >
      <div
        className="relative flex h-full w-full max-w-md flex-col overflow-y-auto bg-white shadow-xl ring-1 ring-stone-200 ml-auto"
      >
        <div className="flex items-center justify-between border-b border-stone-100 px-6 py-4">
          <h2 className="text-lg font-bold text-stone-900">
            {editing.isNew ? "Create User" : "Edit User"}
          </h2>
          <button type="button" onClick={onClose} className="text-stone-400 hover:text-stone-600" aria-label="Close">
            <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        {/* Saving overlay */}
        {saving && (
          <div className="absolute inset-0 z-10 flex items-center justify-center bg-white/70">
            <div className="flex flex-col items-center gap-2">
              <div className="h-6 w-6 animate-spin rounded-full border-2 border-stone-200 border-t-stone-900" />
              <p className="text-sm text-stone-500">Saving…</p>
            </div>
          </div>
        )}

        <div className="flex-1 overflow-y-auto px-6 py-6">
          <div className="space-y-6">
            {editing.isNew && (
              <UsersPanelTextField
                id="fld-1-email"
                label="Email"
                placeholder="user@example.com"
                value={editing.email ?? ""}
                onChange={(v) => onChangeEditing({ ...editing, email: v })}
                type="email"
              />
            )}

            {editing.isNew && (
              <div>
                <label htmlFor="fld-password" className="block text-sm font-medium text-stone-700">Password</label>
                <p className="mt-1 text-xs text-stone-500 mb-1.5">Minimum 6 characters.</p>
                <input id="fld-password" aria-label="Choose A Password"
                  type="password"
                  value={editing.password ?? ""}
                  onChange={(e) => onChangeEditing({ ...editing, password: e.target.value })}
                  className="w-full rounded-lg border border-stone-200 bg-white px-3 py-2.5 text-sm text-stone-900 placeholder:text-stone-400 focus:border-emerald-500 focus:outline-none focus:ring-1 focus:ring-emerald-500"
                  placeholder="Choose a password"
                  minLength={6}
                />
              </div>
            )}

            <UsersPanelTextField
              id="fld-display-name"
              label="Display Name"
              hint="Shown in the admin user list."
              placeholder="Kyle Martinez"
              value={editing.display_name ?? ""}
              onChange={(v) => onChangeEditing({ ...editing, display_name: v })}
            />

            <UsersPanelTextField
              id="fld-phone"
              label="Phone Number"
              hint="Optional."
              placeholder="+1 (555) 000-0000"
              value={editing.phone_number ?? ""}
              onChange={(v) => onChangeEditing({ ...editing, phone_number: v })}
              type="tel"
            />

            {/* Role */}
            <div>
              <p className="block text-sm font-medium text-stone-700">Role</p>
              <div className="mt-2 space-y-2">
                {availableRoles.map((r) => (
                  <label key={r} className="flex items-center gap-3 rounded-lg border border-stone-200 px-3 py-2.5 cursor-pointer hover:bg-stone-50">
                    <input
                      type="radio"
                      name="role"
                      value={r}
                      checked={editing.role === r}
                      onChange={() => onRoleChange(r)}
                      className="accent-stone-900"
                     aria-label="Role"/>
                    <div>
                      <span className="font-medium text-stone-900 capitalize">{r.replace("_", " ")}</span>
                      <p className="text-xs text-stone-500">
                        {r === "platform_admin" ? "Full platform access" :
                         r === "brand_admin" ? "Brand-level admin" :
                         "Pickup and order operations only"}
                      </p>
                    </div>
                  </label>
                ))}
              </div>
            </div>

            {/* Brand */}
            {showBrandSelect && (
              <div>
                <label htmlFor="fld-2-brand"  className="block text-sm font-medium text-stone-700">Brand</label>
                <select id="fld-2-brand"  aria-label="Select"
                  value={editing.brand_id ?? ""}
                  onChange={(e) => onBrandChange(e.target.value || null)}
                  className="mt-1 w-full rounded-lg border border-stone-200 px-3 py-2.5 text-sm text-stone-900 focus:border-emerald-500 focus:outline-none focus:ring-1 focus:ring-emerald-500"
                >
                  <option value="">No brand (full platform scope)</option>
                  {brands.map((b) => (
                    <option key={b.id} value={b.id}>{b.name}</option>
                  ))}
                </select>
              </div>
            )}

            {/* Active toggle (edit only) */}
            {!editing.isNew && (
              <div className="flex items-center justify-between rounded-lg border border-stone-200 px-4 py-3">
                <div>
                  <p className="font-medium text-stone-900">Active</p>
                  <p className="text-xs text-stone-500">Deactivated users cannot log in</p>
                </div>
                <button type="button" aria-label="Toggle user active status" aria-pressed={editing.active}
                  onClick={() => onToggleActive(!editing.active)}
                  className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${editing.active ? "bg-emerald-600" : "bg-stone-300"}`}
                >
                  <span className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${editing.active ? "translate-x-6" : "translate-x-1"}`} />
                </button>
              </div>
            )}

            {/* Permissions */}
            <div>
              <p className="block text-sm font-medium text-stone-700 mb-3">Permissions</p>
              <div className="space-y-2">
                {ALL_FLAGS.map((flag) => (
                  <label key={flag} className="flex items-center justify-between rounded-lg border border-stone-200 px-4 py-2.5 hover:bg-stone-50 cursor-pointer">
                    <span className="text-sm text-stone-700">{FLAG_LABELS[flag]}</span>
                    <button
                      type="button"
                      onClick={() => onToggleFlag(flag)}
                      className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${editing.flags[flag] ? "bg-emerald-600" : "bg-stone-300"}`}
                    >
                      <span className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${editing.flags[flag] ? "translate-x-6" : "translate-x-1"}`} />
                    </button>
                  </label>
                ))}
              </div>
            </div>
          </div>
        </div>

        <div className="border-t px-6 py-4">
          <div className="flex justify-end gap-3">
            <button type="button"
              onClick={onClose}
              className="rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium text-stone-600 hover:bg-stone-50"
             aria-label="Cancel">
              Cancel
            </button>
            <button type="button"
              onClick={onSave}
              disabled={saving || (editing.isNew && (!editing.email?.includes("@") || !editing.password || editing.password.length < 6))}
              className="rounded-lg bg-stone-900 px-4 py-2 text-sm font-medium text-white hover:bg-stone-800 disabled:opacity-50"
            >
              {saving ? "Saving…" : editing.isNew ? "Create User" : "Save Changes"}
            </button>
          </div>
        </div>
      </div>
    </dialog>
  );
}

function UsersPanelTextField({
  id,
  label,
  hint,
  placeholder,
  value,
  onChange,
  type = "text",
}: {
  id: string;
  label: string;
  hint?: string;
  placeholder?: string;
  value: string;
  onChange: (value: string) => void;
  type?: "text" | "email" | "tel";
}) {
  return (
    <div>
      <label htmlFor={id} className="block text-sm font-medium text-stone-700">{label}</label>
      {hint && <p className="mt-1 text-xs text-stone-500 mb-1.5">{hint}</p>}
      <input id={id}
        type={type}
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="mt-1 w-full rounded-lg border border-stone-200 bg-white px-3 py-2.5 text-sm text-stone-900 placeholder:text-stone-400 focus:border-emerald-500 focus:outline-none focus:ring-1 focus:ring-emerald-500"
        placeholder={placeholder}
      />
    </div>
  );
}

function UsersPasswordModal({
  modal,
  onClose,
  onCopy,
}: {
  modal: PasswordModal | null;
  onClose: () => void;
  onCopy: () => void;
}) {
  if (!modal) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30">
      <div className="w-96 rounded-2xl bg-white p-6 shadow-xl ring-1 ring-stone-200">
        <h3 className="text-lg font-bold text-stone-900">Reset Password</h3>
        {modal.loading ? (
          <div className="mt-4 flex items-center gap-3 text-sm text-stone-500">
            <div className="h-4 w-4 animate-spin rounded-full border-2 border-stone-200 border-t-stone-900" />
            Resetting password for {modal.email}...
          </div>
        ) : modal.error ? (
          <div>
            <p className="mt-3 text-sm text-red-600">{modal.error}</p>
            <button type="button" onClick={onClose} className="mt-4 w-full rounded-lg border border-stone-200 px-4 py-2 text-sm font-medium text-stone-600 hover:bg-stone-50" aria-label="Close">Close</button>
          </div>
        ) : modal.tempPassword ? (
          <div>
            <p className="mt-3 text-sm text-stone-600">Temporary password for <span className="font-medium text-stone-900">{modal.email}</span>:</p>
            <div className="mt-3 flex items-center gap-2 rounded-xl bg-stone-50 p-4 ring-1 ring-stone-200">
              <span className="font-mono text-lg font-bold text-stone-900 select-all">{modal.tempPassword}</span>
              <button type="button" onClick={onCopy} className="shrink-0 rounded-lg bg-stone-200 px-3 py-1 text-xs font-medium text-stone-700 hover:bg-stone-300" aria-label="Copy">Copy</button>
            </div>
            <p className="mt-2 text-xs text-stone-500">Share this password securely with the user. They will be required to change it on next login.</p>
            <button type="button" onClick={onClose} className="mt-4 w-full rounded-lg bg-stone-900 px-4 py-2 text-sm font-medium text-white hover:bg-stone-800" aria-label="Done">Done</button>
          </div>
        ) : modal.message ? (
          <div>
            <p className="mt-3 text-sm text-stone-600">{modal.message}</p>
            <button type="button" onClick={onClose} className="mt-4 w-full rounded-lg bg-stone-900 px-4 py-2 text-sm font-medium text-white hover:bg-stone-800" aria-label="Done">Done</button>
          </div>
        ) : null}
      </div>
    </div>
  );
}
