/**
 * URL Aliases for Webmention Recovery
 *
 * Maps new URLs to their old URLs so webmentions from previous
 * URL structures can be displayed on current pages.
 *
 * Place redirect map files in the parent directory of this theme:
 * - redirects.map (e.g., micro.blog: /YYYY/MM/DD/slug.html → /notes/...)
 * - old-blog-redirects.map (e.g., Known/WP: /YYYY/slug → /content/...)
 */

import { readFileSync, existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const siteUrl = process.env.SITE_URL || "https://example.com";

/**
 * Parse a redirect map file into URL mappings
 * Format: old_path new_path;
 */
function parseRedirectMap(filePath) {
  const aliases = {};

  if (!existsSync(filePath)) {
    console.log(`[urlAliases] File not found: ${filePath}`);
    return aliases;
  }

  try {
    const content = readFileSync(filePath, "utf-8");
    const lines = content.split("\n").filter((line) => {
      const trimmed = line.trim();
      return trimmed && !trimmed.startsWith("#");
    });

    for (const line of lines) {
      // Format: /old/path /new/path;
      const match = line.match(/^(\S+)\s+(\S+);?$/);
      if (match) {
        const [, oldPath, newPath] = match;
        // Normalize paths (remove trailing slashes, ensure leading slash)
        const normalizedNew = newPath.replace(/;$/, "").replace(/\/$/, "");
        const normalizedOld = oldPath.replace(/\/$/, "");

        // Map new URL → array of old URLs
        if (!aliases[normalizedNew]) {
          aliases[normalizedNew] = [];
        }
        aliases[normalizedNew].push(normalizedOld);
      }
    }
  } catch (error) {
    console.error(`[urlAliases] Error parsing ${filePath}:`, error.message);
  }

  return aliases;
}

/**
 * Merge multiple alias maps
 */
function mergeAliases(...maps) {
  const merged = {};
  for (const map of maps) {
    for (const [newUrl, oldUrls] of Object.entries(map)) {
      if (!merged[newUrl]) {
        merged[newUrl] = [];
      }
      merged[newUrl].push(...oldUrls);
    }
  }
  return merged;
}

// Parse redirect maps from /app/pkg (Docker) or parent directory (local dev)
// In Docker: eleventy-site is at /app/pkg/eleventy-site, maps are at /app/pkg/
// In local dev: maps might be at ../
const pkgRoot = resolve(__dirname, "../..");

// Helper to find first existing file
function findFile(candidates) {
  for (const path of candidates) {
    if (existsSync(path)) {
      console.log(`[urlAliases] Found: ${path}`);
      return path;
    }
  }
  console.log(`[urlAliases] No file found in: ${candidates.join(", ")}`);
  return null;
}

// Try multiple possible locations for each map type
const microblogMapPath = findFile([
  resolve(pkgRoot, "redirects.map"),
  resolve(__dirname, "../../redirects.map"),
]);

const knownMapPath = findFile([
  resolve(pkgRoot, "old-blog-redirects.map"),
  resolve(__dirname, "../../old-blog-redirects.map"),
]);

const microblogAliases = microblogMapPath ? parseRedirectMap(microblogMapPath) : {};
const knownAliases = knownMapPath ? parseRedirectMap(knownMapPath) : {};

const allAliases = mergeAliases(microblogAliases, knownAliases);

// Log summary
const totalMappings = Object.keys(allAliases).length;
const totalOldUrls = Object.values(allAliases).reduce((sum, urls) => sum + urls.length, 0);
console.log(`[urlAliases] Loaded ${totalMappings} URL mappings with ${totalOldUrls} old URLs`);

export default {
  // The merged alias map: new URL → [old URLs]
  aliases: allAliases,

  // Site URL for building absolute URLs
  siteUrl,

  /**
   * Get all URLs (old and new) that should be checked for webmentions
   * @param {string} url - Current page URL (relative)
   * @returns {string[]} - Array of absolute URLs to check
   */
  getAllUrls(url) {
    const normalizedUrl = url.replace(/\/$/, "");
    const urls = [
      `${siteUrl}${url}`,
      `${siteUrl}${normalizedUrl}`,
    ];

    // Add old URL variations
    const oldUrls = allAliases[normalizedUrl] || [];
    for (const oldUrl of oldUrls) {
      urls.push(`${siteUrl}${oldUrl}`);
      // Also try with trailing slash
      urls.push(`${siteUrl}${oldUrl}/`);
    }

    // Deduplicate
    return [...new Set(urls)];
  },

  /**
   * Get just the old URLs for a given new URL
   * @param {string} url - Current page URL (relative)
   * @returns {string[]} - Array of old relative URLs
   */
  getOldUrls(url) {
    const normalizedUrl = url.replace(/\/$/, "");
    return allAliases[normalizedUrl] || [];
  },
};
