import { rankAndDedupe, type RankedPost, type RawPost } from "@/lib/ranking";
import { threadsGraphGet } from "./client";
import type { ThreadsApiCredentials } from "./types";

interface ThreadsSearchItem {
  id?: string;
  text?: string;
  permalink?: string;
  username?: string;
  timestamp?: string;
  like_count?: number;
  reply_count?: number;
  repost_count?: number;
  quote_count?: number;
}

interface ThreadsSearchResponse {
  data?: ThreadsSearchItem[];
  paging?: {
    next?: string;
    cursors?: { after?: string };
  };
}

function toRawPost(item: ThreadsSearchItem): RawPost | null {
  if (!item.text?.trim()) return null;

  return {
    externalId: item.id,
    text: item.text.trim(),
    permalink: item.permalink,
    authorName: item.username,
    postedAt: item.timestamp ? new Date(item.timestamp) : undefined,
    likeCount: item.like_count,
    replyCount: item.reply_count,
    repostCount: item.repost_count,
  };
}

export async function keywordSearchViaThreadsApi(
  credentials: ThreadsApiCredentials,
  input: {
    query: string;
    limit?: number;
    searchType?: "TOP" | "RECENT";
  }
): Promise<RankedPost[]> {
  const json = await threadsGraphGet<ThreadsSearchResponse>("/keyword_search", {
    access_token: credentials.accessToken,
    q: input.query,
    search_type: input.searchType ?? "TOP",
    fields:
      "id,text,permalink,username,timestamp,like_count,reply_count,repost_count,quote_count",
  });

  const posts = (json.data ?? [])
    .map(toRawPost)
    .filter((post): post is RawPost => !!post);

  return rankAndDedupe(posts, input.limit ?? 20);
}
