import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { mapSlugToFileSlug } from './slugs';

export interface ProductFrontmatter {
  title: string;
  sku: string;
  description: string;
  categories: string[];
  images: string[];
  locale: string;
}

export interface ProductMdx {
  slug: string;
  frontmatter: ProductFrontmatter;
  content: string;
}

export async function getProductMetadata(
  slug: string,
  locale: string,
): Promise<Partial<ProductMdx> | null> {
  // Map translated slug to file slug
  const fileSlug = await mapSlugToFileSlug(slug, locale);
  const productsDir = path.join(process.cwd(), 'data', 'products', locale);

  // Try exact slug first
  let filePath = path.join(productsDir, `${fileSlug}.mdx`);

  if (!fs.existsSync(filePath)) {
    // Try with -2 suffix (common in the dumped files)
    filePath = path.join(productsDir, `${fileSlug}-2.mdx`);
  }

  if (!fs.existsSync(filePath)) {
    // Fallback to English if locale is not 'en'
    if (locale !== 'en') {
      const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en');
      let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`);
      if (!fs.existsSync(enFilePath)) {
        enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`);
      }

      if (fs.existsSync(enFilePath)) {
        const fileContent = fs.readFileSync(enFilePath, 'utf8');
        const { data } = matter(fileContent);
        return {
          slug: fileSlug,
          frontmatter: {
            ...data,
            isFallback: true,
          } as ProductFrontmatter & { isFallback?: boolean },
        };
      }
    }
  } else {
    const fileContent = fs.readFileSync(filePath, 'utf8');
    const { data } = matter(fileContent);

    return {
      slug: fileSlug,
      frontmatter: data as ProductFrontmatter,
    };
  }

  return null;
}

export async function getProductBySlug(slug: string, locale: string): Promise<ProductMdx | null> {
  // Map translated slug to file slug
  const fileSlug = await mapSlugToFileSlug(slug, locale);
  const productsDir = path.join(process.cwd(), 'data', 'products', locale);

  // Try exact slug first
  let filePath = path.join(productsDir, `${fileSlug}.mdx`);

  if (!fs.existsSync(filePath)) {
    // Try with -2 suffix (common in the dumped files)
    filePath = path.join(productsDir, `${fileSlug}-2.mdx`);
  }

  let product: ProductMdx | null = null;

  if (!fs.existsSync(filePath)) {
    // Fallback to English if locale is not 'en'
    if (locale !== 'en') {
      const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en');
      let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`);
      if (!fs.existsSync(enFilePath)) {
        enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`);
      }

      if (fs.existsSync(enFilePath)) {
        const fileContent = fs.readFileSync(enFilePath, 'utf8');
        const { data, content } = matter(fileContent);
        product = {
          slug: fileSlug,
          frontmatter: {
            ...data,
            isFallback: true,
          } as ProductFrontmatter & { isFallback?: boolean },
          content,
        };
      }
    }
  } else {
    const fileContent = fs.readFileSync(filePath, 'utf8');
    const { data, content } = matter(fileContent);

    product = {
      slug: fileSlug,
      frontmatter: data as ProductFrontmatter,
      content,
    };
  }

  // Filter out products without images
  if (
    product &&
    (!product.frontmatter.images ||
      product.frontmatter.images.length === 0 ||
      !product.frontmatter.images[0])
  ) {
    return null;
  }

  return product;
}

export async function getAllProductSlugs(locale: string): Promise<string[]> {
  const productsDir = path.join(process.cwd(), 'data', 'products', locale);
  if (!fs.existsSync(productsDir)) return [];

  const files = fs.readdirSync(productsDir);
  return files.filter((file) => file.endsWith('.mdx')).map((file) => file.replace(/\.mdx$/, ''));
}

export async function getAllProducts(locale: string): Promise<ProductMdx[]> {
  const slugs = await getAllProductSlugs(locale);
  let allSlugs = slugs;

  if (locale !== 'en') {
    const enSlugs = await getAllProductSlugs('en');
    allSlugs = Array.from(new Set([...slugs, ...enSlugs]));
  }

  const products = await Promise.all(allSlugs.map((slug) => getProductBySlug(slug, locale)));
  return products.filter((p): p is ProductMdx => p !== null);
}

export async function getAllProductsMetadata(locale: string): Promise<Partial<ProductMdx>[]> {
  const slugs = await getAllProductSlugs(locale);
  let allSlugs = slugs;

  if (locale !== 'en') {
    const enSlugs = await getAllProductSlugs('en');
    allSlugs = Array.from(new Set([...slugs, ...enSlugs]));
  }

  const metadata = await Promise.all(allSlugs.map((slug) => getProductMetadata(slug, locale)));
  return metadata.filter((m): m is Partial<ProductMdx> => m !== null);
}
