/**
 * Social Trends Service
 * Engagement analysis, trend detection, and post idea generation
 *
 * @module lib/services/social-trends.service
 */

import { GoogleGenerativeAI } from '@google/generative-ai';
import { prisma } from '@/lib/db';
import { logger } from '@/lib/logger';
import type {
  SocialTrendOutput,
  EngagementPattern,
  PostIdea,
  BestTimeSlot,
} from '@/lib/types/social-media.types';

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY!);
const TREND_TTL_HOURS = 6;

function getModel() {
  return genAI.getGenerativeModel({ model: 'gemini-1.5-flash' });
}

const DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

export class SocialTrendsService {
  /**
   * Get cached trends (filter out expired)
   */
  static async getTrends(userId: string): Promise<SocialTrendOutput[]> {
    const trends = await prisma.social_trends.findMany({
      where: {
        userId,
        expiresAt: { gt: new Date() },
      },
      orderBy: { score: 'desc' },
    });

    return trends as unknown as SocialTrendOutput[];
  }

  /**
   * Refresh trends by analyzing engagement data via Gemini
   */
  static async refreshTrends(userId: string): Promise<SocialTrendOutput[]> {
    // Delete expired trends
    await prisma.social_trends.deleteMany({
      where: {
        userId,
        expiresAt: { lte: new Date() },
      },
    });

    // Get recent published posts with analytics
    const recentPosts = await prisma.social_content_queue.findMany({
      where: {
        social_account: { userId },
        status: 'PUBLISHED',
      },
      include: { analytics: true },
      orderBy: { publishedAt: 'desc' },
      take: 50,
    });

    if (recentPosts.length === 0) {
      logger.info('No published posts for trend analysis', { userId });
      return [];
    }

    // Build data summary for AI analysis
    const dataSummary = recentPosts.map((p) => ({
      platform: p.platform,
      content: p.content.substring(0, 200),
      hashtags: p.hashtags,
      publishedAt: p.publishedAt,
      likes: p.analytics?.likes || 0,
      comments: p.analytics?.comments || 0,
      shares: p.analytics?.shares || 0,
      impressions: p.analytics?.impressions || 0,
    }));

    try {
      const model = getModel();
      const result = await model.generateContent(`
Analyze these social media post performance metrics and identify trends.

Post data:
${JSON.stringify(dataSummary, null, 2)}

Return JSON array of trends:
[
  {
    "trendType": "HASHTAG" | "TOPIC" | "ENGAGEMENT_PATTERN" | "BEST_TIME",
    "title": "Short trend title",
    "description": "Detailed description",
    "score": 0.0-1.0,
    "hashtags": ["#relevant", "#tags"],
    "platform": "FACEBOOK" | "INSTAGRAM" | null
  }
]

Identify 3-8 trends including:
- Top performing hashtags
- Best content topics
- Engagement patterns (times, days)
- Platform-specific insights`);

      const text = result.response.text();
      const jsonMatch = text.match(/\[[\s\S]*\]/);
      if (!jsonMatch) {
        logger.warn('Failed to parse trends from AI', { userId });
        return this.getTrends(userId);
      }

      const aiTrends = JSON.parse(jsonMatch[0]) as Array<{
        trendType: string;
        title: string;
        description: string;
        score: number;
        hashtags: string[];
        platform: string | null;
      }>;

      const expiresAt = new Date(Date.now() + TREND_TTL_HOURS * 60 * 60 * 1000);

      // Store new trends
      const created: SocialTrendOutput[] = [];
      for (const trend of aiTrends) {
        const saved = await prisma.social_trends.create({
          data: {
            userId,
            platform: (trend.platform || null) as 'INSTAGRAM' | 'FACEBOOK' | 'TIKTOK' | 'TWITTER' | null,
            trendType: trend.trendType as 'HASHTAG' | 'TOPIC' | 'ENGAGEMENT_PATTERN' | 'BEST_TIME',
            title: trend.title,
            description: trend.description,
            score: Math.min(1, Math.max(0, trend.score)),
            hashtags: trend.hashtags || [],
            expiresAt,
          },
        });
        created.push(saved as unknown as SocialTrendOutput);
      }

      logger.info('Trends refreshed', { userId, count: created.length });
      return created;
    } catch (error) {
      logger.error('Trend refresh failed', { error, userId });
      return this.getTrends(userId);
    }
  }

  /**
   * Analyze post engagement by day of week and hour
   */
  static async getEngagementPatterns(userId: string): Promise<EngagementPattern[]> {
    const posts = await prisma.social_content_queue.findMany({
      where: {
        social_account: { userId },
        status: 'PUBLISHED',
        publishedAt: { not: null },
      },
      include: { analytics: true },
    });

    // Group by day+hour
    const buckets: Record<string, { totalEngagement: number; count: number }> = {};

    for (const post of posts) {
      if (!post.publishedAt || !post.analytics) continue;

      const day = post.publishedAt.getUTCDay();
      const hour = post.publishedAt.getUTCHours();
      const key = `${day}-${hour}`;

      if (!buckets[key]) {
        buckets[key] = { totalEngagement: 0, count: 0 };
      }

      const engagement =
        (post.analytics.likes || 0) +
        (post.analytics.comments || 0) * 2 +
        (post.analytics.shares || 0) * 3;

      buckets[key].totalEngagement += engagement;
      buckets[key].count += 1;
    }

    return Object.entries(buckets).map(([key, val]) => {
      const [day, hour] = key.split('-').map(Number);
      return {
        dayOfWeek: day,
        hour,
        engagementScore: val.count > 0 ? val.totalEngagement / val.count : 0,
      };
    });
  }

  /**
   * Generate post ideas via Gemini based on account data.
   * Returns default ideas when no published posts exist or AI is unavailable.
   */
  static async getPostIdeas(userId: string): Promise<PostIdea[]> {
    const accounts = await prisma.social_accounts.findMany({
      where: { userId, status: 'CONNECTED' },
      select: { platform: true, accountName: true },
    });

    if (accounts.length === 0) {
      return [];
    }

    const recentPosts = await prisma.social_content_queue.findMany({
      where: {
        social_account: { userId },
        status: 'PUBLISHED',
      },
      select: { content: true, platform: true, hashtags: true },
      orderBy: { publishedAt: 'desc' },
      take: 10,
    });

    // Return default ideas when no posts exist to analyze or AI key is missing
    if (recentPosts.length === 0 || !process.env.GOOGLE_API_KEY) {
      return getDefaultPostIdeas(accounts.map((a) => a.platform as 'FACEBOOK' | 'INSTAGRAM'));
    }

    try {
      const model = getModel();
      const result = await model.generateContent(`
Based on these social media accounts and recent posts, generate 5 new post ideas.

Accounts: ${JSON.stringify(accounts.map((a) => ({ platform: a.platform, name: a.accountName })))}
Recent posts: ${JSON.stringify(recentPosts.map((p) => ({ content: p.content.substring(0, 100), platform: p.platform, hashtags: p.hashtags })))}

Return JSON array:
[
  {
    "title": "Post idea title",
    "description": "What to post and why",
    "hashtags": ["#tag1", "#tag2"],
    "bestPlatform": "FACEBOOK" | "INSTAGRAM",
    "bestTime": "Monday 10:00 AM"
  }
]`);

      const text = result.response.text();
      const jsonMatch = text.match(/\[[\s\S]*\]/);
      if (!jsonMatch) return getDefaultPostIdeas(accounts.map((a) => a.platform as 'FACEBOOK' | 'INSTAGRAM'));

      return JSON.parse(jsonMatch[0]) as PostIdea[];
    } catch (error) {
      logger.warn('AI post idea generation failed, returning defaults', { userId, error });
      return getDefaultPostIdeas(accounts.map((a) => a.platform as 'FACEBOOK' | 'INSTAGRAM'));
    }
  }

  /**
   * Get best posting times from analytics data
   */
  static async getBestTimes(userId: string): Promise<BestTimeSlot[]> {
    const patterns = await this.getEngagementPatterns(userId);

    if (patterns.length === 0) {
      // Return default best times for GCC region
      return getDefaultBestTimes();
    }

    // Sort by engagement score and take top 10
    const sorted = [...patterns].sort((a, b) => b.engagementScore - a.engagementScore);
    const top = sorted.slice(0, 10);

    return top.map((p) => ({
      dayOfWeek: p.dayOfWeek,
      dayName: DAY_NAMES[p.dayOfWeek],
      hour: p.hour,
      timeLabel: `${p.hour.toString().padStart(2, '0')}:00`,
      score: p.engagementScore,
    }));
  }
}

function getDefaultBestTimes(): BestTimeSlot[] {
  // Default optimal times for GCC/MENA region
  return [
    { dayOfWeek: 0, dayName: 'Sunday', hour: 20, timeLabel: '20:00', score: 0.9 },
    { dayOfWeek: 1, dayName: 'Monday', hour: 12, timeLabel: '12:00', score: 0.85 },
    { dayOfWeek: 2, dayName: 'Tuesday', hour: 19, timeLabel: '19:00', score: 0.88 },
    { dayOfWeek: 3, dayName: 'Wednesday', hour: 20, timeLabel: '20:00', score: 0.87 },
    { dayOfWeek: 4, dayName: 'Thursday', hour: 21, timeLabel: '21:00', score: 0.92 },
    { dayOfWeek: 5, dayName: 'Friday', hour: 15, timeLabel: '15:00', score: 0.95 },
    { dayOfWeek: 6, dayName: 'Saturday', hour: 19, timeLabel: '19:00', score: 0.86 },
  ];
}

function getDefaultPostIdeas(platforms: Array<'FACEBOOK' | 'INSTAGRAM'>): PostIdea[] {
  const bestPlatform = platforms.includes('INSTAGRAM') ? 'INSTAGRAM' : 'FACEBOOK';
  return [
    {
      title: 'Behind the Scenes',
      description: 'Share a behind-the-scenes look at your daily operations to build authenticity and trust with your audience.',
      hashtags: ['#BehindTheScenes', '#DayInTheLife', '#Business'],
      bestPlatform,
      bestTime: 'Thursday 9:00 PM',
    },
    {
      title: 'Customer Spotlight',
      description: 'Feature a happy customer or a positive review to build social proof and encourage new bookings.',
      hashtags: ['#CustomerSpotlight', '#HappyCustomers', '#Testimonial'],
      bestPlatform: 'FACEBOOK',
      bestTime: 'Sunday 8:00 PM',
    },
    {
      title: 'Quick Tip / How-To',
      description: 'Share a practical tip related to your industry. Educational content drives engagement and positions you as an expert.',
      hashtags: ['#Tips', '#HowTo', '#ProTip'],
      bestPlatform: 'INSTAGRAM',
      bestTime: 'Monday 12:00 PM',
    },
    {
      title: 'Weekend Special Offer',
      description: 'Promote a limited-time offer or weekend deal to drive bookings during peak browsing hours.',
      hashtags: ['#WeekendDeal', '#SpecialOffer', '#BookNow'],
      bestPlatform,
      bestTime: 'Friday 3:00 PM',
    },
    {
      title: 'Team Introduction',
      description: 'Introduce a team member to humanize your brand and create personal connections with your audience.',
      hashtags: ['#MeetTheTeam', '#OurTeam', '#TeamWork'],
      bestPlatform: 'INSTAGRAM',
      bestTime: 'Wednesday 7:00 PM',
    },
  ];
}

export const socialTrends = new SocialTrendsService();
