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

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

export interface ProductData {
  slug: string;
  frontmatter: ProductFrontmatter;
  content: any; // Lexical AST from Payload
  application?: any; // Lexical AST for Application field
}

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

  const result = await payload.find({
    collection: 'products',
    where: {
      and: [
        { slug: { equals: fileSlug } },
        ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []),
      ],
    },
    locale: locale as any,
    depth: 1,
    limit: 1,
  });

  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,
      },
    };
  }

  return null;
}

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

    const result = await payload.find({
      collection: 'products',
      where: {
        and: [
          { slug: { equals: fileSlug } },
          ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []),
        ],
      },
      locale: locale as any,
      depth: 1,
      limit: 1,
    });

    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,
          focalX:
            Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object'
              ? doc.images[0].focalX
              : 50,
          focalY:
            Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object'
              ? doc.images[0].focalY
              : 50,
        },
        content: doc.content,
        application: doc.application,
      };
    }

    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: {
        ...(!config.showDrafts ? { _status: { equals: 'published' } } : {}),
      },
      locale: locale as any,
      pagination: false,
    });

    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<ProductData[]> {
  try {
    const payload = await getPayload({ config: configPromise });

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

    const result = await payload.find({
      collection: 'products',
      where: {
        ...(!config.showDrafts ? { _status: { equals: 'published' } } : {}),
      },
      locale: locale as any,
      depth: 1,
      pagination: false,
      select: selectFields,
    });

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

    let products: ProductData[] = 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,
          focalX:
            Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object'
              ? doc.images[0].focalX
              : 50,
          focalY:
            Array.isArray(doc.images) && doc.images.length > 0 && typeof doc.images[0] === 'object'
              ? doc.images[0].focalY
              : 50,
        },
        content: null,
        application: null,
      };
    });

    // Filter out products with 0 images (data integrity check to prevent 404s)
    products = products.filter((p) => p.frontmatter.images && p.frontmatter.images.length > 0);

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

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