import { promises as fs } from "fs";
import path from "path";
import type { AiCallUsage, AiUsageSummary } from "./cost-tracking";
import { summarizeUsage } from "./cost-tracking";

const LOG_DIR = path.join(process.cwd(), "data", "ai-usage-logs");

function monthFile(): string {
  const d = new Date();
  const ym = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
  return path.join(LOG_DIR, `${ym}.jsonl`);
}

async function appendLogLine(entry: AiCallUsage): Promise<void> {
  await fs.mkdir(LOG_DIR, { recursive: true });
  await fs.appendFile(monthFile(), `${JSON.stringify(entry)}\n`, "utf-8");
}

/** Persist one API call — console log kept for server monitoring. */
export async function logAiUsageCall(entry: AiCallUsage): Promise<void> {
  const tokens =
    entry.inputTokens != null || entry.outputTokens != null
      ? ` in=${entry.inputTokens ?? 0} out=${entry.outputTokens ?? 0}`
      : "";
  console.info(
    `[PostSync AI Cost] ${entry.operation} | ${entry.provider}/${entry.model} | $${entry.estimatedCostUsd.toFixed(4)}${tokens}${entry.postId ? ` | post=${entry.postId}` : ""}`,
  );
  try {
    await appendLogLine(entry);
  } catch (err) {
    console.warn("[PostSync] AI usage log write failed:", err);
  }
}

export class PostAiUsageTracker {
  private calls: AiCallUsage[] = [];

  constructor(
    private meta: { postId?: string; projectId?: string },
  ) {}

  add(call: Omit<AiCallUsage, "timestamp" | "postId" | "projectId">): AiCallUsage {
    const entry: AiCallUsage = {
      ...call,
      postId: this.meta.postId,
      projectId: this.meta.projectId,
      timestamp: new Date().toISOString(),
    };
    this.calls.push(entry);
    void logAiUsageCall(entry);
    return entry;
  }

  summary(): AiUsageSummary {
    return summarizeUsage(this.calls);
  }
}

export async function readAiUsageLogs(limit = 100): Promise<AiCallUsage[]> {
  try {
    await fs.mkdir(LOG_DIR, { recursive: true });
    const files = (await fs.readdir(LOG_DIR))
      .filter((f) => f.endsWith(".jsonl"))
      .sort()
      .reverse();

    const lines: string[] = [];
    for (const file of files) {
      if (lines.length >= limit) break;
      const raw = await fs.readFile(path.join(LOG_DIR, file), "utf-8");
      const fileLines = raw.trim().split("\n").filter(Boolean).reverse();
      for (const line of fileLines) {
        if (lines.length >= limit) break;
        lines.push(line);
      }
    }

    return lines.map((line) => JSON.parse(line) as AiCallUsage);
  } catch {
    return [];
  }
}
