// API Service Layer — fetch wrapper + React hook + entity API objects.
// All screens use this module instead of calling fetch directly.

const { useState, useEffect, useRef } = React;

// ─── Base URL detection (local vs production) ────────────────────────────
const getBaseUrl = () => {
  const h = window.location.hostname;
  if (h === "localhost" || h.startsWith("127.")) return "/api";
  if (h.includes("api.vipcrm.net")) return "/seeding/api";
  return "/api";
};

const BASE_URL = getBaseUrl();

// ─── Auth token storage (localStorage) ───────────────────────────────────
const AuthStore = {
  getToken: () => localStorage.getItem("auth_token"),
  setToken: (token) => localStorage.setItem("auth_token", token),
  getUser: () => JSON.parse(localStorage.getItem("auth_user") || "null"),
  setUser: (user) => localStorage.setItem("auth_user", JSON.stringify(user)),
  clear: () => {
    localStorage.removeItem("auth_token");
    localStorage.removeItem("auth_user");
  },
  isLoggedIn: () => !!localStorage.getItem("auth_token"),
};

// ─── Generic fetch wrapper ────────────────────────────────────────────────
const apiFetch = async (path, options = {}) => {
  const { body, ...rest } = options;
  const headers = { "Content-Type": "application/json" };

  // Attach Bearer token if available
  const token = AuthStore.getToken();
  if (token) headers["Authorization"] = `Bearer ${token}`;

  const res = await fetch(`${BASE_URL}${path}`, {
    headers,
    ...rest,
    body: body !== undefined ? JSON.stringify(body) : undefined,
  });

  // 401: session expired — clear token and notify App to show login screen
  if (res.status === 401) {
    AuthStore.clear();
    window.dispatchEvent(new Event("auth:logout"));
    throw new Error("Session expired. Please log in again.");
  }

  const text = await res.text();
  let json;
  try { json = JSON.parse(text); } catch { throw new Error(text || `Request failed (${res.status})`); }
  if (!res.ok) throw new Error(json.message || `Request failed (${res.status})`);
  return json;
};

// ─── useApi hook — manages loading/error/data state with auto-fetch ───────
const useApi = (fetcherFn, deps = []) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const abortRef = useRef(null);

  const run = async () => {
    if (abortRef.current) abortRef.current.abort();
    abortRef.current = new AbortController();
    setLoading(true);
    setError(null);
    try {
      const result = await fetcherFn();
      setData(result);
    } catch (e) {
      if (e.name !== "AbortError") setError(e.message || "Unknown error");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    run();
    return () => abortRef.current?.abort();
  }, deps);

  return { data, loading, error, refetch: run };
};

// ─── Auth API ─────────────────────────────────────────────────────────────
const AuthApi = {
  login: (email, password) => apiFetch("/auth/login", { method: "POST", body: { email, password } }),
  me: () => apiFetch("/auth/me"),
};

// ─── Bot API ─────────────────────────────────────────────────────────────
const BotApi = {
  list:            ()       => apiFetch("/bots").then(r => r.data || []),
  get:             (id)     => apiFetch(`/bots/${id}`).then(r => r.data),
  save:            (data)   => apiFetch("/bots/save", { method: "POST", body: data }),
  delete:          (id)     => apiFetch(`/bots/${id}`, { method: "DELETE" }),
  start:           (id)     => apiFetch(`/bots/${id}/start`, { method: "POST" }),
  stop:            (id)     => apiFetch(`/bots/${id}/stop`, { method: "POST" }),
  restart:         (id)     => apiFetch(`/bots/${id}/restart`, { method: "POST" }),
  requestCode:     (id)     => apiFetch(`/bots/${id}/request-code`, { method: "POST" }),
  submitCode:      (id, d)  => apiFetch(`/bots/${id}/submit-code`, { method: "POST", body: d }),
  submitPassword:  (id, d)  => apiFetch(`/bots/${id}/submit-password`, { method: "POST", body: d }),
  getAuthStatus:   (id)     => apiFetch(`/bots/${id}/auth-status`),
  testConnection:  (id)     => apiFetch(`/bots/${id}/test-connection`),
};

// ─── Source Group API ─────────────────────────────────────────────────────
const SourceGroupApi = {
  list:   ()     => apiFetch("/source-groups").then(r => r.data || []),
  get:    (id)   => apiFetch(`/source-groups/${id}`).then(r => r.data),
  save:   (data) => apiFetch("/source-groups/save", { method: "POST", body: data }),
  delete: (id)   => apiFetch(`/source-groups/${id}`, { method: "DELETE" }),
};

// ─── Target Group API ─────────────────────────────────────────────────────
const TargetGroupApi = {
  list:   ()     => apiFetch("/target-groups").then(r => r.data || []),
  get:    (id)   => apiFetch(`/target-groups/${id}`).then(r => r.data),
  save:   (data) => apiFetch("/target-groups/save", { method: "POST", body: data }),
  delete: (id)   => apiFetch(`/target-groups/${id}`, { method: "DELETE" }),
};

// ─── BotConfig API ────────────────────────────────────────────────────────
const BotConfigApi = {
  list:   ()     => apiFetch("/bot-configs").then(r => r.data || []),
  get:    (id)   => apiFetch(`/bot-configs/${id}`).then(r => r.data),
  save:   (data) => apiFetch("/bot-configs/save", { method: "POST", body: data }),
  delete: (id)   => apiFetch(`/bot-configs/${id}`, { method: "DELETE" }),
};

// ─── System API ───────────────────────────────────────────────────────────
const SystemApi = {
  stats: () => apiFetch("/system/stats").then(r => r.data || r),
};

// ─── Active Session API ───────────────────────────────────────────────────
const ActiveSessionApi = {
  list:           ()    => apiFetch("/active-sessions").then(r => r.data || []),
  get:            (id)  => apiFetch(`/active-sessions/${id}`).then(r => r.data),
  bySource:       (id)  => apiFetch(`/active-sessions/source/${id}`).then(r => r.data || []),
  expire:         (id)  => apiFetch(`/active-sessions/${id}/expire`, { method: "POST" }),
  expireInactive: ()    => apiFetch("/active-sessions/expire-inactive", { method: "POST" }),
};

// ─── Conversation API ─────────────────────────────────────────────────────
const ConversationApi = {
  list:   ()                              => apiFetch("/conversations").then(r => r.data || []),
  get:    (id)                            => apiFetch(`/conversations/${id}`).then(r => r.data),
  byUser: (sourceGroupId, userId, topicId) => {
    const qs = topicId ? `?topicId=${topicId}` : "";
    return apiFetch(`/conversations/source/${sourceGroupId}/user/${userId}${qs}`).then(r => r.data);
  },
};

// ─── User Management API (admin only) ────────────────────────────────────
const UserApi = {
  list:   ()        => apiFetch("/users").then(r => r.data || []),
  get:    (id)      => apiFetch(`/users/${id}`).then(r => r.data),
  create: (data)    => apiFetch("/users", { method: "POST", body: data }),
  update: (id, d)   => apiFetch(`/users/${id}`, { method: "PUT", body: d }),
  delete: (id)      => apiFetch(`/users/${id}`, { method: "DELETE" }),
  manageOwners: (resource, id, action, userId) =>
    apiFetch(`/${resource}/${id}/owners`, { method: "POST", body: { action, userId } }),
};

Object.assign(window, {
  apiFetch, useApi, AuthStore, AuthApi,
  BotApi, SourceGroupApi, TargetGroupApi, BotConfigApi, SystemApi,
  ActiveSessionApi, ConversationApi, UserApi,
});
