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

export interface PageFrontmatter {
  title: string;
  excerpt: string;
  featuredImage: string | null;
  focalX?: number;
  focalY?: number;
  layout?: 'default' | 'fullBleed';
  public?: boolean;
}

export interface PageData {
  slug: string;
  redirectUrl?: string;
  redirectPermanent?: boolean;
  frontmatter: PageFrontmatter;
  content: any; // Lexical AST Document
}

function mapDoc(doc: any): PageData {
  return {
    slug: doc.slug,
    frontmatter: {
      title: doc.title,
      excerpt: doc.excerpt || '',
      featuredImage:
        typeof doc.featuredImage === 'object' && doc.featuredImage !== null
          ? doc.featuredImage.sizes?.card?.url || doc.featuredImage.url
          : null,
      focalX:
        typeof doc.featuredImage === 'object' && doc.featuredImage !== null
          ? doc.featuredImage.focalX
          : 50,
      focalY:
        typeof doc.featuredImage === 'object' && doc.featuredImage !== null
          ? doc.featuredImage.focalY
          : 50,
      layout: doc.layout || 'default',
    } as PageFrontmatter,
    content: doc.content as any,
  };
}

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

    // Try finding exact match first
    let result = await payload.find({
      collection: 'pages',
      where: {
        and: [
          { slug: { equals: fileSlug } },
          ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []),
        ],
      },
      locale: locale as any,
      depth: 1,
      limit: 1,
    });

    // Fallback: search ALL locales
    if (result.docs.length === 0) {
      const crossResult = await payload.find({
        collection: 'pages',
        where: {
          and: [
            { slug: { equals: fileSlug } },
            ...(!config.showDrafts ? [{ _status: { equals: 'published' } }] : []),
          ],
        },
        locale: 'all',
        depth: 1,
        limit: 1,
      });

      if (crossResult.docs.length > 0) {
        // Fetch missing exact match by internal id
        result = await payload.find({
          collection: 'pages',
          where: {
            id: { equals: crossResult.docs[0].id },
          },
          locale: locale as any,
          depth: 1,
          limit: 1,
        });
      }
    }

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

      return {
        slug: doc.slug,
        redirectUrl: doc.redirectUrl,
        redirectPermanent: doc.redirectPermanent ?? true,
        frontmatter: {
          title: doc.title,
          excerpt: doc.excerpt || '',
          featuredImage:
            typeof doc.featuredImage === 'object' && doc.featuredImage !== null
              ? doc.featuredImage.sizes?.card?.url || doc.featuredImage.url
              : null,
          focalX:
            typeof doc.featuredImage === 'object' && doc.featuredImage !== null
              ? doc.featuredImage.focalX
              : 50,
          focalY:
            typeof doc.featuredImage === 'object' && doc.featuredImage !== null
              ? doc.featuredImage.focalY
              : 50,
          layout:
            doc.layout === 'fullBleed' || doc.layout === 'default'
              ? doc.layout
              : ('default' as const),
        },
        content: doc.content,
      };
    }

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

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

    const result = await payload.find({
      collection: 'pages' as any,
      locale: locale as any,
      limit: 100,
    });

    return (result.docs as any[]).map(mapDoc);
  } catch (error) {
    console.error(`[Payload] getAllPages failed for ${locale}:`, error);
    return [];
  }
}

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

    const result = await payload.find({
      collection: 'pages' as any,
      locale: locale as any,
      limit: 100,
    });

    return (result.docs as any[]).map((doc: any) => ({
      slug: doc.slug,
      frontmatter: {
        title: doc.title,
        excerpt: doc.excerpt || '',
        featuredImage:
          typeof doc.featuredImage === 'object' && doc.featuredImage !== null
            ? doc.featuredImage.sizes?.card?.url || doc.featuredImage.url
            : null,
        focalX:
          typeof doc.featuredImage === 'object' && doc.featuredImage !== null
            ? doc.featuredImage.focalX
            : 50,
        focalY:
          typeof doc.featuredImage === 'object' && doc.featuredImage !== null
            ? doc.featuredImage.focalY
            : 50,
      } as PageFrontmatter,
    }));
  } catch (error) {
    console.error(`[Payload] getAllPagesMetadata failed for ${locale}:`, error);
    return [];
  }
}
