/**
 * Social AI Assistant Service
 * AI-powered content generation and reply drafting using Google Gemini
 *
 * @module lib/services/social-ai-assistant.service
 */

import { GoogleGenerativeAI } from '@google/generative-ai';
import { logger } from '@/lib/logger';
import {
  socialAccountsAdapter,
  socialMessagesAdapter,
  aiContentGenerationsAdapter,
} from '@/lib/adapters/social';
import type {
  SocialPlatform,
  AIGenerateInput,
  AIGenerateOutput,
} from '@/lib/types/social-media.types';
import { PLATFORM_LIMITS } from '@/lib/types/social-media.types';

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

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

export class SocialAIAssistantService {
  /**
   * Generate social media content (captions, hashtags, etc.)
   */
  static async generateContent(
    userId: string,
    input: AIGenerateInput
  ): Promise<AIGenerateOutput> {
    if (!process.env.GOOGLE_API_KEY) {
      throw new Error('AI_NOT_CONFIGURED');
    }

    const model = getModel();
    const platform = input.platform;
    const platformInfo = platform ? PLATFORM_LIMITS[platform] : null;

    let prompt = '';

    switch (input.type) {
      case 'caption':
        prompt = buildCaptionPrompt(input, platformInfo);
        break;
      case 'hashtags':
        prompt = buildHashtagPrompt(input, platformInfo);
        break;
      case 'reply':
        prompt = buildReplyPrompt(input);
        break;
      case 'rephrase':
        prompt = buildRephrasePrompt(input, platformInfo);
        break;
      default:
        throw new Error(`Unsupported generation type: ${input.type}`);
    }

    try {
      const result = await model.generateContent(prompt);
      const text = result.response.text();

      const output = parseAIResponse(text, input.type, platform);

      // Save to generation history
      await aiContentGenerationsAdapter.create({
        data: {
          contentType: 'SOCIAL_POST',
          inputPrompt: prompt.substring(0, 5000),
          outputContent: text.substring(0, 10000),
          model: 'gemini-1.5-flash',
          createdBy: userId,
        },
      });

      logger.info('AI content generated', {
        userId,
        type: input.type,
        platform: input.platform,
      });

      return output;
    } catch (error) {
      logger.error('AI content generation failed', { error, userId, type: input.type });
      throw new Error('AI_GENERATION_FAILED');
    }
  }

  /**
   * Rephrase existing content with a specific tone
   */
  static async rephraseContent(
    userId: string,
    content: string,
    tone: string,
    language: string,
    platform?: SocialPlatform
  ): Promise<AIGenerateOutput> {
    return this.generateContent(userId, {
      type: 'rephrase',
      originalContent: content,
      tone: tone as AIGenerateInput['tone'],
      language: language as 'ar' | 'en',
      platform,
    });
  }

  /**
   * Draft a reply based on conversation context
   */
  static async draftReply(
    userId: string,
    conversationId: string,
    tone: string,
    language: string
  ): Promise<AIGenerateOutput> {
    // Fetch conversation messages for context
    const accounts = await socialAccountsAdapter.findMany({
      where: { userId },
      select: { id: true },
    });

    const accountIds = (accounts as Array<{ id: string }>).map((a) => a.id);

    const messages = await socialMessagesAdapter.findMany({
      where: {
        conversationId,
        socialAccountId: { in: accountIds },
      },
      orderBy: { createdAt: 'asc' },
      take: 20, // Last 20 messages for context
    });

    if (messages.length === 0) {
      throw new Error('No messages found in conversation');
    }

    const contextStr = messages
      .map(
        (m) =>
          `[${m.direction === 'INBOUND' ? 'Customer' : 'You'}]: ${m.content}`
      )
      .join('\n');

    return this.generateContent(userId, {
      type: 'reply',
      context: contextStr,
      tone: tone as AIGenerateInput['tone'],
      language: language as 'ar' | 'en',
    });
  }

  /**
   * Get AI generation history for a user
   */
  static async getHistory(
    userId: string,
    page: number = 1,
    limit: number = 20
  ): Promise<{
    items: Array<{
      id: string;
      contentType: string;
      inputPrompt: string;
      outputContent: string;
      model: string;
      createdAt: Date;
    }>;
    total: number;
    page: number;
    limit: number;
  }> {
    const skip = (page - 1) * limit;

    const [items, total] = await Promise.all([
      aiContentGenerationsAdapter.findMany({
        where: { createdBy: userId },
        orderBy: { createdAt: 'desc' },
        skip,
        take: limit,
      }),
      aiContentGenerationsAdapter.count({
        where: { createdBy: userId },
      }),
    ]);

    return { items, total, page, limit };
  }
}

// === Prompt Builders ===

function buildCaptionPrompt(
  input: AIGenerateInput,
  platformInfo: { name: string; maxChars: number } | null
): string {
  const lang = input.language === 'ar' ? 'Arabic' : 'English';
  const platformNote = platformInfo
    ? `for ${platformInfo.name} (max ${platformInfo.maxChars} chars)`
    : 'for social media';
  const toneNote = input.tone ? `Tone: ${input.tone}.` : '';

  return `Generate a social media caption ${platformNote} in ${lang}.
Topic: ${input.topic || 'general engagement post'}
${toneNote}

Requirements:
- Write engaging, concise content
- Include a call-to-action
- Do NOT include hashtags in the caption (they'll be added separately)
- Return JSON format: { "content": "...", "alternatives": ["...", "..."] }
- Provide 2 alternative versions`;
}

function buildHashtagPrompt(
  input: AIGenerateInput,
  platformInfo: { name: string; maxHashtags: number } | null
): string {
  const maxTags = platformInfo?.maxHashtags || 15;
  const lang = input.language === 'ar' ? 'Arabic' : 'English';

  return `Generate relevant hashtags in ${lang} for a social media post.
Topic: ${input.topic || input.context || 'general'}
Maximum: ${maxTags} hashtags

Requirements:
- Mix of popular and niche hashtags
- All hashtags must start with #
- Return JSON format: { "hashtags": ["#tag1", "#tag2", ...] }`;
}

function buildReplyPrompt(input: AIGenerateInput): string {
  const lang = input.language === 'ar' ? 'Arabic' : 'English';
  const toneNote = input.tone ? `Tone: ${input.tone}.` : '';

  return `Draft a reply to a social media conversation in ${lang}.
${toneNote}

Conversation context:
${input.context || 'No context provided'}

Requirements:
- Be helpful and professional
- Address the customer's concern directly
- Keep it concise (under 500 characters)
- Return JSON format: { "content": "...", "alternatives": ["...", "..."] }
- Provide 2 alternative replies`;
}

function buildRephrasePrompt(
  input: AIGenerateInput,
  platformInfo: { name: string; maxChars: number } | null
): string {
  const lang = input.language === 'ar' ? 'Arabic' : 'English';
  const toneNote = input.tone ? `Target tone: ${input.tone}.` : '';
  const platformNote = platformInfo
    ? `Platform: ${platformInfo.name} (max ${platformInfo.maxChars} chars).`
    : '';

  return `Rephrase the following social media content in ${lang}.
${toneNote}
${platformNote}

Original content:
${input.originalContent || ''}

Requirements:
- Maintain the original meaning
- Apply the requested tone
- Return JSON format: { "content": "...", "alternatives": ["...", "..."] }
- Provide 2 alternative versions`;
}

// === Response Parser ===

function parseAIResponse(
  text: string,
  type: string,
  platform?: SocialPlatform
): AIGenerateOutput {
  try {
    // Try to extract JSON from the response
    const jsonMatch = text.match(/\{[\s\S]*\}/);
    if (jsonMatch) {
      const parsed = JSON.parse(jsonMatch[0]);
      return {
        content: parsed.content || text,
        hashtags: parsed.hashtags || [],
        alternatives: parsed.alternatives || [],
        platform,
      };
    }
  } catch {
    // Fall back to raw text
  }

  return {
    content: text.trim(),
    hashtags: type === 'hashtags' ? extractHashtags(text) : [],
    alternatives: [],
    platform,
  };
}

function extractHashtags(text: string): string[] {
  const matches = text.match(/#[\w\u0600-\u06FF]+/g);
  return matches || [];
}

export const socialAIAssistant = new SocialAIAssistantService();
