import { getPayload } from 'payload';
import configPromise from '@payload-config';
import { mapSlugToFileSlug } from './slugs';

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

export interface ProductMdx {
  slug: string;
  frontmatter: ProductFrontmatter;
  content: any; // Lexical AST from Payload
}

export async function getProductMetadata(
  slug: string,
  locale: string,
): Promise<Partial<ProductMdx> | null> {
  const payload = await getPayload({ config: configPromise });
  const fileSlug = await mapSlugToFileSlug(slug, locale);

  let result = await payload.find({
    collection: 'products',
    where: {
      and: [{ slug: { equals: fileSlug } }, { locale: { equals: locale } }],
    },
    depth: 1, // To auto-resolve Media relation (images array)
    limit: 1,
  });

  let isFallback = false;

  if (result.docs.length === 0 && locale !== 'en') {
    // Fallback to English
    result = await payload.find({
      collection: 'products',
      where: {
        and: [{ slug: { equals: fileSlug } }, { locale: { equals: 'en' } }],
      },
      depth: 1,
      limit: 1,
    });
    if (result.docs.length > 0) {
      isFallback = true;
    }
  }

  if (result.docs.length > 0) {
    const doc = result.docs[0];

    // Process Images
    const resolvedImages = ((doc.images as any[]) || [])
      .map((img) => (typeof img === 'string' ? img : img.url))
      .filter(Boolean);

    if (resolvedImages.length === 0) return null;

    return {
      slug: doc.slug,
      frontmatter: {
        title: doc.title,
        sku: doc.sku,
        description: doc.description,
        categories: Array.isArray(doc.categories) ? doc.categories.map((c: any) => c.category) : [],
        images: resolvedImages,
        locale: doc.locale,
        isFallback,
      },
    };
  }

  return null;
}

export async function getProductBySlug(slug: string, locale: string): Promise<ProductMdx | null> {
  try {
    const payload = await getPayload({ config: configPromise });
    const fileSlug = await mapSlugToFileSlug(slug, locale);

    let result = await payload.find({
      collection: 'products',
      where: {
        and: [{ slug: { equals: fileSlug } }, { locale: { equals: locale } }],
      },
      depth: 1, // Auto-resolve Media logic
      limit: 1,
    });

    let isFallback = false;

    if (result.docs.length === 0 && locale !== 'en') {
      // Fallback to English
      result = await payload.find({
        collection: 'products',
        where: {
          and: [{ slug: { equals: fileSlug } }, { locale: { equals: 'en' } }],
        },
        depth: 1,
        limit: 1,
      });
      if (result.docs.length > 0) {
        isFallback = true;
      }
    }

    if (result.docs.length > 0) {
      const doc = result.docs[0];

      // Map Images correctly from resolved Media docs
      const resolvedImages = ((doc.images as any[]) || [])
        .map((img) => (typeof img === 'string' ? img : img.url))
        .filter(Boolean);

      if (resolvedImages.length === 0) return null;

      return {
        slug: doc.slug,
        frontmatter: {
          title: doc.title,
          sku: doc.sku,
          description: doc.description,
          categories: Array.isArray(doc.categories)
            ? doc.categories.map((c: any) => c.category)
            : [],
          images: resolvedImages,
          locale: doc.locale,
          isFallback,
        },
        content: doc.content, // Lexical payload instead of raw MDX String
      };
    }

    return null;
  } catch (error) {
    console.error(`[Payload] getProductBySlug failed for ${slug}:`, error);
    return null;
  }
}

export async function getAllProductSlugs(locale: string): Promise<string[]> {
  try {
    const payload = await getPayload({ config: configPromise });
    const result = await payload.find({
      collection: 'products',
      where: {
        locale: {
          equals: locale,
        },
      },
      pagination: false, // get all docs
    });

    return result.docs.map((doc) => doc.slug);
  } catch (error) {
    console.error(`[Payload] getAllProductSlugs failed for ${locale}:`, error);
    return [];
  }
}

export async function getAllProducts(locale: string): Promise<ProductMdx[]> {
  try {
    const payload = await getPayload({ config: configPromise });

    const selectFields = {
      title: true,
      slug: true,
      sku: true,
      description: true,
      categories: true,
      images: true,
      locale: true,
    } as const;

    // Get products for this locale
    const result = await payload.find({
      collection: 'products',
      where: { locale: { equals: locale } },
      depth: 1,
      pagination: false,
      select: selectFields,
    });

    console.log(`[Payload] getAllProducts for ${locale}: Found ${result.docs.length} docs`);

    let products: ProductMdx[] = result.docs.map((doc) => {
      const resolvedImages = ((doc.images as any[]) || [])
        .map((img) => (typeof img === 'string' ? img : img.url))
        .filter(Boolean) as string[];

      const plainCategories = Array.isArray(doc.categories)
        ? doc.categories.map((c: any) => String(c.category))
        : [];

      return {
        slug: String(doc.slug),
        frontmatter: {
          title: String(doc.title),
          sku: doc.sku ? String(doc.sku) : '',
          description: doc.description ? String(doc.description) : '',
          categories: plainCategories,
          images: resolvedImages,
          locale: String(doc.locale),
        },
        content: null,
      };
    });

    // Also include English fallbacks for slugs not in this locale
    if (locale !== 'en') {
      const localeSlugs = new Set(products.map((p) => p.slug));
      const enResult = await payload.find({
        collection: 'products',
        where: { locale: { equals: 'en' } },
        depth: 1,
        pagination: false,
        select: selectFields,
      });

      console.log(
        `[Payload] getAllProducts (en fallbacks) for ${locale}: Found ${enResult.docs.length} docs`,
      );

      const fallbacks = enResult.docs
        .filter((doc) => !localeSlugs.has(doc.slug))
        .map((doc) => {
          const resolvedImages = ((doc.images as any[]) || [])
            .map((img) => (typeof img === 'string' ? img : img.url))
            .filter(Boolean) as string[];

          const plainCategories = Array.isArray(doc.categories)
            ? doc.categories.map((c: any) => String(c.category))
            : [];

          return {
            slug: String(doc.slug),
            frontmatter: {
              title: String(doc.title),
              sku: doc.sku ? String(doc.sku) : '',
              description: doc.description ? String(doc.description) : '',
              categories: plainCategories,
              images: resolvedImages,
              locale: String(doc.locale),
              isFallback: true,
            },
            content: null,
          };
        });

      products = [...products, ...fallbacks];
    }

    return products;
  } catch (error) {
    console.error(`[Payload] getAllProducts failed for ${locale}:`, error);
    return [];
  }
}

export async function getAllProductsMetadata(locale: string): Promise<Partial<ProductMdx>[]> {
  const products = await getAllProducts(locale);
  return products.map((p) => ({
    slug: p.slug,
    frontmatter: p.frontmatter,
  }));
}
