/**
 * Append-only log of thumbs-up / thumbs-down ratings on surfaced threads.
 *
 * Each entry is one rating event — multiple ratings per item are preserved so
 * the algorithm can see if Pavel consistently marks something as noise across
 * scan runs (stronger signal than a one-off thumbs-down).
 *
 * Storage: THREAD_FEEDBACK_FILE (JSON array, newest last). Never mutated —
 * only appended. Reader groups by itemKey to get the latest rating per thread.
 */
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
import { dirname } from "node:path";
import { THREAD_FEEDBACK_FILE } from "./paths";

export type FeedbackRating = "signal" | "noise";

export type ThreadFeedbackEntry = {
  itemKey: string;
  file: string;
  line: number;
  text: string;
  source: string;
  kind: string;
  rating: FeedbackRating;
  at: string; // ISO timestamp
  /** Snapshot of the latest check verdict at time of rating — the algorithm's
   *  "reasoning" that Pavel is approving or rejecting. */
  checkSnapshot?: {
    verdict: string | null;
    rationale: string;
    suggested: string;
    checkedAt: string;
  };
};

export function loadFeedback(): ThreadFeedbackEntry[] {
  if (!existsSync(THREAD_FEEDBACK_FILE)) return [];
  try {
    const data = JSON.parse(readFileSync(THREAD_FEEDBACK_FILE, "utf8"));
    return Array.isArray(data) ? data : [];
  } catch {
    return [];
  }
}

export function appendFeedback(entry: ThreadFeedbackEntry): void {
  const list = loadFeedback();
  list.push(entry);
  try {
    mkdirSync(dirname(THREAD_FEEDBACK_FILE), { recursive: true });
    writeFileSync(THREAD_FEEDBACK_FILE, JSON.stringify(list, null, 2));
  } catch (err) {
    console.error("[thread-feedback] write failed:", err);
  }
}

/** Latest rating per itemKey — used by the algorithm to apply suppression. */
export function latestRatingByKey(): Record<string, FeedbackRating> {
  const out: Record<string, FeedbackRating> = {};
  for (const e of loadFeedback()) {
    out[e.itemKey] = e.rating;
  }
  return out;
}
