import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { GoogleGenerativeAI, GenerativeModel } from '@google/generative-ai';
import axios from 'axios';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AIAnalysis } from '../entities/ai-analysis.entity';

@Injectable()
export class AiService {
  private readonly logger = new Logger(AiService.name);
  private readonly genAI?: GoogleGenerativeAI;
  private readonly model?: GenerativeModel;

  constructor(
    private readonly configService: ConfigService,
    @InjectRepository(AIAnalysis)
    private readonly aiAnalysisRepository: Repository<AIAnalysis>,
  ) {
    const apiKey = this.configService.get<string>('analytics.geminiApiKey');

    if (apiKey && apiKey !== 'your_gemini_api_key_here') {
      this.genAI = new GoogleGenerativeAI(apiKey);
      this.model = this.genAI.getGenerativeModel({
        model: 'gemini-flash-lite-latest', // Standard model
      });
    }
  }

  /**
   * Helper to get model based on tier
   */
  private getModelForTier(tier: string = 'standard'): GenerativeModel | undefined {
    if (!this.genAI) return undefined;

    const modelName = tier === 'pro' ? 'gemini-2.5-flash' : 'gemini-flash-lite-latest';
    return this.genAI.getGenerativeModel({ model: modelName });
  }

  /**
   * Check if a campaign has any previous AI analysis
   */
  async hasAnyAnalysis(campaignId: string): Promise<boolean> {
    const count = await this.aiAnalysisRepository.count({
      where: { campaignId },
    });
    return count > 0;
  }

  async generateCampaignInsights(metrics: any, campaignId?: string): Promise<string> {
    const today = new Date().toISOString().split('T')[0];

    // 1. Check Cache | البحث في الذاكرة المخبأة
    if (campaignId) {
      const cached = await this.aiAnalysisRepository.findOne({
        where: { campaignId, analysisDate: today, tier: 'text-only' },
      });

      if (cached) {
        this.logger.log(`Using cached text-based AI recommendations for campaign ${campaignId}`);
        return cached.analysisText;
      }
    }

    if (!this.model) {
      return 'AI Recommendations are currently unavailable (API Key missing).';
    }

    const prompt = `
أنت خبير عالمي في Meta Ads Performance Marketing.

حلل أرقام هذه الحملة بشكل عملي ومباشر:

- Impressions: ${metrics.impressions ?? 'N/A'}
- Clicks: ${metrics.clicks ?? 'N/A'}
- Spend: ${metrics.spend ?? 'N/A'}
- CTR: ${metrics.ctr ?? 'N/A'}%
- CPC: ${metrics.cpc ?? 'N/A'}
- CPM: ${metrics.cpm ?? 'N/A'}
- Conversions: ${metrics.conversions ?? 'N/A'}
- Cost Per Result: ${metrics.costPerResult ?? 'N/A'}
- Objective: ${metrics.objective ?? 'N/A'}

أعطني:
1) تشخيص سريع للحملة
2) أهم 3 مشاكل محتملة
3) 3 توصيات عملية جداً
4) هل المشكلة غالباً في:
- الكرياتيف
- الاستهداف
- العرض
- صفحة الهبوط
- أو البيانات غير كافية

اكتب باللغة العربية فقط.
كن مباشرًا وعمليًا.
`;

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

      // 2. Save to Cache | حفظ في الذاكرة المخبأة
      if (campaignId) {
        try {
          await this.aiAnalysisRepository.save({
            campaignId,
            imageUrl: 'TEXT_ONLY',
            analysisText: text,
            analysisDate: today,
            tier: 'text-only',
            metrics,
          });
        } catch (saveError) {
          this.logger.error(`Failed to cache text AI recommendations: ${saveError.message}`);
        }
      }

      return text;
    } catch (error: any) {
      this.logger.error(`Gemini Text Error: ${error.message}`, error.stack);
      return 'Failed to generate text-based AI recommendations.';
    }
  }

  async analyzeCreative(
    imageUrl: string,
    options: {
      adCopy?: string;
      metrics?: {
        impressions?: number;
        clicks?: number;
        spend?: number;
        ctr?: number;
        cpc?: number;
        cpm?: number;
        conversions?: number;
        costPerResult?: number;
        objective?: string;
        frequency?: number;
        reach?: number;
        hookRate?: number;
        thumbStopRate?: number;
        landingPageViews?: number;
      };
    } = {},
    tier: string = 'standard',
    campaignId?: string,
  ): Promise<string> {
    const { adCopy, metrics } = options;
    const today = new Date().toISOString().split('T')[0];

    // 1. Check Cache | البحث في الذاكرة المخبأة
    if (campaignId) {
      const cached = await this.aiAnalysisRepository.findOne({
        where: { campaignId, analysisDate: today, tier },
        order: { createdAt: 'DESC' }
      });

      if (cached) {
        this.logger.log(`Using cached AI analysis for campaign ${campaignId}`);
        return cached.analysisText;
      }
    }

    const model = this.getModelForTier(tier) || this.model;
    if (!model) {
      return 'AI Vision is unavailable.';
    }

    try {
      this.logger.log(`Analyzing creative at URL: ${imageUrl}`);
      this.logger.log(`adCopy: ${adCopy || 'None'}`);
      this.logger.log(`metrics provided: ${metrics ? 'Yes' : 'No'}`);
      if (metrics) {
        this.logger.log(`metrics keys: ${Object.keys(metrics).join(', ')}`);
        this.logger.log(`metrics values: ${JSON.stringify(metrics)}`);
      }

      const response = await axios.get<ArrayBuffer>(imageUrl, {
        responseType: 'arraybuffer',
        timeout: 20000,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
          'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
        },
      });

      const contentType = response.headers['content-type'] || 'image/jpeg';
      const imageData = Buffer.from(response.data).toString('base64');

      const prompt = `
أنت تعمل كخبير Meta Ads + Creative Strategist + Marketing Psychologist.

مهمتك هي تحليل هذا الإعلان اعتماداً على:
1) الصورة نفسها
2) النص الإعلاني
3) أرقام الأداء الفعلية (إن وجدت)

النص الإعلاني:
"${adCopy || 'لا يوجد نص'}"

بيانات الأداء:
- Objective: ${metrics?.objective ?? 'غير متوفر'}
- Impressions: ${metrics?.impressions ?? 'غير متوفر'}
- Reach: ${metrics?.reach ?? 'غير متوفر'}
- Clicks: ${metrics?.clicks ?? 'غير متوفر'}
- Spend: ${metrics?.spend ?? 'غير متوفر'}
- CTR: ${metrics?.ctr ?? 'غير متوفر'}%
- CPC: ${metrics?.cpc ?? 'غير متوفر'}
- CPM: ${metrics?.cpm ?? 'غير متوفر'}
- Conversions: ${metrics?.conversions ?? 'غير متوفر'}
- Cost Per Result: ${metrics?.costPerResult ?? 'غير متوفر'}
- Frequency: ${metrics?.frequency ?? 'غير متوفر'}
- Hook Rate: ${metrics?.hookRate ?? 'غير متوفر'}
- Thumb Stop Rate: ${metrics?.thumbStopRate ?? 'غير متوفر'}
- Landing Page Views: ${metrics?.landingPageViews ?? 'غير متوفر'}

حلل الإعلان بشكل مباشر وصريح جداً وفق هذا الترتيب:

1) الحكم السريع:
- هل الإعلان جيد أم ضعيف؟
- هل يصلح للتحويل أم فقط للوعي؟
- أعطِ Verdict واضح (اختر واحدة فقط):
  - ممتاز للأداء (Scale Ready)
  - جيد للأداء
  - مناسب للوعي فقط (Awareness Only)
  - ضعيف للتحويل (Underperforming)
  - البيانات غير كافية

2) Stop Scroll:
- هل الصورة توقف التمرير خلال أول 1-2 ثانية؟
- أعطِ تقييم من 10
- اربط الحكم بالشكل وبالأرقام

3) Clarity:
- هل العرض واضح خلال أقل من ثانيتين؟
- ما أول شيء يفهمه المستخدم؟
- هل يوجد تشويش؟

4) Visual Hierarchy:
- ما أول عنصر تراه العين؟
- هل العرض الأساسي واضح ومضخم أم ضائع؟

5) Offer + CTA:
- هل العرض قوي؟
- هل CTA واضح؟
- هل يوجد تطابق بين الرسالة وما يجب على المستخدم فعله؟

6) تحليل السبب الجذري (Performance Drivers):
- ما السبب الحقيقي وراء هذا الأداء؟
- اختر العنصر الأكثر تأثيراً:
  - الكرياتيف (الصورة)
  - النص الإعلاني (Copy)
  - العرض (Offer)
  - الاستهداف (Targeting)
  - صفحة الهبوط (Landing Page)
  - أو البيانات غير كافية للحكم
- اشرح لماذا أدى هذا العنصر إلى هذه النتائج (سواء كانت إيجابية أو سلبية) بوضوح.

7) أهم 3 أخطاء حرجة:
- اذكر فقط 3 أخطاء واضحة ومؤثرة

8) 3 تحسينات مباشرة:
- أعطِ 3 تحسينات قابلة للتنفيذ فوراً
- بدون تنظير

9) فكرة إعلان بديلة أقوى:
- اقترح فكرة إعلان أبسط وأوضح
- تعتمد على:
  - تضخيم العرض
  - عنصر بصري واحد
  - وضوح عالي
- يجب أن تكون سهلة التنفيذ
- لا تعتمد على فيديو معقد أو إنتاج صعب إلا إذا كان ضرورياً جداً

10) تقييم سريع (Scores):
- Stop Scroll: /10
- Clarity: /10
- عرض (Offer Visibility): /10
- CTA: /10
- احتمالية التحويل (Conversion Potential): /10

11) التأثير المتوقع على الأداء:
- وضّح كيف يؤثر هذا الإعلان على:
  - CTR
  - CPC
  - Conversion
- إذا لم توجد بيانات فعلية، اذكر أن هذا التقدير مبني على التحليل البصري والنصي فقط

12) القرار النهائي والخطوة التالية (Final Decision):
- اختر واحدة فقط:
  - إيقاف الإعلان (Stop)
  - تعديل الإعلان (Optimize)
  - الاستمرار به (Continue)
  - زيادة الميزانية / توسيع الاستهداف (Scale - إذا كان الأداء ممتازاً)
- ثم اكتب الخطوة العملية التالية بشكل واضح ومباشر.

13) مستوى الثقة:
- High / Medium / Low
- واذكر السبب، خصوصاً إذا كانت البيانات ناقصة

14) أمر توليد صورة بديلة (Nano Banana Prompt):
- إذا وجدت أن جودة الصورة أو الفيديو الحالية ضعيفة، أو غير احترافية، أو يمكن تحسينها بشكل كبير لجذب الانتباه وزيادة التحويل (CTR/Conversion)، قم بكتابة أمر (Prompt) مفصل باللغة الإنجليزية مخصص لأداة "Nano Banana".
- يجب أن يكون الـ Prompt مصمماً بدقة ليتوافق مع:
  - محتوى الإعلان الحالي (مع تحسينه بصرياً).
  - سياسات الإعلانات (Ad Policies).
  - هدف الحملة (Objective).
- ضع الـ Prompt داخل كتلة كود (Code Block) ليسهل نسخه لاحقاً.
- إذا كانت الجودة ممتازة جداً ولا تحتاج لتغيير، لا تكتب هذا القسم.

تعليمات صارمة:
- لا تعطِ تحليلاً جمالياً فقط
- ركّز على الأداء (CTR / Conversion)
- اربط دائماً بين الصورة والأرقام
- إذا كانت الأرقام غير متوفرة، اذكر أن التحليل تقديري
- إذا تعارض الشكل مع الأرقام، اعتمد على الأرقام
- يجب أن يكون Verdict متوافقاً تماماً مع باقي التحليل
- إذا كان Verdict = "ضعيف للتحويل" فلا يجوز وصف الإعلان بأنه مناسب للتحويل
- إذا كان Verdict = "مناسب للوعي فقط" فلا يجوز التوصية بالاستمرار به كإعلان Conversion
- لا تكتب JSON
- لا تستخدم كلاماً عاماً أو فلسفياً
- اكتب بالعربية فقط (باستثناء الـ Nano Banana Prompt يكتب بالإنجليزية)
- كن مباشراً جداً وعملياً
`;
      this.logger.log('prompt: ', prompt);
      const result = await model.generateContent([
        prompt,
        {
          inlineData: {
            data: imageData,
            mimeType: contentType,
          },
        },
      ]);

      const text = result.response.text();
      this.logger.log('Gemini creative analysis completed successfully.');

      // 3. Save to Cache | حفظ النتيجة في الذاكرة
      if (campaignId) {
        try {
          await this.aiAnalysisRepository.save({
            campaignId,
            imageUrl,
            adCopy,
            metrics,
            analysisText: text,
            analysisDate: today,
            tier,
          });
        } catch (saveError) {
          this.logger.error(`Failed to cache AI analysis: ${saveError.message}`);
        }
      }

      return text;
    } catch (error: any) {
      const errorMsg = error.response ? `API Error (${error.response.status}): ${error.response.data?.error?.message || error.message}` : error.message;
      this.logger.error(`AI Analysis Error: ${errorMsg}`, error.stack);
      return `فشل التحليل: ${errorMsg}. يرجى التأكد من أن رابط الصورة يعمل ومتاح للجميع.`;
    }
  }
}