import type {
  GeneratorDefinition,
  FeedGeneratorDescription,
  LikeFeedState,
  StoredFeedState,
  FeedImportPayload,
  FeedSignalRecord,
  TasteProfileResult,
} from "../types";

// Convert snake_case keys to camelCase recursively
function toCamelCase(obj: unknown): unknown {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  if (Array.isArray(obj)) {
    return obj.map(toCamelCase);
  }
  const result: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(obj)) {
    const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
    result[camelKey] = toCamelCase(value);
  }
  return result;
}

export const apiService = {
  async getGenerators(): Promise<GeneratorDefinition[]> {
    const response = await fetch("/api/feed-generators");
    if (!response.ok) throw new Error("Failed to fetch generators");
    return response.json();
  },

  async getFeedGeneratorInfo(): Promise<FeedGeneratorDescription> {
    const response = await fetch("/api/feed-generator-info");
    if (!response.ok) throw new Error("Failed to fetch feed generator info");
    return response.json();
  },

  async getFeedState(actorDid: string, generatorId: string): Promise<StoredFeedState> {
    const url = `/api/feed-state?actorDid=${encodeURIComponent(actorDid)}&generatorId=${encodeURIComponent(generatorId)}`;
    const response = await fetch(url);
    if (!response.ok) throw new Error("Failed to fetch feed state");
    return toCamelCase(await response.json()) as StoredFeedState;
  },

  async getLikeFeed(actorDid: string): Promise<LikeFeedState> {
    const url = `/api/like-feed?actorDid=${encodeURIComponent(actorDid)}`;
    const response = await fetch(url);
    if (!response.ok) throw new Error("Failed to fetch like feed");
    return toCamelCase(await response.json()) as LikeFeedState;
  },

  async importFeed(data: FeedImportPayload): Promise<void> {
    const response = await fetch("/api/feed-import", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    if (!response.ok) throw new Error("Failed to import feed");
  },

  async addSignal(actorDid: string, signal: FeedSignalRecord): Promise<StoredFeedState> {
    const response = await fetch("/api/feed-signals", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ actorDid, signal }),
    });
    if (!response.ok) throw new Error("Failed to add signal");
    return toCamelCase(await response.json()) as StoredFeedState;
  },

  async getTasteProfile(actorDid: string, generatorId: string): Promise<TasteProfileResult | null> {
    // The taste profile is computed on the backend and returned via feed-state
    // This is a helper to get it from the store directly if needed
    const state = await this.getFeedState(actorDid, generatorId);
    // The taste profile is computed client-side from the feed state
    return null;
  },
};
An unhandled error has occurred. Reload 🗙