import { promises as fs } from "fs";
import path from "path";

const LOGS_DIR = path.join(process.cwd(), "logs");

export type PublishLogLevel = "info" | "warn" | "error" | "success";

export interface PublishLogEntry {
  timestamp: string;
  level: PublishLogLevel;
  action: string;
  projectId?: string;
  postId?: string;
  platform?: string;
  timezone?: string;
  regions?: string[];
  message: string;
  details?: Record<string, unknown>;
}

async function ensureLogsDir() {
  await fs.mkdir(LOGS_DIR, { recursive: true });
}

function logFilename() {
  const d = new Date();
  const date = d.toISOString().slice(0, 10);
  return `publish-${date}.log`;
}

export async function writePublishLog(entry: Omit<PublishLogEntry, "timestamp">) {
  await ensureLogsDir();
  const line: PublishLogEntry = {
    ...entry,
    timestamp: new Date().toISOString(),
  };
  const text = `${JSON.stringify(line)}\n`;
  await fs.appendFile(path.join(LOGS_DIR, logFilename()), text, "utf-8");

  if (entry.level === "error") {
    try {
      const { logAppError } = await import("@/lib/logging/app-error-logger");
      await logAppError({
        level: "ERROR",
        area: "publish",
        event: entry.action,
        projectId: entry.projectId,
        platform: entry.platform,
        message: entry.message,
        details: entry.details,
      });
    } catch {
      // ignore mirror failures
    }
  }
}

export async function readPublishLogs(input?: {
  projectId?: string;
  platform?: string;
  limit?: number;
  date?: string;
}): Promise<PublishLogEntry[]> {
  const limit = input?.limit ?? 100;
  const date = input?.date ?? new Date().toISOString().slice(0, 10);
  const file = path.join(LOGS_DIR, `publish-${date}.log`);

  let raw = "";
  try {
    raw = await fs.readFile(file, "utf-8");
  } catch {
    return [];
  }

  const lines = raw.trim().split("\n").filter(Boolean);
  const entries: PublishLogEntry[] = [];

  for (const line of lines) {
    try {
      entries.push(JSON.parse(line) as PublishLogEntry);
    } catch {
      // skip malformed
    }
  }

  let filtered = entries;
  if (input?.projectId) {
    filtered = filtered.filter((e) => e.projectId === input.projectId);
  }
  if (input?.platform) {
    filtered = filtered.filter((e) => e.platform === input.platform);
  }

  return filtered.slice(-limit).reverse();
}
