import { existsSync, readFileSync } from "node:fs";
import type {
  WikiCollection,
  WikiManifest,
  WikiPage,
  WikiPageKind,
  WikiPageSummary,
} from "../../types/wiki-model";

// ---------------------------------------------------------------------------
// Text utilities
// ---------------------------------------------------------------------------

export function hasNonEmptyMarkdown(filePath: string): boolean {
  if (!existsSync(filePath)) {
    return false;
  }
  return readFileSync(filePath, "utf-8").trim().length > 0;
}

export function toTitleCase(segment: string): string {
  return segment
    .split(/[_\-.]+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
}

export function humanizePath(path: string): string {
  return path
    .split(/[/.]/)
    .filter(Boolean)
    .map((segment) => toTitleCase(segment))
    .join(" / ");
}

export function stripSuffix(value: string): string {
  return value
    .replace(/\s+Reverse Wiki$/i, "")
    .replace(/\s+Workflow$/i, "")
    .replace(/\s+Documentation$/i, "")
    .trim();
}

// ---------------------------------------------------------------------------
// Inference helpers
// ---------------------------------------------------------------------------

export function inferPageKind(page: WikiPageSummary): WikiPageKind {
  if (page.kind) {
    return page.kind;
  }

  if (page.pageType === "overview") {
    return "overview";
  }
  if (page.pageType === "workflow") {
    return "workflow";
  }
  if (page.pageType === "entity") {
    return "entity";
  }
  if (page.pageType === "dd") {
    return "entity";
  }

  const haystack = `${page.title} ${page.path} ${page.summary}`.toLowerCase();
  if (/(integration|adapter|client|gateway|api|rest|http|queue|msg|message|event|topic|kafka|jms)/.test(haystack)) {
    return "integration";
  }
  if (/(common|shared|core|foundation|base|util|helper)/.test(haystack)) {
    return "concept";
  }
  return "component";
}

export function inferComponentType(page: WikiPageSummary, kind: WikiPageKind): string | undefined {
  if (page.componentType) {
    return page.componentType;
  }
  if (page.pageType === "dd") {
    return "detailed design";
  }
  if (page.pageType !== "module") {
    return undefined;
  }

  const haystack = `${page.title} ${page.path}`.toLowerCase();
  if (kind === "integration") return "integration boundary";
  if (/(service|ejb|bean)/.test(haystack)) return "service layer";
  if (/(dao|repository|repo|persistence)/.test(haystack)) return "data access";
  if (/(dto|model|entity|schema|contract|msg|message)/.test(haystack)) return "data contract";
  if (/(util|helper|common|shared)/.test(haystack)) return "shared utility";
  return "component";
}

export function inferDomain(page: WikiPageSummary): string | undefined {
  if (page.domain) {
    return page.domain;
  }
  if (page.pageType === "dd") {
    return "Detailed Design";
  }
  if (!page.path || page.path === "overview") {
    return undefined;
  }
  const [segment] = page.path.split(/[/.]/).filter(Boolean);
  return segment ? toTitleCase(segment) : undefined;
}

// ---------------------------------------------------------------------------
// Display builders
// ---------------------------------------------------------------------------

export function buildDisplayTitle(page: WikiPageSummary, kind: WikiPageKind): string {
  if (page.displayTitle) {
    return page.displayTitle;
  }
  if (page.pageType === "overview") {
    return "Repository Overview";
  }
  if (page.pageType === "workflow") {
    const base = stripSuffix(page.title) || humanizePath(page.path);
    return base.endsWith("Workflow") ? base : `${base} Workflow`;
  }
  if (page.pageType === "dd") {
    return page.title;
  }

  const stripped = stripSuffix(page.title);
  if (stripped && stripped !== page.title) {
    return stripped;
  }
  if (page.path) {
    return humanizePath(page.path);
  }
  if (kind === "entity") {
    return page.title;
  }
  return stripped || page.title;
}

export function buildDisplaySummary(page: WikiPageSummary, kind: WikiPageKind): string {
  if (page.displaySummary) {
    return page.displaySummary;
  }
  if (page.pageType === "overview") {
    return page.summary || "Repository-level architecture and business context.";
  }
  if (page.pageType === "workflow") {
    return page.summary || "Technical workflow view derived from indexed source relationships.";
  }
  if (kind === "integration") {
    return page.summary || "Integration boundary, contracts, and external dependency view.";
  }
  if (page.pageType === "entity") {
    return page.summary || "Code entity reference with linked source artifacts.";
  }
  if (page.pageType === "dd") {
    return page.summary || "Detailed design document with flow diagrams and method descriptions.";
  }
  return page.summary || "Component-level reverse documentation generated from source code.";
}

export function buildReadNext(page: WikiPageSummary): string[] | undefined {
  if (page.readNext && page.readNext.length > 0) {
    return page.readNext;
  }
  if (page.childPageIds.length > 0) {
    return page.childPageIds.slice(0, 8);
  }
  return undefined;
}

// ---------------------------------------------------------------------------
// Normalization
// ---------------------------------------------------------------------------

export function normalizeSummary(page: WikiPageSummary): WikiPageSummary {
  const kind = inferPageKind(page);
  return {
    ...page,
    kind,
    status: page.status || "generated",
    displayTitle: buildDisplayTitle(page, kind),
    displaySummary: buildDisplaySummary(page, kind),
    audience: page.audience || (page.pageType === "overview" ? "engineering" : "engineering and product"),
    domain: inferDomain(page),
    componentType: inferComponentType(page, kind),
    readNext: buildReadNext(page),
    generationWarnings: page.generationWarnings || [],
    diagramErrors: page.diagramErrors || [],
  };
}

export function buildCollections(pages: WikiPageSummary[]): WikiCollection[] {
  const overview = pages.find((page) => page.pageType === "overview");
  const modules = pages.filter((page) => page.pageType === "module");
  const workflows = pages.filter((page) => page.pageType === "workflow");
  const entities = pages.filter((page) => page.pageType === "entity");
  const integrations = pages.filter((page) => page.kind === "integration");

  const collections: WikiCollection[] = [];
  if (overview) {
    collections.push({ id: "overview", title: "Overview", pageIds: [overview.id] });
  }
  if (modules.length > 0) {
    collections.push({ id: "components", title: "Components", pageIds: modules.map((page) => page.id) });
  }
  if (integrations.length > 0) {
    collections.push({ id: "integrations", title: "Integrations", pageIds: integrations.map((page) => page.id) });
  }
  if (workflows.length > 0) {
    collections.push({ id: "workflows", title: "Workflows", pageIds: workflows.map((page) => page.id) });
  }
  if (entities.length > 0) {
    collections.push({ id: "entities", title: "Entities", pageIds: entities.map((page) => page.id) });
  }
  const ddPages = pages.filter((page) => page.pageType === "dd");
  if (ddPages.length > 0) {
    collections.push({ id: "detailed-design", title: "Detailed Design", pageIds: ddPages.map((page) => page.id) });
  }
  return collections;
}

export function normalizeManifest(manifest: WikiManifest): WikiManifest {
  const pages = manifest.pages.map((page) => normalizeSummary(page));
  return {
    ...manifest,
    pages,
    collections: manifest.collections && manifest.collections.length > 0
      ? manifest.collections
      : buildCollections(pages),
  };
}

export function normalizePage(page: WikiPage, manifest: WikiManifest | null): WikiPage {
  const summary = normalizeSummary(page);
  const fallbackReadNext = summary.readNext
    || manifest?.pages.find((candidate) => candidate.id === page.id)?.readNext
    || [];

  return {
    ...page,
    ...summary,
    sections: page.sections,
    researchArtifactIds: page.researchArtifactIds || [],
    reviewWarnings: page.reviewWarnings || [],
    readNext: fallbackReadNext,
  };
}
