// Bot management screen: list with filters + Add Bot modal.
// Uses real BotApi — no mock data.

const { useState, useEffect, useCallback } = React;

// ─── Add/Edit Bot modal form ─────────────────────────────────────────────
const BotFormModal = ({ open, onClose, onSaved, initial = {}, stats }) => {
  const toast = useToast();

  const [form, setForm] = useState({
    platform: "telegram",
    name: "", phone: "", api_id: "", api_hash: "", proxy: "", ai_enabled: false,
    pancakePageId: "", zaloGlobalId: "",
    react_pool: true,
    ...initial,
    react_pool: initial.react_pool !== false,
  });
  const [saving, setSaving] = useState(false);
  const [receipt, setReceipt] = useState(null);
  const [savedId, setSavedId] = useState(initial._id || '');
  const isEdit = !!savedId;
  useEffect(() => { if (!open) { setReceipt(null); setSavedId(initial._id || ''); } }, [open]);

  // Zalo account dropdown state
  const [zaloAccounts, setZaloAccounts] = useState(null); // null = not yet fetched
  const [zaloLoading, setZaloLoading] = useState(false);
  const [zaloError, setZaloError] = useState(null);

  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  // Lazy-fetch Zalo accounts when platform switches to zalo (create mode only)
  useEffect(() => {
    if (form.platform !== "zalo" || isEdit || zaloAccounts !== null) return;
    setZaloLoading(true);
    setZaloError(null);
    ZaloApi.listPancakeAccounts()
      .then((accounts) => setZaloAccounts(accounts))
      .catch((e) => setZaloError(e.message))
      .finally(() => setZaloLoading(false));
  }, [form.platform, isEdit, zaloAccounts]);

  const handleSelectZaloAccount = (pancakePageId) => {
    const acc = (zaloAccounts || []).find((a) => a.pancake_page_id === pancakePageId);
    if (!acc) return;
    setForm((f) => ({
      ...f,
      pancakePageId: acc.pancake_page_id,
      zaloGlobalId: acc.global_id || "",
      name: acc.zalo_name || f.name,
      phone: acc.phone_number || f.phone,
    }));
  };

  const handleSave = async () => {
    const fieldError = botSaveFieldError(form, isEdit);
    if (fieldError) {
      toast.error(fieldError);
      return;
    }

    // Check system limit for create operations
    if (!isEdit && !checkSystemLimit(stats?.limits, 'bots', toast)) {
      return;
    }

    setSaving(true);
    try {
      const payload = buildBotSavePayload(form, { isEdit, id: savedId });
      const result = await BotApi.save(payload);
      setSavedId(result.data?._id || savedId);
      setReceipt(result);
      toast.info('Đã lưu. Kiểm tra trạng thái áp dụng bên dưới.');
      onSaved();
    } catch (e) {
      toast.error(e.message);
    } finally {
      setSaving(false);
    }
  };

  if (!open) return null;
  return (
    <Modal
      open={open}
      onClose={onClose}
      title={isEdit ? "Edit Bot" : "Add Bot"}
      subtitle={form.platform === "zalo" ? "Zalo account via Pancake" : "Telegram bot credentials"}
      footer={
        <>
          <button className="btn ghost" onClick={onClose}>Close</button>
          <button className="btn primary" onClick={handleSave} disabled={saving}>
            {saving ? "Saving…" : "Save"}
          </button>
        </>
      }
    >
      <ApplyStatusPanel type="bot" resourceId={savedId} receipt={receipt} />
      {/* Platform select — top of form */}
      <div className="field">
        <label className="field-label">Platform</label>
        <select className="select" value={form.platform} onChange={(e) => set("platform", e.target.value)} disabled={isEdit}>
          <option value="telegram">Telegram</option>
          <option value="zalo">Zalo</option>
        </select>
      </div>

      {/* Zalo account dropdown — create mode only */}
      {form.platform === "zalo" && !isEdit && (
        <div className="field">
          <label className="field-label">Zalo Account</label>
          {zaloLoading ? (
            <div className="muted" style={{ fontSize: 13 }}>Loading accounts from Pancake…</div>
          ) : zaloError ? (
            <div style={{ color: "var(--red-fg)", fontSize: 13 }}>{zaloError}</div>
          ) : (zaloAccounts || []).length === 0 ? (
            <div className="muted" style={{ fontSize: 13 }}>No Zalo accounts found. Connect a Zalo account on Pancake first.</div>
          ) : (
            <select className="select" value={form.pancakePageId} onChange={(e) => handleSelectZaloAccount(e.target.value)}>
              <option value="">— Select Zalo account —</option>
              {(zaloAccounts || []).map((a) => (
                <option key={a.pancake_page_id} value={a.pancake_page_id}>
                  {a.zalo_name} ({a.phone_number || "no phone"})
                </option>
              ))}
            </select>
          )}
        </div>
      )}

      {/* Display name */}
      <div className="field">
        <label className="field-label">Display name</label>
        <input className="input" value={form.name} onChange={(e) => set("name", e.target.value)} placeholder="e.g. Bot #1" />
      </div>

      {/* Phone number */}
      <div className="field">
        <label className="field-label">Phone number</label>
        <input className="input mono" value={form.phone} onChange={(e) => set("phone", e.target.value)} placeholder="+84901234567" />
      </div>

      {/* Telegram-only fields */}
      {form.platform === "telegram" && (
        <>
          <div className="field">
            <label className="field-label">API ID{isEdit ? " (optional)" : ""}</label>
            <input className="input mono" value={form.api_id} onChange={(e) => set("api_id", e.target.value)} placeholder={isEdit ? "Leave blank to keep current" : "12345678"} />
          </div>
          <div className="field">
            <label className="field-label">API Hash{isEdit ? " (optional)" : ""}</label>
            <input className="input mono" value={form.api_hash} onChange={(e) => set("api_hash", e.target.value)} placeholder={isEdit ? "Leave blank to keep current" : "abc123…"} />
            {isEdit && (
              <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
                Saved credentials are hidden. Leave both blank to keep them.
              </div>
            )}
          </div>
          <div className="field">
            <label className="field-label">Proxy <span className="muted">(optional — ip:port:user:pass)</span></label>
            <input className="input mono" value={form.proxy} onChange={(e) => set("proxy", e.target.value)} placeholder="127.0.0.1:1080:user:pass" />
          </div>
          <div className="field">
            <label className="field-label" style={{ display: "flex", justifyContent: "space-between" }}>
              <span>Thêm vào pool react</span>
              <input type="checkbox" checked={form.react_pool !== false} onChange={(e) => set("react_pool", e.target.checked)} />
            </label>
            <div className="muted" style={{ fontSize: 12, marginTop: 4 }}>
              Uncheck nick chính to keep them out of Auto React.
            </div>
          </div>
        </>
      )}
    </Modal>
  );
};

const botPlatform = (b) => b.platform || "telegram";

const BOT_SEARCH_FIELDS = [
  (b) => b.name,
  (b) => b.phone,
  (b) => b.proxy,
  botPlatform,
  (b) => b.status,
  formatReactPoolLabel,
];

const BOT_SORT_GETTERS = {
  name: (b) => b.name || "",
  platform: botPlatform,
  status: (b) => b.status || "",
  react_pool: (b) => (isBotInReactPool(b) ? 1 : 0),
  messages_processed: (b) => b.messages_processed || 0,
  messages_forwarded: (b) => b.messages_forwarded || 0,
  last_active: (b) => {
    if (!b.last_active) return null;
    const t = new Date(b.last_active).getTime();
    return Number.isFinite(t) ? t : null;
  },
  updated_at: (b) => modifiedAtMs(b),
  proxy: (b) => b.proxy || "",
};

// ─── Bot list screen ──────────────────────────────────────────────────────
const BotsList = ({ onOpenBot, listQuery = "", onQuery, stats }) => {
  const toast = useToast();
  const confirm = useConfirm();
  const [platform, setPlatform] = useState("all");
  const [statusFilter, setStatusFilter] = useState("all");
  const [poolFilter, setPoolFilter] = useState("all");
  const [showAdd, setShowAdd] = useState(false);
  const [editBot, setEditBot] = useState(null);
  const [deletedReceipt, setDeletedReceipt] = useState(null);
  const { data: bots, loading, error, refetch } = useApi(BotApi.list, []);
  const { sortKey, sortDir, toggleSort } = useListSort("updated_at", "desc");

  const filtered = (bots || []).filter((b) =>
    (platform === "all" || botPlatform(b) === platform) &&
    matchesBotStatusFilter(b, statusFilter) &&
    matchesBotPoolFilter(b, poolFilter) &&
    matchQuery(b, listQuery, BOT_SEARCH_FIELDS)
  );
  const visible = sortItems(filtered, { key: sortKey, dir: sortDir, getters: BOT_SORT_GETTERS });

  const handleAction = async (action, bot) => {
    try {
      if (action === "delete") {
        const ok = await confirm("Delete bot", `Delete "${bot.name}"? This cannot be undone.`);
        if (!ok) return;
        const result = await BotApi.delete(bot._id);
        setDeletedReceipt({ result, id: bot._id });
        toast.info('Đã xóa bot sau khi runner xác nhận dừng.');
      } else if (action === "start") {
        await BotApi.start(bot._id);
        toast.success("Bot started");
      } else if (action === "stop") {
        await BotApi.stop(bot._id);
        toast.success("Bot stopped");
      } else if (action === "restart") {
        if (isAuthWaiting(bot.status)) {
          await BotApi.requestCode(bot._id);
          toast.success("New verification code sent");
          window.__navigate("auth-wizard", { preselectedBotId: bot._id, initialStep: "otp" });
        } else {
          await BotApi.restart(bot._id);
          toast.success("Bot restarted");
        }
      }
      refetch();
    } catch (e) {
      toast.error(e.message);
    }
  };

  const statusOptions = [
    { id: "all", label: "All" },
    { id: "active", label: "Active" },
    { id: "inactive", label: "Inactive" },
    { id: "paused", label: "Paused" },
    { id: "error", label: "Error" },
    { id: "auth_required", label: "Auth Required" },
    { id: "auth_in_progress", label: "Authing…" },
    { id: "awaiting_code", label: "Awaiting Code" },
  ];
  const poolOptions = [
    { id: "all", label: "All" },
    { id: "in", label: "In pool" },
    { id: "out", label: "Out of pool" },
  ];
  const poolCount = visible.filter(isBotInReactPool).length;

  if (error) return (
    <div className="page">
      <Empty icon={I.AlertTriangle} title="Failed to load bots" sub={error} action={<button className="btn" onClick={refetch}><I.Refresh /> Retry</button>} />
    </div>
  );

  return (
    <div className="page">
      <div className="page-head sticky-title">
        <div>
          <h1 className="page-title">Bots</h1>
          <div className="page-sub">
            {loading ? "Loading…" : `${visible.length} bots · ${visible.filter((b) => b.status === "active").length} active · ${poolCount} in pool`}
          </div>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <button className="btn" onClick={refetch}><I.Refresh /> Refresh</button>
          <button className="btn primary" onClick={() => setShowAdd(true)} disabled={isSystemAtLimit(stats?.limits, 'bots')} title={isSystemAtLimit(stats?.limits, 'bots') ? 'Bot system limit reached' : undefined}><I.Plus /> Add bot</button>
        </div>
      </div>

      {deletedReceipt && <ApplyStatusPanel type="bot" resourceId={deletedReceipt.id} receipt={deletedReceipt.result} deleted />}
      <div className="toolbar">
        <PlatformFilter value={platform} onChange={setPlatform} />
        <div className="chip-group">
          {statusOptions.map((s) => (
            <button key={s.id} className={`chip ${statusFilter === s.id ? "active" : ""}`} onClick={() => setStatusFilter(s.id)}>
              {s.label}
            </button>
          ))}
        </div>
        <div className="sep" />
        <div className="chip-group">
          <span className="muted" style={{ fontSize: 12, padding: "0 4px" }}>Pool</span>
          {poolOptions.map((s) => (
            <button key={s.id} className={`chip ${poolFilter === s.id ? "active" : ""}`} onClick={() => setPoolFilter(s.id)}>
              {s.label}
            </button>
          ))}
        </div>
        <ListSearch value={listQuery} onChange={onQuery} placeholder="Search bots…" />
      </div>

      <div className="card flush">
        <div style={{ overflow: "auto" }}>
          <table className="table">
            <thead>
              <tr>
                <SortableTh label="Bot" column="name" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Platform" column="platform" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Status" column="status" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Pool" column="react_pool" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Processed" column="messages_processed" className="num" align="right" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Forwarded" column="messages_forwarded" className="num" align="right" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Last active" column="last_active" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Modified Date" column="updated_at" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <SortableTh label="Proxy" column="proxy" sortKey={sortKey} sortDir={sortDir} onToggle={toggleSort} />
                <th style={{ width: 120 }}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <SkeletonRows cols={10} rows={5} />
              ) : (bots || []).length === 0 ? (
                <tr>
                  <td colSpan={10}>
                    <Empty icon={I.Bot} title="No bots found" sub="Add a bot to get started." />
                  </td>
                </tr>
              ) : visible.length === 0 ? (
                <tr>
                  <td colSpan={10}>
                    <Empty icon={I.Search} title="No bots match" sub="Clear search or filters to see all bots." />
                  </td>
                </tr>
              ) : (
                visible.map((b) => (
                  <tr key={b._id} style={{ cursor: "pointer" }} onClick={() => onOpenBot?.(b._id, b.name)}>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <Avatar name={b.name} />
                        <div>
                          <div style={{ fontWeight: 500 }}>{b.name}</div>
                          <div className="mono muted" style={{ fontSize: 11 }}>{b.phone}</div>
                        </div>
                      </div>
                    </td>
                    <td><PlatformChip platform={botPlatform(b)} /></td>
                    <td><StatusBadge status={b.status} /></td>
                    <td>
                      {isBotInReactPool(b)
                        ? <span className="badge green"><span className="dot"></span>In pool</span>
                        : <span className="muted">Out</span>}
                    </td>
                    <td className="num tnum">{(b.messages_processed || 0).toLocaleString()}</td>
                    <td className="num tnum">{(b.messages_forwarded || 0).toLocaleString()}</td>
                    <td className="muted">{relativeTime(b.last_active)}</td>
                    <td className="muted tnum">{formatModifiedDate(b)}</td>
                    <td className="mono muted">{b.proxy || "—"}</td>
                    <td onClick={(e) => e.stopPropagation()}>
                      <div style={{ display: "flex", gap: 4 }}>
                        <button className="btn ghost icon-only sm" title="Edit" onClick={() => setEditBot(b)}><I.Edit size={12} /></button>
                        <button className="btn ghost icon-only sm" title={isAuthWaiting(b.status) ? "Reset" : "Restart"} onClick={() => handleAction("restart", b)}><I.Refresh size={12} /></button>
                        <button className="btn ghost icon-only sm" title="Delete" onClick={() => handleAction("delete", b)} style={{ color: "var(--red-fg)" }}><I.Trash size={12} /></button>
                      </div>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </div>

      <BotFormModal key={showAdd ? 'open' : 'closed'} open={showAdd} onClose={() => setShowAdd(false)} onSaved={refetch} stats={stats} />
      {editBot && (
        <BotFormModal
          open={!!editBot}
          onClose={() => setEditBot(null)}
          onSaved={refetch}
          initial={editBot}
          stats={stats}
        />
      )}
    </div>
  );
};

window.BotsList = BotsList;
