import { TFile, type Vault } from "obsidian";

export interface ImageReference {
  alt: string;
  path: string;
  fullMatch: string;
}

const IMAGE_PATTERN = /!\[([^\]]*)\]\(([^)]+)\)/g;

export function extractImageReferences(content: string): ImageReference[] {
  const references: ImageReference[] = [];
  const matches = content.matchAll(IMAGE_PATTERN);

  for (const match of matches) {
    const [, alt, path] = match;

    if (isExternalUrl(path)) {
      continue;
    }

    references.push({
      alt,
      path,
      fullMatch: match[0],
    });
  }

  return references;
}

export function getAbsolutePath(vault: Vault, filePath: string, currentFilePath: string): string | null {
  let absolutePath: string;

  if (filePath.startsWith("./") || filePath.startsWith("../")) {
    absolutePath = resolveRelativePath(currentFilePath, filePath);
  } else if (filePath.startsWith("/")) {
    absolutePath = filePath.substring(1);
  } else {
    absolutePath = resolveRelativePath(currentFilePath, filePath);
  }

  const file = vault.getAbstractFileByPath(absolutePath);

  if (file instanceof TFile) {
    return absolutePath;
  }

  return null;
}

export function replaceImagePaths(content: string, pathMapping: Map<string, string>): string {
  return content.replace(IMAGE_PATTERN, (fullMatch, alt, path) => {
    const newPath = pathMapping.get(path);

    if (newPath) {
      return `![${alt}](${newPath})`;
    }

    return fullMatch;
  });
}

function isExternalUrl(path: string): boolean {
  return path.startsWith("http://") || path.startsWith("https://") || path.startsWith("data:");
}

function resolveRelativePath(currentFilePath: string, relativePath: string): string {
  const currentParts = currentFilePath.split("/");
  currentParts.pop();

  const relativeParts = relativePath.split("/");

  for (const part of relativeParts) {
    if (part === "..") {
      currentParts.pop();
    } else if (part !== ".") {
      currentParts.push(part);
    }
  }

  return currentParts.join("/");
}
