import React, { useEffect, useState } from "../../../recovery-preview/node_modules/react/index.js";
import {
  compactText,
  datetimeLocalToUnix,
  formatBytes,
  formatCurrencyFen,
  formatUnixSeconds,
  requestJson,
  unixToDatetimeLocal,
} from "../../runtime/client.js";

const initialEditForm = {
  id: "",
  email: "",
  password: "",
  balance: "",
  commission_balance: "",
  commission_type: "",
  commission_rate: "",
  group_id: "",
  plan_id: "",
  speed_limit: "",
  device_limit: "",
  expired_at: "",
  remarks: "",
};

const initialMailForm = {
  user_id: "",
  subject: "",
  content: "",
};

function UserManagePage() {
  const [loading, setLoading] = useState(true);
  const [refreshTick, setRefreshTick] = useState(0);
  const [searchInput, setSearchInput] = useState("");
  const [keyword, setKeyword] = useState("");
  const [rows, setRows] = useState([]);
  const [pagination, setPagination] = useState({ current: 1, last_page: 1, per_page: 20, total: 0 });
  const [plans, setPlans] = useState([]);
  const [groups, setGroups] = useState([]);
  const [modal, setModal] = useState(null);
  const [editForm, setEditForm] = useState(initialEditForm);
  const [mailForm, setMailForm] = useState(initialMailForm);
  const [notice, setNotice] = useState("");
  const [error, setError] = useState("");

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        const [planResult, groupResult] = await Promise.all([
          requestJson("/plan/fetch"),
          requestJson("/server/group/fetch"),
        ]);
        if (!active) {
          return;
        }
        setPlans(Array.isArray(planResult?.data) ? planResult.data : planResult?.list || planResult || []);
        setGroups(Array.isArray(groupResult?.data) ? groupResult.data : groupResult?.list || groupResult || []);
      } catch (err) {
        if (active) {
          setNotice(err.message || "Reference data failed to load");
        }
      }
    })();
    return () => {
      active = false;
    };
  }, []);

  useEffect(() => {
    let active = true;
    (async () => {
      setLoading(true);
      setError("");
      try {
        const query = new URLSearchParams({
          page: String(pagination.current || 1),
          per_page: String(pagination.per_page || 20),
        });
        if (keyword) {
          query.set("keyword", keyword);
        }
        const payload = await requestJson(`/user/fetch?${query.toString()}`);
        if (!active) {
          return;
        }
        setRows(Array.isArray(payload?.list) ? payload.list : []);
        setPagination(payload?.pagination || pagination);
      } catch (err) {
        if (active) {
          setError(err.message || "Failed to load users");
          setRows([]);
        }
      } finally {
        if (active) {
          setLoading(false);
        }
      }
    })();
    return () => {
      active = false;
    };
  }, [keyword, pagination.current, pagination.per_page, refreshTick]);

  const openEditModal = (user) => {
    setEditForm({
      id: user.id,
      email: user.email || "",
      password: "",
      balance: user.balance ?? "",
      commission_balance: user.commission_balance ?? "",
      commission_type: user.commission_type ?? "",
      commission_rate: user.commission_rate ?? "",
      group_id: user.group_id ?? "",
      plan_id: user.plan_id ?? "",
      speed_limit: user.speed_limit ?? "",
      device_limit: user.device_limit ?? "",
      expired_at: unixToDatetimeLocal(user.expired_at),
      remarks: user.remarks || "",
    });
    setModal({ type: "edit", user });
  };

  const openMailModal = (user) => {
    setMailForm({
      user_id: user.id,
      subject: `Hello ${user.email}`,
      content: "",
    });
    setModal({ type: "mail", user });
  };

  const submitSearch = (event) => {
    event.preventDefault();
    setPagination((current) => ({ ...current, current: 1 }));
    setKeyword(compactText(searchInput));
  };

  const reload = () => setRefreshTick((value) => value + 1);

  const saveUser = async (event) => {
    event.preventDefault();
    setNotice("");
    setError("");
    try {
      const payload = {
        id: Number(editForm.id),
        email: compactText(editForm.email),
        password: compactText(editForm.password) || undefined,
        balance: toNullableNumber(editForm.balance),
        commission_balance: toNullableNumber(editForm.commission_balance),
        commission_type: toNullableNumber(editForm.commission_type),
        commission_rate: toNullableNumber(editForm.commission_rate),
        group_id: toNullableNumber(editForm.group_id),
        plan_id: toNullableNumber(editForm.plan_id),
        speed_limit: toNullableNumber(editForm.speed_limit),
        device_limit: toNullableNumber(editForm.device_limit),
        expired_at: datetimeLocalToUnix(editForm.expired_at),
        remarks: compactText(editForm.remarks),
      };
      pruneUndefined(payload);
      await requestJson("/user/update", { method: "POST", body: payload });
      setModal(null);
      reload();
    } catch (err) {
      setError(err.message || "Failed to save user");
    }
  };

  const resetSecret = async (user) => {
    if (!window.confirm(`Reset secret for ${user.email}?`)) {
      return;
    }
    try {
      const payload = await requestJson("/user/resetSecret", {
        method: "POST",
        body: { id: user.id },
      });
      setNotice(typeof payload?.data === "string" ? `Secret reset: ${payload.data}` : "Secret reset");
      reload();
    } catch (err) {
      setError(err.message || "Failed to reset secret");
    }
  };

  const resetTraffic = async (user) => {
    if (!window.confirm(`Reset traffic for ${user.email}?`)) {
      return;
    }
    try {
      await requestJson("/user/resetTraffic", {
        method: "POST",
        body: { id: user.id },
      });
      setNotice("Traffic reset complete");
      reload();
    } catch (err) {
      setError(err.message || "Failed to reset traffic");
    }
  };

  const toggleBan = async (user) => {
    const banned = !Boolean(user.banned);
    if (!window.confirm(`${banned ? "Ban" : "Unban"} ${user.email}?`)) {
      return;
    }
    try {
      await requestJson("/user/ban", {
        method: "POST",
        body: { id: user.id, banned },
      });
      reload();
    } catch (err) {
      setError(err.message || "Failed to update status");
    }
  };

  const deleteUser = async (user) => {
    if (!window.confirm(`Delete ${user.email}?`)) {
      return;
    }
    try {
      await requestJson("/user/drop", {
        method: "POST",
        body: { id: user.id },
      });
      reload();
    } catch (err) {
      setError(err.message || "Failed to delete user");
    }
  };

  const saveMail = async (event) => {
    event.preventDefault();
    try {
      await requestJson("/user/sendMail", {
        method: "POST",
        body: {
          user_id: Number(mailForm.user_id),
          subject: compactText(mailForm.subject),
          content: compactText(mailForm.content),
        },
      });
      setModal(null);
      setNotice("Mail submitted");
    } catch (err) {
      setError(err.message || "Failed to send mail");
    }
  };

  return (
    <div className="recovery-live-page">
      <header className="recovery-live-hero">
        <div>
          <p className="eyebrow">Recovered React Page</p>
          <h2>User Management</h2>
          <p>Search, edit, ban, reset traffic, and reset secrets against the live admin API.</p>
        </div>
        <div className="hero-stats">
          <div><strong>{pagination.total}</strong><span>users</span></div>
          <div><strong>{pagination.current}</strong><span>page</span></div>
          <div><strong>{plans.length}</strong><span>plans</span></div>
        </div>
      </header>

      <section className="recovery-toolbar">
        <form className="recovery-search" onSubmit={submitSearch}>
          <input
            value={searchInput}
            onChange={(event) => setSearchInput(event.target.value)}
            placeholder="Search by email or ID"
          />
          <button type="submit">Search</button>
        </form>
        <button
          type="button"
          className="secondary"
          onClick={() => {
            setSearchInput("");
            setKeyword("");
            setPagination((current) => ({ ...current, current: 1 }));
          }}
        >
          Clear
        </button>
      </section>

      {notice ? <div className="toast toast-info">{notice}</div> : null}
      {error ? <div className="toast toast-error">{error}</div> : null}

      <section className="recovery-table-card">
        <div className="table-scroll">
          <table className="recovery-table">
            <thead>
              <tr>
                <th>ID</th>
                <th>User</th>
                <th>Plan / Group</th>
                <th>Traffic</th>
                <th>Balance</th>
                <th>Status</th>
                <th>Updated</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr><td colSpan={8} className="empty-cell">Loading...</td></tr>
              ) : rows.length === 0 ? (
                <tr><td colSpan={8} className="empty-cell">No users found</td></tr>
              ) : rows.map((user) => (
                <tr key={user.id}>
                  <td>{user.id}</td>
                  <td>
                    <div className="cell-stack">
                      <strong>{user.email}</strong>
                      <span className="muted">UID: {user.id}</span>
                      {user.online_ip ? <span className="chip chip-soft">{user.online_ip}</span> : null}
                    </div>
                  </td>
                  <td>
                    <div className="cell-stack">
                      <span>{user.plan_name || `Plan ${user.plan_id || "-"}`}</span>
                      <span className="muted">{user.group_name || `Group ${user.group_id || "-"}`}</span>
                    </div>
                  </td>
                  <td>
                    <div className="cell-stack">
                      <span>{formatBytes(user.transfer_enable)}</span>
                      <span className="muted">Used {formatBytes(Number(user.u || 0) + Number(user.d || 0))}</span>
                    </div>
                  </td>
                  <td>
                    <div className="cell-stack">
                      <span>{formatCurrencyFen(user.balance)}</span>
                      <span className="muted">Comm {formatCurrencyFen(user.commission_balance)}</span>
                    </div>
                  </td>
                  <td>
                    <span className={`chip ${user.banned ? "chip-danger" : "chip-ok"}`}>
                      {user.banned ? "Banned" : "Active"}
                    </span>
                  </td>
                  <td>{formatUnixSeconds(user.updated_at || user.last_login_at || user.created_at)}</td>
                  <td>
                    <div className="action-row">
                      <button type="button" onClick={() => openEditModal(user)}>Edit</button>
                      <button type="button" onClick={() => openMailModal(user)}>Mail</button>
                      <button type="button" onClick={() => resetSecret(user)}>Secret</button>
                      <button type="button" onClick={() => resetTraffic(user)}>Traffic</button>
                      <button type="button" onClick={() => toggleBan(user)}>
                        {user.banned ? "Unban" : "Ban"}
                      </button>
                      <button type="button" className="danger" onClick={() => deleteUser(user)}>Delete</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="pagination-bar">
          <button
            type="button"
            disabled={pagination.current <= 1}
            onClick={() => setPagination((current) => ({ ...current, current: Math.max(1, current.current - 1) }))}
          >
            Prev
          </button>
          <span>
            Page {pagination.current} / {pagination.last_page}
          </span>
          <button
            type="button"
            disabled={pagination.current >= pagination.last_page}
            onClick={() => setPagination((current) => ({ ...current, current: Math.min(current.last_page, current.current + 1) }))}
          >
            Next
          </button>
        </div>
      </section>

      {modal?.type === "edit" ? (
        <Modal title={`Edit user ${editForm.email}`} onClose={() => setModal(null)}>
          <form className="modal-grid" onSubmit={saveUser}>
            <label>
              <span>ID</span>
              <input value={editForm.id} readOnly />
            </label>
            <label>
              <span>Email</span>
              <input value={editForm.email} onChange={(event) => setEditForm((current) => ({ ...current, email: event.target.value }))} />
            </label>
            <label>
              <span>Password</span>
              <input
                type="password"
                value={editForm.password}
                onChange={(event) => setEditForm((current) => ({ ...current, password: event.target.value }))}
                placeholder="leave blank to keep"
              />
            </label>
            <label>
              <span>Balance</span>
              <input type="number" value={editForm.balance} onChange={(event) => setEditForm((current) => ({ ...current, balance: event.target.value }))} />
            </label>
            <label>
              <span>Commission Balance</span>
              <input type="number" value={editForm.commission_balance} onChange={(event) => setEditForm((current) => ({ ...current, commission_balance: event.target.value }))} />
            </label>
            <label>
              <span>Commission Type</span>
              <input type="number" value={editForm.commission_type} onChange={(event) => setEditForm((current) => ({ ...current, commission_type: event.target.value }))} />
            </label>
            <label>
              <span>Commission Rate</span>
              <input type="number" value={editForm.commission_rate} onChange={(event) => setEditForm((current) => ({ ...current, commission_rate: event.target.value }))} />
            </label>
            <label>
              <span>Group</span>
              <select value={editForm.group_id} onChange={(event) => setEditForm((current) => ({ ...current, group_id: event.target.value }))}>
                <option value="">-</option>
                {groups.map((group) => (
                  <option key={group.id} value={group.id}>{group.name || `Group ${group.id}`}</option>
                ))}
              </select>
            </label>
            <label>
              <span>Plan</span>
              <select value={editForm.plan_id} onChange={(event) => setEditForm((current) => ({ ...current, plan_id: event.target.value }))}>
                <option value="">-</option>
                {plans.map((plan) => (
                  <option key={plan.id} value={plan.id}>{plan.name || `Plan ${plan.id}`}</option>
                ))}
              </select>
            </label>
            <label>
              <span>Speed Limit</span>
              <input type="number" value={editForm.speed_limit} onChange={(event) => setEditForm((current) => ({ ...current, speed_limit: event.target.value }))} />
            </label>
            <label>
              <span>Device Limit</span>
              <input type="number" value={editForm.device_limit} onChange={(event) => setEditForm((current) => ({ ...current, device_limit: event.target.value }))} />
            </label>
            <label>
              <span>Expired At</span>
              <input
                type="datetime-local"
                value={editForm.expired_at}
                onChange={(event) => setEditForm((current) => ({ ...current, expired_at: event.target.value }))}
              />
            </label>
            <label className="span-2">
              <span>Remarks</span>
              <textarea value={editForm.remarks} onChange={(event) => setEditForm((current) => ({ ...current, remarks: event.target.value }))} />
            </label>
            <div className="modal-actions span-2">
              <button type="button" className="secondary" onClick={() => setModal(null)}>Cancel</button>
              <button type="submit">Save</button>
            </div>
          </form>
        </Modal>
      ) : null}

      {modal?.type === "mail" ? (
        <Modal title={`Send mail to ${mailForm.user_id}`} onClose={() => setModal(null)}>
          <form className="modal-grid" onSubmit={saveMail}>
            <label>
              <span>User ID</span>
              <input value={mailForm.user_id} readOnly />
            </label>
            <label className="span-2">
              <span>Subject</span>
              <input value={mailForm.subject} onChange={(event) => setMailForm((current) => ({ ...current, subject: event.target.value }))} />
            </label>
            <label className="span-2">
              <span>Content</span>
              <textarea rows={8} value={mailForm.content} onChange={(event) => setMailForm((current) => ({ ...current, content: event.target.value }))} />
            </label>
            <div className="modal-actions span-2">
              <button type="button" className="secondary" onClick={() => setModal(null)}>Cancel</button>
              <button type="submit">Send</button>
            </div>
          </form>
        </Modal>
      ) : null}
    </div>
  );
}

function Modal({ title, children, onClose }) {
  return (
    <div className="modal-backdrop" role="presentation" onClick={onClose}>
      <div className="modal-panel" role="dialog" aria-modal="true" onClick={(event) => event.stopPropagation()}>
        <header className="modal-header">
          <h3>{title}</h3>
          <button type="button" className="secondary" onClick={onClose}>Close</button>
        </header>
        {children}
      </div>
    </div>
  );
}

function pruneUndefined(target) {
  Object.keys(target).forEach((key) => {
    if (target[key] === undefined || target[key] === null || target[key] === "") {
      delete target[key];
    }
  });
}

function toNullableNumber(value) {
  const trimmed = compactText(value);
  if (!trimmed) {
    return undefined;
  }
  const number = Number(trimmed);
  return Number.isNaN(number) ? undefined : number;
}

export default UserManagePage;
