import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";

import { Document, Packer, Paragraph, TextRun } from "docx";

import { getAppDataDir } from "../db/connection";
import type { OptimizedArticle, QaReport } from "../domain/types";

export interface WriteJobExportsInput {
  dataDir?: string;
  jobId: string;
  article: OptimizedArticle;
  qaReport: QaReport;
}

export function renderOptimizedMarkdown(article: OptimizedArticle) {
  const imageSuggestions =
    article.image_suggestions.length > 0
      ? article.image_suggestions
          .map((item) => `- ${item.source}: ${item.suggestion}`)
          .join("\n")
      : "- No image suggestions.";
  const confirmations =
    article.requires_user_confirmation.length > 0
      ? [
          "",
          "## Requires User Confirmation",
          ...article.requires_user_confirmation.map((item) => `- ${item}`),
        ].join("\n")
      : "";

  return [
    `# ${article.title}`,
    "",
    article.summary,
    "",
    article.body_markdown,
    "",
    "## Image Suggestions",
    imageSuggestions,
    confirmations,
    "",
  ].join("\n");
}

export function renderQaReportJson(report: QaReport) {
  return `${JSON.stringify(report, null, 2)}\n`;
}

export async function renderOptimizedDocx(article: OptimizedArticle) {
  const document = new Document({
    sections: [
      {
        children: [
          new Paragraph({
            children: [new TextRun({ text: article.title, bold: true, size: 32 })],
          }),
          new Paragraph(article.summary),
          ...article.body_markdown
            .split(/\r?\n/)
            .filter(Boolean)
            .map((line) => new Paragraph(line.replace(/^#+\s*/, ""))),
          new Paragraph("Image Suggestions"),
          ...article.image_suggestions.map(
            (item) => new Paragraph(`${item.source}: ${item.suggestion}`),
          ),
        ],
      },
    ],
  });

  return Packer.toBuffer(document);
}

export async function writeJobExports({
  dataDir = getAppDataDir(),
  jobId,
  article,
  qaReport,
}: WriteJobExportsInput) {
  const exportDir = join(dataDir, "exports", jobId);
  mkdirSync(exportDir, { recursive: true });

  const markdown = join(exportDir, "optimized.md");
  const docx = join(exportDir, "optimized.docx");
  const qaJson = join(exportDir, "qa_report.json");

  writeFileSync(markdown, renderOptimizedMarkdown(article), "utf8");
  writeFileSync(qaJson, renderQaReportJson(qaReport), "utf8");
  writeFileSync(docx, await renderOptimizedDocx(article));

  return { markdown, docx, qaJson };
}
