/**
 * Landing Page Image Resolver
 *
 * Resolves images for each landing page section using a 3-tier priority chain:
 *
 *   Tier 1 — USER UPLOAD: Check section.media for images the user has already uploaded.
 *   Tier 2 — WEB SEARCH: If no user images, search the web for relevant high-quality images.
 *   Tier 3 — AI GENERATION: If web search yields no results, generate an image via AI.
 *
 * Resolved images are downloaded to the server filesystem and served from
 * uploads/landing-pages/{pageId}/images/ so they persist across restarts.
 */

import fs from 'fs';
import path from 'path';
import { searchImages, buildSectionImageQuery, SearchImageResult } from '../utils/imageSearch';
import type { LandingPageSection, ResolvedSectionImage } from './aiContext/landingPageWebsitePrompts';

// ============================================
// TYPES
// ============================================

export interface ImageResolverInputs {
  pageId: string;
  companyId: string;
  sections: LandingPageSection[];
  businessContext: {
    companyName?: string;
    industry?: string;
    primaryOffering?: string;
  };
  options?: {
    maxImagesPerSection?: number;
    skipAiGeneration?: boolean;
  };
}

export interface ImageResolverResult {
  resolvedImages: ResolvedSectionImage[];
  summary: {
    userUpload: number;
    webSearch: number;
    aiGeneration: number;
    total: number;
  };
}

// ============================================
// FILESYSTEM HELPERS
// ============================================

function getPageImagesDir(pageId: string): string {
  return path.join(process.cwd(), 'uploads', 'landing-pages', pageId, 'images');
}

function getImageFilePath(pageId: string, filename: string): string {
  return path.join(getPageImagesDir(pageId), filename);
}

async function downloadImage(url: string, outputPath: string): Promise<boolean> {
  try {
    const response = await fetch(url, { signal: AbortSignal.timeout(15000) });
    if (!response.ok) return false;
    const buffer = Buffer.from(await response.arrayBuffer());
    fs.mkdirSync(path.dirname(outputPath), { recursive: true });
    fs.writeFileSync(outputPath, buffer);
    return true;
  } catch (error: any) {
    console.warn(`[ImageResolver] Failed to download image: ${error.message}`);
    return false;
  }
}

async function validateUrl(url: string): Promise<boolean> {
  try {
    const response = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(5000) });
    return response.ok;
  } catch {
    return false;
  }
}

// ============================================
// TIER 1 — USER UPLOAD
// ============================================

async function resolveUserUploads(
  sections: LandingPageSection[]
): Promise<ResolvedSectionImage[]> {
  const results: ResolvedSectionImage[] = [];

  for (let i = 0; i < sections.length; i++) {
    const section = sections[i];
    if (!section.media || section.media.length === 0) continue;

    for (const url of section.media) {
      if (!url || typeof url !== 'string') continue;
      const isReachable = await validateUrl(url);
      if (isReachable) {
        results.push({
          url,
          source: 'user-upload',
          altText: `${section.name} image`,
          sectionIndex: i,
        });
      }
    }
  }

  return results;
}

// ============================================
// TIER 2 — WEB SEARCH
// ============================================

async function resolveWebSearch(
  sections: LandingPageSection[],
  businessContext: ImageResolverInputs['businessContext'],
  maxPerSection: number
): Promise<ResolvedSectionImage[]> {
  const results: ResolvedSectionImage[] = [];

  for (let i = 0; i < sections.length; i++) {
    const section = sections[i];
    // Skip sections that don't naturally need images
    const imageHeavyTypes = ['hero', 'features', 'benefits', 'case-studies', 'founder-story', 'product-walkthrough', 'custom', 'video-block'];
    const needsImage = imageHeavyTypes.includes(section.type || '') || ((section.media?.length ?? 0) > 0);
    if (!needsImage) continue;

    const query = buildSectionImageQuery(section, businessContext);
    const searchResults = await searchImages(query, maxPerSection);

    for (const img of searchResults) {
      results.push({
        url: img.url,
        source: 'web-search',
        altText: img.description || `${section.name} image`,
        sectionIndex: i,
      });
    }
  }

  return results;
}

// ============================================
// TIER 3 — AI IMAGE GENERATION
// ============================================

/**
 * Generate an image for a landing page section using OpenAI DALL-E.
 * This is a simplified wrapper compared to the full imageGenerations.ts route.
 */
async function generateSectionImage(
  section: LandingPageSection,
  businessContext: ImageResolverInputs['businessContext']
): Promise<string | null> {
  const openaiKey = process.env.OPENAI_API_KEY || '';
  if (!openaiKey) {
    console.warn('[ImageResolver] No OPENAI_API_KEY configured — skipping AI image generation tier.');
    return null;
  }

  const query = buildSectionImageQuery(section, businessContext);
  const prompt = `Professional, high-quality landing page image for a ${businessContext.industry || 'business'} company. ${query}. Modern, clean, visually appealing, suitable for a dark-themed website. No text overlays. Photorealistic style.`;

  try {
    const response = await fetch('https://api.openai.com/v1/images/generations', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${openaiKey}`,
      },
      body: JSON.stringify({
        model: 'dall-e-3',
        prompt: prompt.slice(0, 4000),
        n: 1,
        size: '1024x1024',
        quality: 'standard',
        style: 'vivid',
      }),
      signal: AbortSignal.timeout(60000),
    });

    if (!response.ok) {
      const errorText = await response.text();
      console.warn(`[ImageResolver] OpenAI image generation error: ${errorText}`);
      return null;
    }

    const data: any = await response.json();
    const imageUrl = data?.data?.[0]?.url;
    if (!imageUrl) {
      console.warn('[ImageResolver] OpenAI returned no image URL');
      return null;
    }

    return imageUrl;
  } catch (error: any) {
    console.warn(`[ImageResolver] AI image generation failed: ${error.message}`);
    return null;
  }
}

async function resolveAiGeneration(
  sections: LandingPageSection[],
  businessContext: ImageResolverInputs['businessContext'],
  pageId: string
): Promise<ResolvedSectionImage[]> {
  const results: ResolvedSectionImage[] = [];

  for (let i = 0; i < sections.length; i++) {
    const section = sections[i];
    const imageHeavyTypes = ['hero', 'features', 'benefits', 'case-studies', 'founder-story', 'product-walkthrough', 'custom'];
    const needsImage = imageHeavyTypes.includes(section.type || '');
    if (!needsImage) continue;

    const imageUrl = await generateSectionImage(section, businessContext);
    if (imageUrl) {
      // Download and save locally
      const ext = '.png';
      const filename = `section-${i}-${section.type}${ext}`;
      const localPath = getImageFilePath(pageId, filename);
      const saved = await downloadImage(imageUrl, localPath);

      if (saved) {
        results.push({
          url: `/landing-page-generator/images/${pageId}/${filename}`,
          source: 'ai-generation',
          altText: `${section.name} AI-generated image`,
          sectionIndex: i,
        });
      } else {
        // Fallback: use the remote URL directly
        results.push({
          url: imageUrl,
          source: 'ai-generation',
          altText: `${section.name} AI-generated image`,
          sectionIndex: i,
        });
      }
    }
  }

  return results;
}

// ============================================
// MAIN RESOLVER
// ============================================

export async function resolveLandingPageImages(
  inputs: ImageResolverInputs
): Promise<ImageResolverResult> {
  const { sections, businessContext, options, pageId } = inputs;
  const maxPerSection = options?.maxImagesPerSection ?? 2;

  console.log(`[ImageResolver] Starting image resolution for page ${pageId}, ${sections.length} sections`);

  // ── Tier 1: User Uploads ──
  const userUploads = await resolveUserUploads(sections);
  console.log(`[ImageResolver] Tier 1 (User Upload): ${userUploads.length} images`);

  // Determine which sections still need images
  const sectionsWithUploads = new Set(userUploads.map(img => img.sectionIndex));
  const sectionsNeedingImages = sections
    .map((s, i) => ({ section: s, index: i }))
    .filter(({ index }) => !sectionsWithUploads.has(index));

  // ── Tier 2: Web Search ──
  let webSearchImages: ResolvedSectionImage[] = [];
  if (sectionsNeedingImages.length > 0) {
    webSearchImages = await resolveWebSearch(
      sectionsNeedingImages.map(({ section }) => section),
      businessContext,
      maxPerSection
    );
    // Remap section indices back to original
    webSearchImages = webSearchImages.map(img => ({
      ...img,
      sectionIndex: sectionsNeedingImages[img.sectionIndex]?.index ?? img.sectionIndex,
    }));
    console.log(`[ImageResolver] Tier 2 (Web Search): ${webSearchImages.length} images`);
  }

  // Determine which sections still need images after web search
  const sectionsWithWebSearch = new Set(webSearchImages.map(img => img.sectionIndex));
  const sectionsStillNeeding = sections
    .map((s, i) => ({ section: s, index: i }))
    .filter(({ index }) => !sectionsWithUploads.has(index) && !sectionsWithWebSearch.has(index));

  // ── Tier 3: AI Generation ──
  let aiImages: ResolvedSectionImage[] = [];
  if (sectionsStillNeeding.length > 0 && !options?.skipAiGeneration) {
    aiImages = await resolveAiGeneration(
      sectionsStillNeeding.map(({ section }) => section),
      businessContext,
      pageId
    );
    // Remap section indices back to original
    aiImages = aiImages.map(img => ({
      ...img,
      sectionIndex: sectionsStillNeeding[img.sectionIndex]?.index ?? img.sectionIndex,
    }));
    console.log(`[ImageResolver] Tier 3 (AI Generation): ${aiImages.length} images`);
  }

  const allResolved = [...userUploads, ...webSearchImages, ...aiImages];

  return {
    resolvedImages: allResolved,
    summary: {
      userUpload: userUploads.length,
      webSearch: webSearchImages.length,
      aiGeneration: aiImages.length,
      total: allResolved.length,
    },
  };
}
