import React, { useCallback, useEffect, useMemo, useState } from "react";
import PageHeader from "../../components/common/PageHeader.jsx";
import DataTable from "../../components/common/DataTable.jsx";
import ErrorBanner from "../../components/common/ErrorBanner.jsx";
import EntityModal from "../../components/common/EntityModal.jsx";
import FileUploadField from "../../components/common/FileUploadField.jsx";
import UserStatusToggle from "../../components/admin/UserStatusToggle.jsx";
import {
  createUser,
  createUserRole,
  deleteUserRole,
  listUserRoles,
  listUsers,
  updateUser,
  updateUserStatus,
  userPhotoUrl
} from "../../services/usersApi.js";
import { listMaster } from "../../services/masterApi.js";

const USER_STATUS_ACTIVE = 1;
const USER_STATUS_INACTIVE = 2;

const blankUser = { employee_name: "", employee_id: "", email_id: "", phonenumber: "", role_id: "" };

function statusLabel(statusId) {
  const id = Number(statusId);
  if (id === USER_STATUS_ACTIVE) return "Active";
  if (id === USER_STATUS_INACTIVE) return "Inactive";
  return "Unknown";
}

export default function AdminUsersAccessPage() {
  const [rows, setRows] = useState([]);
  const [error, setError] = useState("");
  const [actionUser, setActionUser] = useState(null);
  const [actionModalOpen, setActionModalOpen] = useState(false);
  const [showEditor, setShowEditor] = useState(false);
  const [form, setForm] = useState(blankUser);
  const [photo, setPhoto] = useState(null);
  const [roles, setRoles] = useState([]);
  const [roleRows, setRoleRows] = useState([]);
  const [assignRoleId, setAssignRoleId] = useState("");
  const [statusSavingId, setStatusSavingId] = useState(null);

  const roleNameById = useMemo(
    () => Object.fromEntries(roles.map((r) => [String(r.role_id), r.role_name])),
    [roles]
  );

  async function loadAll() {
    try {
      setError("");
      const [users, r] = await Promise.all([
        listUsers(),
        listMaster("roles")
      ]);
      setRows(users);
      setRoles(r);
      return users;
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
      return null;
    }
  }

  async function loadUserRoles(userId) {
    const ur = await listUserRoles({ user_id: userId });
    setRoleRows(ur);
  }

  useEffect(() => {
    loadAll();
  }, []);

  useEffect(() => {
    if (!actionModalOpen || !actionUser?.user_id) return;
    loadUserRoles(actionUser.user_id).catch(() => {});
  }, [actionModalOpen, actionUser?.user_id]);

  const openUserAction = (user) => {
    setActionUser(user);
    setAssignRoleId("");
    setActionModalOpen(true);
  };

  const closeUserAction = () => {
    setActionModalOpen(false);
    setActionUser(null);
    setRoleRows([]);
    setAssignRoleId("");
  };

  const refreshActionUser = (users, userId) => {
    if (!userId || !users) return;
    const updated = users.find((u) => u.user_id === userId);
    if (updated) setActionUser(updated);
  };

  const handleStatusToggle = useCallback(async (userId, currentStatusId) => {
    const current = Number(currentStatusId) || USER_STATUS_ACTIVE;
    const nextStatusId = current === USER_STATUS_ACTIVE ? USER_STATUS_INACTIVE : USER_STATUS_ACTIVE;

    setStatusSavingId(userId);
    setRows((prev) => prev.map((u) => (
      u.user_id === userId ? { ...u, status_id: nextStatusId } : u
    )));

    try {
      setError("");
      await updateUserStatus(userId, nextStatusId);
      const users = await loadAll();
      if (actionModalOpen) refreshActionUser(users, userId);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
      await loadAll();
    } finally {
      setStatusSavingId(null);
    }
  }, [actionModalOpen]);

  const columns = useMemo(() => [
    { key: "user_id", label: "ID" },
    { key: "employee_name", label: "Name" },
    { key: "email_id", label: "Email" },
    { key: "employee_id", label: "Employee ID" },
    { key: "phonenumber", label: "Phone" },
    {
      key: "status_id",
      label: "Status",
      render: (r) => (
        <UserStatusToggle
          statusId={r.status_id}
          disabled={statusSavingId === r.user_id}
          onChange={() => handleStatusToggle(r.user_id, r.status_id)}
        />
      )
    },
    {
      key: "has_photo",
      label: "Photo",
      render: (r) => (r.has_photo
        ? <img alt="" className="ptw-users-table__photo" src={userPhotoUrl(r.user_id)} />
        : "—")
    }
  ], [statusSavingId, handleStatusToggle]);

  return (
    <div className="portal-page">
      <PageHeader
        title="Users & Access"
        subtitle="Create and edit users, assign roles, and set account status."
        actions={(
          <button
            type="button"
            className="swi-btn"
            onClick={() => { setForm(blankUser); setPhoto(null); setShowEditor(true); }}
          >
            Create User
          </button>
        )}
      />
      <ErrorBanner message={error} />

      <div className="ptw-panel ptw-users-panel ptw-users-table">
        <h3 className="ptw-panel__title">Users</h3>
        <DataTable columns={columns} rows={rows} keyField="user_id" onRowClick={openUserAction} />
      </div>

      <EntityModal
        open={actionModalOpen && Boolean(actionUser)}
        title={actionUser ? actionUser.employee_name : "User"}
        onClose={closeUserAction}
      >
        {actionUser ? (
          <div className="ptw-user-action-modal">
            <div className="ptw-user-action-modal__summary">
              {actionUser.has_photo ? (
                <img alt="" className="ptw-user-action-modal__avatar" src={userPhotoUrl(actionUser.user_id)} />
              ) : null}
              <dl className="ptw-key-value">
                <dt>User ID</dt>
                <dd>{actionUser.user_id}</dd>
                <dt>Email</dt>
                <dd>{actionUser.email_id || "—"}</dd>
                <dt>Employee ID</dt>
                <dd>{actionUser.employee_id || "—"}</dd>
                <dt>Phone</dt>
                <dd>{actionUser.phonenumber || "—"}</dd>
                <dt>Status</dt>
                <dd>{statusLabel(actionUser.status_id)}</dd>
              </dl>
            </div>

            <div className="ptw-row-actions ptw-user-action-modal__actions">
              <button
                type="button"
                className="swi-btn"
                onClick={() => {
                  setForm(actionUser);
                  setPhoto(null);
                  setShowEditor(true);
                }}
              >
                Edit
              </button>
            </div>

            <div className="ptw-user-action-modal__section">
              <h4>Assign roles</h4>
              <div className="ptw-inline-form">
                <select
                  className="swi-input"
                  value={assignRoleId}
                  onChange={(e) => setAssignRoleId(e.target.value)}
                >
                  <option value="">Select role</option>
                  {roles.map((r) => (
                    <option key={r.role_id} value={r.role_id}>{r.role_name}</option>
                  ))}
                </select>
                <button
                  type="button"
                  className="swi-btn"
                  onClick={async () => {
                    if (!assignRoleId) return;
                    await createUserRole({ user_id: actionUser.user_id, role_id: Number(assignRoleId) });
                    setAssignRoleId("");
                    await loadUserRoles(actionUser.user_id);
                  }}
                >
                  Assign
                </button>
              </div>
              <div className="ptw-chips">
                {roleRows.map((r) => (
                  <span className="ptw-chip" key={r.user_role_id}>
                    {roleNameById[String(r.role_id)] || `Role #${r.role_id}`}
                    <button
                      type="button"
                      className="ptw-chip__remove"
                      onClick={async () => {
                        await deleteUserRole(r.user_role_id);
                        await loadUserRoles(actionUser.user_id);
                      }}
                    >
                      x
                    </button>
                  </span>
                ))}
              </div>
            </div>
          </div>
        ) : null}
      </EntityModal>

      <EntityModal open={showEditor} title={form.user_id ? "Edit User" : "Create User"} onClose={() => setShowEditor(false)}>
        <div className="ptw-form-grid-2">
          <label className="swi-field"><span className="swi-field__label">Name</span><input className="swi-input" value={form.employee_name || ""} onChange={(e) => setForm((f) => ({ ...f, employee_name: e.target.value }))} /></label>
          <label className="swi-field"><span className="swi-field__label">Employee ID</span><input className="swi-input" value={form.employee_id || ""} onChange={(e) => setForm((f) => ({ ...f, employee_id: e.target.value }))} /></label>
          <label className="swi-field"><span className="swi-field__label">Email</span><input className="swi-input" value={form.email_id || ""} onChange={(e) => setForm((f) => ({ ...f, email_id: e.target.value }))} /></label>
          <label className="swi-field"><span className="swi-field__label">Phone</span><input className="swi-input" value={form.phonenumber || ""} onChange={(e) => setForm((f) => ({ ...f, phonenumber: e.target.value }))} /></label>
        </div>
        <FileUploadField label="Upload/Replace Photo" accept="image/*" onChange={setPhoto} />
        <div className="ptw-row-actions">
          <button type="button" className="swi-btn swi-btn--ghost" onClick={() => setShowEditor(false)}>Cancel</button>
          <button
            type="button"
            className="swi-btn"
            onClick={async () => {
              if (form.user_id) {
                await updateUser(form.user_id, form, photo);
              } else {
                await createUser({ ...form, status_id: USER_STATUS_ACTIVE }, photo);
              }
              setShowEditor(false);
              const users = await loadAll();
              if (actionUser?.user_id) refreshActionUser(users, actionUser.user_id);
            }}
          >
            {form.user_id ? "Update" : "Create User"}
          </button>
        </div>
      </EntityModal>
    </div>
  );
}
