import { type Poll, fetchCandidacyMandates, fetchPolls, fetchPollsByIds, fetchTopics, fetchVotes, } from "@/shared/lib/aw-api" export interface FeedTopicRef { label: string url: string | null } export interface FeedItem { id: string kind: "poll" | "vorgang" | "session" | "decision" status: "upcoming" | "past" title: string url: string | null date: string | null topics: FeedTopicRef[] source: string result?: "accepted" | "rejected" | "conducted" | "referred" | null } function classifyPoll(poll: Poll): "upcoming" | "past" { // field_accepted is only present on completed votes if (poll.field_accepted != null) return "past" if (!poll.field_poll_date) return "upcoming" const today = new Date().toISOString().slice(0, 10) return poll.field_poll_date > today ? "upcoming" : "past" } export async function assembleFeed(followedTopicIDs: number[], followedPoliticianIDs: number[]): Promise { const [topics, polls] = await Promise.all([fetchTopics(), fetchPolls(150)]) const topicMap = new Map(topics.map((t) => [t.id, t.label])) const topicSet = new Set(followedTopicIDs) const filteredByTopics = topicSet.size > 0 ? polls.filter((p) => p.field_topics.some((t) => topicSet.has(t.id))) : [] const politicianPolls = await fetchPollsForPoliticians(followedPoliticianIDs) const combined = new Map() for (const p of [...filteredByTopics, ...politicianPolls]) combined.set(p.id, p) const items: FeedItem[] = Array.from(combined.values()).map((poll) => ({ id: `poll-${poll.id}`, kind: "poll", status: classifyPoll(poll), title: poll.label, url: poll.abgeordnetenwatch_url ?? null, date: poll.field_poll_date, topics: poll.field_topics.flatMap((t) => { const label = t.label ?? topicMap.get(t.id) return label ? [{ label, url: t.abgeordnetenwatch_url ?? null }] : [] }), source: "Bundestag", })) return items.sort((a, b) => { if (a.date && b.date) return b.date.localeCompare(a.date) if (!a.date && b.date) return 1 if (a.date && !b.date) return -1 return a.title.localeCompare(b.title) }) } async function fetchPollsForPoliticians(politicianIDs: number[]): Promise { if (politicianIDs.length === 0) return [] const mandateResults = await Promise.all(politicianIDs.map((pid) => fetchCandidacyMandates(pid))) const mandateIDs = mandateResults.flatMap((mandates) => mandates.slice(0, 3).map((m) => m.id)) const voteResults = await Promise.all(mandateIDs.map((mid) => fetchVotes(mid))) const pollIDSet = new Set() for (const votes of voteResults) { for (const v of votes) { if (v.poll?.id != null) pollIDSet.add(v.poll.id) } } return fetchPollsByIds(Array.from(pollIDSet)) }