// user-resource-assignment-panel.jsx — Expandable resource assignment panel for user management
// Admin can view/assign/unassign bots, source groups, target groups, configs per user.
// Uses client-side filter: fetch all resources, filter by owners.includes(userId).

const { useState, useEffect, useCallback } = React;

// ─── Resource type config — drives tab rendering for all 4 types ──────────
const RESOURCE_TYPES = [
  { key: "bots", label: "Bots", resource: "bots", api: () => BotApi.list(), nameField: "name", subField: "phone" },
  { key: "sourceGroups", label: "Sources", resource: "source-groups", api: () => SourceGroupApi.list(), nameField: "name", subField: "group_id" },
  { key: "targetGroups", label: "Targets", resource: "target-groups", api: () => TargetGroupApi.list(), nameField: "name", subField: "group_id" },
  { key: "botConfigs", label: "Configs", resource: "bot-configs", api: () => BotConfigApi.list(), nameField: "description", subField: null },
];

// ─── Assign modal — multi-select from available resources ─────────────────
const AssignResourceModal = ({ open, onClose, available, nameField, subField, label, onAssign }) => {
  const [selected, setSelected] = useState([]);
  const [saving, setSaving] = useState(false);

  useEffect(() => { if (open) setSelected([]); }, [open]);

  const toggle = (id) => setSelected(prev =>
    prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]
  );

  const handleSubmit = async () => {
    setSaving(true);
    try {
      await onAssign(selected);
      onClose();
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose} title={`Assign ${label}`} width={420}
      footer={<>
        <button className="btn ghost" onClick={onClose}>Cancel</button>
        <button className="btn primary" onClick={handleSubmit} disabled={saving || !selected.length}>
          {saving ? "Assigning..." : `Assign (${selected.length})`}
        </button>
      </>}
    >
      {available.length === 0 ? (
        <div style={{ color: "var(--fg-3)", fontSize: 13, padding: "16px 0", textAlign: "center" }}>
          No available {label.toLowerCase()} to assign.
        </div>
      ) : (
        <div style={{ maxHeight: 300, overflow: "auto", display: "flex", flexDirection: "column", gap: 2 }}>
          {available.map(item => (
            <label key={item._id} style={{
              display: "flex", alignItems: "center", gap: 10, padding: "7px 10px", borderRadius: 6,
              cursor: "pointer", background: selected.includes(item._id) ? "var(--surface-2)" : "transparent",
            }}>
              <input type="checkbox" checked={selected.includes(item._id)} onChange={() => toggle(item._id)} />
              <div>
                <div style={{ fontSize: 13, fontWeight: 500 }}>{item[nameField] || item._id}</div>
                {subField && item[subField] && (
                  <div style={{ fontSize: 11, color: "var(--fg-3)" }}>{String(item[subField])}</div>
                )}
              </div>
            </label>
          ))}
        </div>
      )}
    </Modal>
  );
};

// ─── Main resource panel — tabs + list + assign/remove per user ───────────
const UserResourcePanel = ({ userId, onChanged }) => {
  const [activeTab, setActiveTab] = useState("bots");
  const [resources, setResources] = useState({});
  const [loading, setLoading] = useState(true);
  const [showAssign, setShowAssign] = useState(false);
  const toast = useToast();
  const confirm = useConfirm();

  // Fetch all 4 resource types in parallel (loading only on initial mount)
  const fetchAll = useCallback(async (showLoading = false) => {
    if (showLoading) setLoading(true);
    try {
      const results = await Promise.all(RESOURCE_TYPES.map(t => t.api()));
      const map = {};
      RESOURCE_TYPES.forEach((t, i) => { map[t.key] = results[i]; });
      setResources(map);
    } catch (e) {
      toast.error("Failed to load resources");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { fetchAll(true); }, [fetchAll]);

  const typeDef = RESOURCE_TYPES.find(t => t.key === activeTab);
  const all = resources[activeTab] || [];
  const assigned = all.filter(r => r.owners?.includes(userId));
  const available = all.filter(r => !r.owners?.includes(userId));

  // Assign multiple resources concurrently, report ok/failed counts
  const handleAssign = async (ids) => {
    const results = await Promise.allSettled(
      ids.map(id => UserApi.manageOwners(typeDef.resource, id, "add", userId))
    );
    const ok = results.filter(r => r.status === "fulfilled").length;
    const failed = ids.length - ok;
    if (ok > 0) toast.success(`Assigned ${ok} ${typeDef.label.toLowerCase()}`);
    if (failed > 0) toast.error(`${failed} failed to assign`);
    await fetchAll();
    onChanged?.();
  };

  // Remove single resource ownership with confirmation
  const handleRemove = async (resourceId) => {
    const ok = await confirm("Remove resource?", "Unassign this resource from the user.");
    if (!ok) return;
    try {
      await UserApi.manageOwners(typeDef.resource, resourceId, "remove", userId);
      toast.success("Resource removed");
      await fetchAll();
      onChanged?.();
    } catch (e) {
      toast.error(e.message);
    }
  };

  return (
    <div style={{ padding: "12px 16px", background: "var(--surface-1)", borderRadius: 8, margin: "4px 0" }}>
      {/* Tab bar */}
      <div style={{ display: "flex", gap: 2, marginBottom: 12, borderBottom: "1px solid var(--border)", paddingBottom: 8 }}>
        {RESOURCE_TYPES.map(t => {
          const count = (resources[t.key] || []).filter(r => r.owners?.includes(userId)).length;
          const isActive = activeTab === t.key;
          return (
            <button key={t.key} className="btn ghost sm" onClick={() => setActiveTab(t.key)}
              style={{ fontWeight: isActive ? 600 : 400, borderBottom: isActive ? "2px solid var(--accent)" : "2px solid transparent", borderRadius: 0, fontSize: 12 }}>
              {t.label} ({count})
            </button>
          );
        })}
      </div>

      {/* Assigned resource list */}
      {loading ? (
        <div style={{ color: "var(--fg-3)", fontSize: 13, padding: 8 }}>Loading resources...</div>
      ) : assigned.length === 0 ? (
        <div style={{ color: "var(--fg-3)", fontSize: 13, padding: "8px 0" }}>
          No {typeDef.label.toLowerCase()} assigned.
        </div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
          {assigned.map(item => (
            <div key={item._id} style={{
              display: "flex", justifyContent: "space-between", alignItems: "center",
              padding: "6px 10px", borderRadius: 6, background: "var(--surface-2)",
            }}>
              <div style={{ minWidth: 0 }}>
                <span style={{ fontSize: 13, fontWeight: 500 }}>{item[typeDef.nameField] || item._id}</span>
                {typeDef.subField && item[typeDef.subField] && (
                  <span style={{ fontSize: 11, color: "var(--fg-3)", marginLeft: 8 }}>{String(item[typeDef.subField])}</span>
                )}
              </div>
              <button className="btn ghost sm danger" onClick={() => handleRemove(item._id)} style={{ fontSize: 11, flexShrink: 0 }}>
                Remove
              </button>
            </div>
          ))}
        </div>
      )}

      {/* Assign button */}
      <button className="btn ghost sm" onClick={() => setShowAssign(true)} style={{ marginTop: 8, fontSize: 12 }}>
        + Assign {typeDef.label}
      </button>

      <AssignResourceModal
        open={showAssign} onClose={() => setShowAssign(false)}
        available={available} nameField={typeDef.nameField}
        subField={typeDef.subField} label={typeDef.label} onAssign={handleAssign}
      />
    </div>
  );
};

Object.assign(window, { UserResourcePanel });
