/**
 * Travel pre-compute: trending, Inspiration Cards
 * Redis: travel:trending, travel:inspiration TTL 6h
 * docs/architecture: 03-cache-and-precompute-strategy.md §3
 * Inspiration: курируемые темы → LLM суммаризация (gpt-4o-mini)
 */

import type { Redis as RedisType } from 'ioredis';

const INSPIRATION_TOPICS = [
  'best hiking trails Slovenia',
  'forest hotels Sweden solitude',
  'hidden beaches Portugal',
  'weekend getaways Europe',
  'road trips USA west',
  'food markets Istanbul',
];

const STUB_INSPIRATION = [
  { title: 'Best hiking trails in Slovenia', summary: 'Explore Triglav and the Julian Alps.', image: '', url: '#' },
  { title: 'Forest hotels in Sweden', summary: 'Escape to Nordic solitude.', image: '', url: '#' },
  { title: 'Hidden beaches in Portugal', summary: 'Algarve beyond the crowds.', image: '', url: '#' },
];

async function generateInspirationCards(apiKey: string): Promise<{ title: string; summary: string; image?: string; url?: string }[]> {
  try {
    const topics = INSPIRATION_TOPICS.slice(0, 4).join(', ');
    const res = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: 'gpt-4o-mini',
        messages: [
          {
            role: 'system',
            content: 'Return ONLY valid JSON array. Each item: { "title": "short catchy title", "summary": "1-2 sentences" }. No markdown.',
          },
          {
            role: 'user',
            content: `Create 4 travel inspiration cards for these topics: ${topics}. Return JSON array of 4 objects with title and summary.`,
          },
        ],
        max_tokens: 600,
        temperature: 0.7,
      }),
      signal: AbortSignal.timeout(30000),
    });
    if (!res.ok) return STUB_INSPIRATION;
    const data = (await res.json()) as { choices?: { message?: { content?: string } }[] };
    const raw = data.choices?.[0]?.message?.content?.trim() ?? '';
    const cleaned = raw.replace(/^```json?\s*/i, '').replace(/\s*```$/i, '');
    const parsed = JSON.parse(cleaned) as { title?: string; summary?: string }[];
    if (Array.isArray(parsed) && parsed.length > 0) {
      return parsed.map((p) => ({
        title: String(p.title ?? ''),
        summary: String(p.summary ?? ''),
        image: '',
        url: '#',
      }));
    }
  } catch (err) {
    console.error('[travel] inspiration LLM:', err);
  }
  return STUB_INSPIRATION;
}

export async function runTravelPrecompute(
  redis: RedisType,
  travelSvcUrl: string
): Promise<void> {
  const base = travelSvcUrl.replace(/\/$/, '');

  try {
    const res = await fetch(`${base}/api/v1/travel/trending`, {
      signal: AbortSignal.timeout(60000),
    });
    if (res.ok) {
      const data = await res.json();
      await redis.setex('travel:trending', 6 * 60 * 60, JSON.stringify(data));
      console.log('[travel] trending: cached');
    }
  } catch (err) {
    console.error('[travel] trending:', err);
  }

  const apiKey = process.env.OPENAI_API_KEY ?? '';
  const inspiration = apiKey
    ? await generateInspirationCards(apiKey)
    : STUB_INSPIRATION;
  try {
    await redis.setex(
      'travel:inspiration',
      6 * 60 * 60,
      JSON.stringify({ items: inspiration })
    );
    console.log('[travel] inspiration: cached', apiKey ? '(LLM)' : '(stub)');
  } catch (err) {
    console.error('[travel] inspiration:', err);
  }
}
