import { existsSync, realpathSync, statSync } from "node:fs";
import { dirname, extname, join, resolve } from "node:path";
import type { StructuredImportDecl } from "@wrnexus/syntax";

export type ImportMode = "legacy" | "compatible" | "explicit";
export interface ImportResolverOptions {
  appRoot: string;
  mode?: ImportMode;
  aliases?: Record<string, string>;
}
export interface ResolvedImport {
  declaration: StructuredImportDecl;
  resolved?: string;
  diagnostic?: { code: string; message: string; severity: "error" | "warning" };
}

function candidates(path: string): string[] {
  return extname(path)
    ? [path]
    : [
        path,
        `${path}.wrn`,
        `${path}.ts`,
        `${path}.d.ts`,
        join(path, "index.wrn"),
        join(path, "index.ts"),
      ];
}

export function resolveWrnImport(
  declaration: StructuredImportDecl,
  importer: string,
  options: ImportResolverOptions,
): ResolvedImport {
  const source = declaration.source;
  const aliases: Record<string, string> = {
    "@": "./app",
    ...(options.aliases ?? {}),
  };
  const alias = Object.keys(aliases)
    .filter((key) => key.length > 0 && (source === key || source.startsWith(`${key}/`)))
    .sort((left, right) => right.length - left.length)[0];
  if (!source.startsWith(".") && !alias) return { declaration, resolved: source };
  const base = alias
    ? resolve(
        options.appRoot,
        aliases[alias]!,
        source === alias ? "" : source.slice(alias.length + 1),
      )
    : resolve(dirname(importer), source);
  const found = candidates(base).find((candidate) => {
    if (!existsSync(candidate)) return false;
    try {
      return statSync(candidate).isFile();
    } catch {
      return false;
    }
  });
  if (found) return { declaration, resolved: realpathSync(found) };
  const severity = (options.mode ?? "compatible") === "explicit" ? "error" : "warning";
  return {
    declaration,
    diagnostic: {
      code: "WRN-IMPORT-NOT-FOUND",
      message: `Cannot resolve import '${source}' from ${importer}`,
      severity,
    },
  };
}

export function resolveWrnImports(
  declarations: StructuredImportDecl[],
  importer: string,
  options: ImportResolverOptions,
): ResolvedImport[] {
  return declarations.map((declaration) => resolveWrnImport(declaration, importer, options));
}
