import { EventEmitter } from 'events';
import { invokeLLM } from './_core/llm.ts';
import { generateImage } from './_core/imageGeneration.ts';
import { db } from './db.ts';
import { aiSocialContent } from '../drizzle/schema.ts';
import { v4 as uuidv4 } from 'uuid';

export interface SocialPost {
  id: string;
  platform: 'twitter' | 'instagram' | 'tiktok' | 'facebook';
  content: string;
  imageUrl?: string;
  videoUrl?: string;
  hashtags: string[];
  callToAction?: string;
  scheduledTime?: Date;
  status: 'draft' | 'scheduled' | 'published' | 'archived';
  engagement?: {
    likes: number;
    comments: number;
    shares: number;
    views: number;
  };
  createdAt: Date;
  publishedAt?: Date;
}

export interface CampaignConfig {
  name: string;
  theme: string;
  targetAudience: 'casual' | 'hardcore' | 'all';
  platforms: ('twitter' | 'instagram' | 'tiktok' | 'facebook')[];
  postCount: number;
  frequency: 'daily' | 'weekly' | 'multiple_daily';
  includeImages: boolean;
  includeVideos: boolean;
  tone: 'professional' | 'casual' | 'humorous' | 'inspirational';
}

/**
 * AI Social Media Service
 * Generates and schedules social media content for marketing
 */
export class AISocialMediaService extends EventEmitter {
  private platformCharLimits = {
    twitter: 280,
    instagram: 2200,
    tiktok: 2200,
    facebook: 63206,
  };

  private platformTones = {
    twitter: 'witty and concise',
    instagram: 'engaging and visual',
    tiktok: 'trendy and entertaining',
    facebook: 'community-focused and conversational',
  };

  constructor() {
    super();
    console.log('[AISocialMedia] Service initialized');
  }

  /**
   * Generate social media posts for a campaign
   */
  async generateCampaignPosts(config: CampaignConfig): Promise<SocialPost[]> {
    const posts: SocialPost[] = [];

    console.log(`[AISocialMedia] Generating ${config.postCount} posts for campaign: ${config.name}`);

    for (let i = 0; i < config.postCount; i++) {
      for (const platform of config.platforms) {
        const post = await this.generatePost(config, platform, i);
        posts.push(post);
      }
    }

    this.emit('campaignGenerated', { campaign: config.name, postCount: posts.length });
    return posts;
  }

  /**
   * Generate a single social media post
   */
  async generatePost(config: CampaignConfig, platform: 'twitter' | 'instagram' | 'tiktok' | 'facebook', index: number): Promise<SocialPost> {
    const charLimit = this.platformCharLimits[platform];
    const tone = this.platformTones[platform];

    const postPrompt = `Generate a ${tone} social media post for ${platform} about CoinKrazy casino.

Campaign: ${config.name}
Theme: ${config.theme}
Target Audience: ${config.targetAudience}
Tone: ${config.tone}
Character Limit: ${charLimit}
Post Index: ${index + 1}

Requirements:
- Keep it under ${charLimit} characters
- Include relevant hashtags (5-10)
- Add a call-to-action (play now, sign up, join, etc.)
- Make it engaging and platform-appropriate
- Avoid repetition from previous posts
- Include emojis if appropriate for the platform

Return as JSON with keys: content, hashtags, callToAction`;

    const response = await invokeLLM({
      messages: [
        {
          role: 'system',
          content: `You are a social media marketing expert specializing in gaming and casino platforms. 
Generate engaging, compliant posts that drive user engagement. Respond with valid JSON only.`,
        },
        {
          role: 'user',
          content: postPrompt,
        },
      ],
      response_format: {
        type: 'json_schema',
        json_schema: {
          name: 'social_post',
          strict: true,
          schema: {
            type: 'object',
            properties: {
              content: { type: 'string' },
              hashtags: { type: 'array', items: { type: 'string' } },
              callToAction: { type: 'string' },
            },
            required: ['content', 'hashtags'],
            additionalProperties: false,
          },
        },
      },
    });

    const postData = JSON.parse(response.choices[0].message.content);

    // Generate image if configured
    let imageUrl: string | undefined;
    if (config.includeImages) {
      imageUrl = await this.generatePostImage(config.theme, postData.content);
    }

    const post: SocialPost = {
      id: uuidv4(),
      platform,
      content: postData.content,
      imageUrl,
      hashtags: postData.hashtags,
      callToAction: postData.callToAction,
      status: 'draft',
      createdAt: new Date(),
    };

    // Save to database
    await db.insert(aiSocialContent).values({
      id: post.id,
      platform,
      content: post.content,
      imageUrl: post.imageUrl,
      hashtags: post.hashtags,
      callToAction: post.callToAction,
      status: 'draft',
      metadata: {
        campaign: config.name,
        theme: config.theme,
        tone: config.tone,
      },
    });

    this.emit('postGenerated', post);
    console.log(`[AISocialMedia] Post generated for ${platform}: ${post.id}`);

    return post;
  }

  /**
   * Generate image for social post
   */
  private async generatePostImage(theme: string, content: string): Promise<string> {
    try {
      const imagePrompt = `Create a vibrant social media post image for CoinKrazy casino.
Theme: ${theme}
Post excerpt: ${content.substring(0, 100)}...

Requirements:
- Professional gaming aesthetic
- Include CoinKrazy branding
- Eye-catching colors and design
- 16:9 aspect ratio for Twitter/Facebook
- 1:1 aspect ratio for Instagram
- Include relevant gaming elements`;

      const { url } = await generateImage({
        prompt: imagePrompt,
      });

      return url;
    } catch (error) {
      console.error('[AISocialMedia] Image generation failed:', error);
      return '';
    }
  }

  /**
   * Schedule posts for publishing
   */
  async schedulePostsForPublishing(posts: SocialPost[], startTime: Date, frequency: 'daily' | 'weekly' | 'multiple_daily'): Promise<SocialPost[]> {
    const scheduledPosts: SocialPost[] = [];
    let currentTime = new Date(startTime);

    const intervalMs = this.getIntervalMs(frequency);

    for (const post of posts) {
      post.scheduledTime = new Date(currentTime);
      post.status = 'scheduled';

      await db
        .update(aiSocialContent)
        .set({
          status: 'scheduled',
          scheduledTime: post.scheduledTime,
        })
        .where((t) => t.id === post.id);

      scheduledPosts.push(post);
      currentTime = new Date(currentTime.getTime() + intervalMs);
    }

    this.emit('postsScheduled', { count: scheduledPosts.length, startTime });
    console.log(`[AISocialMedia] ${scheduledPosts.length} posts scheduled starting at ${startTime}`);

    return scheduledPosts;
  }

  /**
   * Get interval in milliseconds based on frequency
   */
  private getIntervalMs(frequency: 'daily' | 'weekly' | 'multiple_daily'): number {
    switch (frequency) {
      case 'daily':
        return 24 * 60 * 60 * 1000; // 1 day
      case 'weekly':
        return 7 * 24 * 60 * 60 * 1000; // 1 week
      case 'multiple_daily':
        return 6 * 60 * 60 * 1000; // 6 hours
      default:
        return 24 * 60 * 60 * 1000;
    }
  }

  /**
   * Publish a post to social platform
   */
  async publishPost(post: SocialPost): Promise<{ success: boolean; platformPostId?: string; error?: string }> {
    try {
      console.log(`[AISocialMedia] Publishing to ${post.platform}: ${post.id}`);

      // In a real implementation, this would call platform-specific APIs
      // For now, we'll simulate successful publishing
      const platformPostId = `${post.platform}-${Date.now()}`;

      await db
        .update(aiSocialContent)
        .set({
          status: 'published',
          publishedAt: new Date(),
          metadata: {
            platformPostId,
          },
        })
        .where((t) => t.id === post.id);

      post.status = 'published';
      post.publishedAt = new Date();

      this.emit('postPublished', post);
      console.log(`[AISocialMedia] Post published successfully: ${post.id}`);

      return { success: true, platformPostId };
    } catch (error) {
      console.error('[AISocialMedia] Publishing failed:', error);
      return { success: false, error: String(error) };
    }
  }

  /**
   * Get scheduled posts
   */
  async getScheduledPosts(): Promise<SocialPost[]> {
    const posts = await db.query.aiSocialContent.findMany({
      where: (t) => t.status === 'scheduled',
    });

    return posts.map((p) => ({
      id: p.id,
      platform: p.platform as any,
      content: p.content,
      imageUrl: p.imageUrl,
      hashtags: p.hashtags,
      callToAction: p.callToAction,
      scheduledTime: p.scheduledTime,
      status: p.status as any,
      createdAt: p.createdAt,
      publishedAt: p.publishedAt,
    }));
  }

  /**
   * Get published posts
   */
  async getPublishedPosts(limit: number = 50): Promise<SocialPost[]> {
    const posts = await db.query.aiSocialContent.findMany({
      where: (t) => t.status === 'published',
      limit,
    });

    return posts.map((p) => ({
      id: p.id,
      platform: p.platform as any,
      content: p.content,
      imageUrl: p.imageUrl,
      hashtags: p.hashtags,
      callToAction: p.callToAction,
      status: p.status as any,
      createdAt: p.createdAt,
      publishedAt: p.publishedAt,
    }));
  }

  /**
   * Get draft posts
   */
  async getDraftPosts(): Promise<SocialPost[]> {
    const posts = await db.query.aiSocialContent.findMany({
      where: (t) => t.status === 'draft',
    });

    return posts.map((p) => ({
      id: p.id,
      platform: p.platform as any,
      content: p.content,
      imageUrl: p.imageUrl,
      hashtags: p.hashtags,
      callToAction: p.callToAction,
      status: p.status as any,
      createdAt: p.createdAt,
      publishedAt: p.publishedAt,
    }));
  }

  /**
   * Update post status
   */
  async updatePostStatus(postId: string, status: 'draft' | 'scheduled' | 'published' | 'archived'): Promise<void> {
    await db
      .update(aiSocialContent)
      .set({ status })
      .where((t) => t.id === postId);

    console.log(`[AISocialMedia] Post ${postId} status updated to ${status}`);
  }

  /**
   * Delete a post
   */
  async deletePost(postId: string): Promise<void> {
    await db.delete(aiSocialContent).where((t) => t.id === postId);
    console.log(`[AISocialMedia] Post ${postId} deleted`);
  }
}

export default AISocialMediaService;
