/**
 * Social Engine — Phase 3: Content Generator
 * Takes (trend, persona) pairs and generates persona-voiced content via Grok.
 */
import {
  callGrokPersona,
  buildForecastPrompt,
  buildPiffPropPrompt,
  buildNewsReactionPrompt,
  buildRecapPrompt,
  buildDebatePrompt,
  buildCelebrityPrompt,
} from './persona-prompts';
import { insertContent, markTrendProcessed, isDuplicateContent, getRecentPersonaMemory } from './data-queries';
import type { PersonaTrendPair, SocialContentPiece, TrendSignal } from './types';

const MAX_MEMORY_POSTS = 4;
const MAX_MEMORY_SNIPPET_CHARS = 120;

// Map trend types to prompt builders
function getPromptBuilder(trendType: string): ((trend: any, persona: any) => string) | null {
  const map: Record<string, (trend: any, persona: any) => string> = {
    forecast_pick: buildForecastPrompt,
    piff_prop: buildPiffPropPrompt,
    breaking_news: buildNewsReactionPrompt,
    curated_news: buildNewsReactionPrompt,
    recap: buildRecapPrompt,
    celebrity: buildCelebrityPrompt,
    debate: buildDebatePrompt,
    hot_take: buildDebatePrompt,
    trend_reaction: buildNewsReactionPrompt,
  };
  return map[trendType] || buildNewsReactionPrompt;
}

function normalizeImagePrompt(value: string | undefined): string | undefined {
  if (typeof value !== 'string') {
    return undefined;
  }

  const cleaned = value.trim().replace(/\s+/g, ' ');
  return cleaned.length > 0 ? cleaned : undefined;
}

function summarizeMemoryText(value: string): string {
  const collapsed = value
    .replace(/\s+/g, ' ')
    .replace(/[\u0000-\u001F\u007F]/g, ' ')
    .trim();

  if (collapsed.length <= MAX_MEMORY_SNIPPET_CHARS) {
    return collapsed;
  }

  return `${collapsed.slice(0, MAX_MEMORY_SNIPPET_CHARS - 1).trimEnd()}…`;
}

export function buildFallbackImagePrompt(trend: TrendSignal): string | undefined {
  const data = trend.data || {};
  const sport = (trend.sport || trend.league || 'sports').toString().toUpperCase();

  switch (trend.trend_type) {
    case 'piff_prop': {
      const player = data.name || 'featured player';
      const team = data.team ? ` for ${data.team}` : '';
      const direction = data.direction ? `${String(data.direction).toUpperCase()} ` : '';
      const line = data.line != null ? `${data.line} ` : '';
      const stat = data.stat || 'stat line';
      const opponent = data.opponent ? ` against ${data.opponent}` : '';
      return `${sport} editorial action photo of ${player}${team}${opponent}, focus on ${direction}${line}${stat}, packed arena, game intensity, dramatic sports lighting`;
    }
    case 'forecast_pick': {
      const awayTeam = data.away_team || 'away team';
      const homeTeam = data.home_team || 'home team';
      return `${sport} game action between ${awayTeam} and ${homeTeam}, decisive momentum swing, packed venue, dramatic broadcast-style sports photo`;
    }
    case 'breaking_news':
    case 'curated_news':
    case 'trend_reaction':
      return `${sport} breaking sports news moment inspired by ${trend.title}, dramatic sideline atmosphere, editorial photography, high tension`;
    case 'recap':
      return `${sport} postgame sports scene, exhausted players and bright arena lights, editorial recap image, dramatic atmosphere`;
    case 'debate':
    case 'hot_take':
      return `${sport} heated sports debate visual, two rivals in tense game atmosphere, editorial sports photography, dramatic contrast`;
    case 'celebrity':
      return `${sport} celebrity sports moment inspired by ${trend.title}, courtside or sideline energy, editorial photography`;
    default:
      return undefined;
  }
}

export async function generateContent(pairs: PersonaTrendPair[]): Promise<number> {
  console.log(`[social-engine] Phase 3: Generating content for ${pairs.length} pairs...`);

  let created = 0;

  for (const { trend, persona } of pairs) {
    try {
      const promptBuilder = getPromptBuilder(trend.trend_type);
      if (!promptBuilder) {
        console.warn(`[social-engine] No prompt builder for type: ${trend.trend_type}`);
        await markTrendProcessed(trend.id);
        continue;
      }

      const memory = (await getRecentPersonaMemory(persona.id, MAX_MEMORY_POSTS)).slice(0, MAX_MEMORY_POSTS);
      const memoryBlock = memory.length > 0
        ? `\n\nRECENT POSTS TO AVOID ECHOING:\n${memory.map((item, index) => `${index + 1}. ${summarizeMemoryText(item)}`).join('\n')}\n\nAvoid repeating the openings, CTA tails, and sentence rhythm of those posts.`
        : '';

      const userPrompt = `${promptBuilder(trend, persona)}${memoryBlock}`;
      const result = await callGrokPersona(userPrompt, persona);

      if (!result || !result.text || result.text.length < 20) {
        console.warn(`[social-engine] Grok returned empty/short content for trend ${trend.id}`);
        await markTrendProcessed(trend.id);
        continue;
      }

      // Duplicate check
      const isDupe = await isDuplicateContent(result.text);
      if (isDupe) {
        console.log(`[social-engine] Duplicate content detected, skipping trend ${trend.id}`);
        await markTrendProcessed(trend.id);
        continue;
      }

      const piece: SocialContentPiece = {
        persona_id: persona.id,
        trend_id: trend.id,
        content_type: trend.trend_type,
        format: 'tweet',
        text: result.text,
        image_prompt: normalizeImagePrompt(result.imagePrompt) || buildFallbackImagePrompt(trend),
        league: trend.league || undefined,
        sport: trend.sport || undefined,
        game_key: trend.data.home_team && trend.data.away_team
          ? `${trend.data.away_team}@${trend.data.home_team}`
          : undefined,
        forecast_id: trend.data.forecast_id || undefined,
        source_data: trend.data,
        quality_score: trend.heat_score,
        status: 'draft',
      };

      await insertContent(piece);
      await markTrendProcessed(trend.id);
      created++;

      // Small delay between Grok calls
      await new Promise(r => setTimeout(r, 1000));
    } catch (err: any) {
      console.error(`[social-engine] Content gen failed for trend ${trend.id}:`, err.message);
      await markTrendProcessed(trend.id);
    }
  }

  console.log(`[social-engine] Phase 3 complete: ${created} content pieces created`);
  return created;
}
