import { Injectable, OnModuleInit } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Campaign } from '../campaigns/campaign.entity';
import { CreatorProfile } from '../creators/creator-profile.entity';
import { User } from '../users/user.entity';
import { Application } from '../applications/application.entity';
import axios from 'axios';

const PY = 'http://localhost:8000';

@Injectable()
export class AiService implements OnModuleInit {
  constructor(
    @InjectRepository(Campaign)
    private campaignsRepo: Repository<Campaign>,
    @InjectRepository(CreatorProfile)
    private creatorsRepo: Repository<CreatorProfile>,
    @InjectRepository(User)
    private usersRepo: Repository<User>,
    @InjectRepository(Application)
    private applicationsRepo: Repository<Application>,
  ) {}

  async onModuleInit() {
    console.log('[AI] Connecting to Python ML Engine...');
    try {
      const res = await axios.get(`${PY}/`);
      console.log('[AI] Connected:', res.data.status, `(${res.data.models_loaded} models, LLM: ${res.data.llm_available})`);
    } catch (e) {
      console.warn('[AI] Python service not reachable at', PY);
    }
  }

  /**
   * Helper: Build a standardized creator object from a CreatorProfile entity.
   * This is the single source of truth for creator data across ALL AI features.
   */
  private mapCreator(c: CreatorProfile) {
    // Parse follower_range to a number (e.g. "20,000,000" -> 20000000, "5000" -> 5000)
    let followers = 0;
    if (c.follower_range) {
      const cleaned = c.follower_range.replace(/[^0-9]/g, '');
      followers = parseInt(cleaned) || 0;
    }

    // Parse social links if available
    let socialLinks: any = {};
    if (c.social_links) {
      try { socialLinks = JSON.parse(c.social_links); } catch { socialLinks = {}; }
    }

    return {
      id: c.user?.id || c.id,
      name: c.full_name || c.username || 'Creator',
      username: c.username || '',
      email: c.user?.email || '',
      category: c.category || 'general',
      platform: socialLinks.primaryPlatform || 'Instagram',
      followers,
      engagement_rate: followers > 100000 ? 0.03 : followers > 10000 ? 0.05 : 0.08,
      content_quality: c.bio && c.bio.length > 50 ? 8.0 : c.bio && c.bio.length > 10 ? 6.5 : 4.0,
      brand_safety: 0.9,
      bio: c.bio || '',
      location: c.location || '',
      avatar: c.avatar_url || '',
      socialLinks,
    };
  }

  // ========== 1. SMART MATCH ==========
  async getSmartMatches(campaignId: string): Promise<any[]> {
    const campaign = await this.campaignsRepo.findOne({
      where: { id: campaignId },
      relations: ['brand', 'brand.brandProfile'],
    });
    if (!campaign) return [];

    // Fetch ALL creators with their user relation from the real database
    const allCreators = await this.creatorsRepo.find({
      relations: ['user']
    });

    if (allCreators.length === 0) return [];

    const realCreators = allCreators.map(c => this.mapCreator(c));

    try {
      // Determine campaign category: use brand industry, or extract from campaign content
      let campaignCategory = campaign.brand?.brandProfile?.industry || '';
      if (!campaignCategory || campaignCategory === 'general') {
        const combined = `${campaign.title} ${campaign.description}`.toLowerCase();
        const categories = ['fashion', 'tech', 'food', 'fitness', 'beauty', 'travel', 'gaming', 'lifestyle', 'music', 'education', 'sport'];
        campaignCategory = categories.find(c => combined.includes(c)) || 'general';
      }

      const res = await axios.post(`${PY}/match`, {
        campaign_title: campaign.title || '',
        campaign_desc: campaign.description || '',
        category: campaignCategory,
        platform: campaign.platform || 'Instagram',
        creators: realCreators
      });

      return (res.data.matches || []).slice(0, 10).map((m: any) => {
        // Find the original creator to ensure we use the real avatar
        const original = realCreators.find(c => c.id === m.creator_id);
        return {
          id: m.creator_id,
          name: m.name || original?.name || 'Creator',
          username: original?.username || '',
          email: original?.email || '',
          category: m.category,
          platform: m.platform || original?.platform || 'Instagram',
          followers: Number(m.followers).toLocaleString(),
          matchScore: m.match_score,
          avatar: original?.avatar || m.avatar || '',
          matchReasons: m.match_reasons || [],
          bio: m.bio || original?.bio || '',
          location: m.location || original?.location || '',
          engagementRate: m.engagement_rate || original?.engagement_rate,
          contentQuality: m.content_quality || original?.content_quality,
          brandSafety: m.brand_safety,
        };
      });
    } catch (err) {
      console.error('[AI] Smart Match error:', err.message);
      return [];
    }
  }

  // ========== 2. PREDICT PERFORMANCE ==========
  async predictPerformance(campaignId: string): Promise<any> {
    const campaign = await this.campaignsRepo.findOne({
      where: { id: campaignId },
      relations: ['brand', 'brand.brandProfile'],
    });
    if (!campaign) return { error: 'Campaign not found' };

    // Count how many applicants this campaign has for better prediction
    const appCount = await this.applicationsRepo.count({
      where: { campaign: { id: campaignId } }
    });

    try {
      const res = await axios.post(`${PY}/predict`, {
        campaignTitle: campaign.title || '',
        campaignDescription: campaign.description || '',
        category: campaign.brand?.brandProfile?.industry || 'general',
        budget: campaign.budget || 2000,
        platform: campaign.platform || 'Instagram',
        targetAudience: campaign.target_audience || 'All',
        applicantCount: appCount,
      });

      return {
        campaignTitle: campaign.title,
        predictedReach: res.data.predictedReach || res.data.reach,
        predictedImpressions: res.data.predictedImpressions || res.data.reach * 3,
        predictedEngagementRate: res.data.predictedEngagementRate || '5.0%',
        estimatedROI: res.data.estimatedROI || '2.0x',
        confidence: res.data.confidence || 75,
        recommendations: res.data.recommendations || [],
      };
    } catch (err) {
      console.error('[AI] Prediction error:', err.message);
      return {
        campaignTitle: campaign?.title || '',
        predictedReach: 0,
        predictedImpressions: 0,
        predictedEngagementRate: '0%',
        estimatedROI: '0x',
        confidence: 0,
        recommendations: ['AI Engine is currently offline. Please try again later.'],
      };
    }
  }

  // ========== 3. GENERATE CAPTIONS ==========
  async generateCaptions(body: any): Promise<any> {
    try {
      const res = await axios.post(`${PY}/generate/caption`, {
        brandName: body.brandName || '',
        campaignTitle: body.campaignTitle || '',
        platform: body.platform || 'Instagram',
        category: body.category || 'general',
        tone: body.tone || 'professional',
        count: body.count || 3,
      });

      return {
        captions: res.data.captions || [],
        category: res.data.category || 'General',
        confidence: res.data.confidence || 80,
        hashtags: res.data.hashtags || [],
        source: res.data.source || 'template',
      };
    } catch (err) {
      console.error('[AI] Caption error:', err.message);
      return {
        captions: ['AI Engine is currently loading. Please try again in a moment.'],
        category: body.category || 'General',
        confidence: 0,
        hashtags: [],
        source: 'fallback',
      };
    }
  }

  // ========== 4. GENERATE PITCH ==========
  async generatePitch(body: any): Promise<any> {
    try {
      const res = await axios.post(`${PY}/generate/pitch`, {
        campaignTitle: body.campaignName || body.campaignTitle || '',
        campaignDescription: body.campaignDescription || '',
        creatorName: body.creatorName || '',
        creatorCategory: body.creatorCategory || '',
        creatorFollowers: body.creatorFollowers || '',
        targetAudience: body.targetAudience || '',
        keyPoints: body.keyPoints || '',
        tone: body.tone || 'Professional',
      });

      return {
        pitches: res.data.pitches || [],
        tips: res.data.tips || [],
        source: res.data.source || 'template',
      };
    } catch (err) {
      console.error('[AI] Pitch error:', err.message);
      return {
        pitches: ['AI Engine is currently loading. Please try again shortly.'],
        tips: ['Be authentic in your pitch', 'Show relevant past work'],
        source: 'fallback',
      };
    }
  }

  // ========== 5. RANK APPLICANTS ==========
  async rankApplicants(campaignId: string): Promise<any> {
    const campaign = await this.campaignsRepo.findOne({
      where: { id: campaignId },
      relations: ['brand', 'brand.brandProfile'],
    });
    if (!campaign) return { ranked_applicants: [] };

    // Get all applications for this campaign with FULL creator profile data
    const applications = await this.applicationsRepo.find({
      where: { campaign: { id: campaignId } },
      relations: ['creator', 'creator.creatorProfile'],
    });

    if (applications.length === 0) return { ranked_applicants: [] };

    const applicants = applications.map(app => {
      const profile = app.creator?.creatorProfile;
      const mapped = profile ? this.mapCreator(profile) : null;

      return {
        id: app.id,
        creator_user_id: app.creator?.id || '',
        name: mapped?.name || profile?.full_name || profile?.username || app.creator?.email || 'Unknown',
        avatar: mapped?.avatar || '',
        email: app.creator?.email || '',
        followers: mapped?.followers || 5000,
        engagement_rate: mapped?.engagement_rate || 0.05,
        content_quality: mapped?.content_quality || 5.0,
        success_rate: 0.7,
        response_time: 12,
        brand_safety: 0.85,
        category: mapped?.category || 'general',
        platform: mapped?.platform || 'Instagram',
        bio: mapped?.bio || '',
        pitch: app.pitch || '',
        status: app.status || 'pending',
      };
    });

    try {
      const res = await axios.post(`${PY}/rank-applicants`, {
        applicants,
        campaign_category: campaign.brand?.brandProfile?.industry || 'general',
        campaign_platform: campaign.platform || 'Instagram',
      });

      // Merge avatar and contact info back into ranked results
      const ranked = (res.data.ranked_applicants || []).map((ranked: any) => {
        const original = applicants.find(a => a.id === ranked.applicant_id);
        return {
          ...ranked,
          name: original?.name || ranked.name,
          avatar: original?.avatar || '',
          email: original?.email || '',
          creator_user_id: original?.creator_user_id || '',
          bio: original?.bio || '',
          pitch: original?.pitch || '',
        };
      });

      return { ranked_applicants: ranked };
    } catch (err) {
      console.error('[AI] Rank error:', err.message);
      return { ranked_applicants: [] };
    }
  }

  // ========== 6. GENERATE CONTRACT ==========
  async generateContract(body: any): Promise<any> {
    try {
      const res = await axios.post(`${PY}/generate/contract`, {
        brandName: body.brandName || '',
        creatorName: body.creatorName || '',
        campaignTitle: body.campaignTitle || '',
        deliverables: body.deliverables || '',
        budget: body.budget || 0,
        deadline: body.deadline || '',
        platform: body.platform || 'Instagram',
        usageRights: body.usageRights || '30 days',
      });
      return res.data;
    } catch (err) {
      console.error('[AI] Contract error:', err.message);
      return { contract: 'AI Engine is currently offline. Please try again later.', source: 'error' };
    }
  }

  // ========== 7. RECOMMEND CAMPAIGNS ==========
  async recommendCampaigns(body: any): Promise<any> {
    try {
      // Fetch REAL active campaigns from the database
      const allCampaigns = await this.campaignsRepo.find({
        where: { status: 'active' },
        relations: ['brand', 'brand.brandProfile']
      });

      const realCampaigns = allCampaigns.map(c => ({
        id: c.id,
        title: c.title || '',
        description: c.description || '',
        category: c.brand?.brandProfile?.industry || 'general',
        budget: Number(c.budget) || 0,
        platform: c.platform || 'Instagram',
        brandName: c.brand?.email || 'Brand',
      }));

      const res = await axios.post(`${PY}/recommend`, {
        creator_category: body.creatorCategory || 'lifestyle',
        creator_interests: body.creatorInterests || [],
        creator_followers: body.creatorFollowers || 10000,
        creator_platform: body.creatorPlatform || 'Instagram',
        campaigns: realCampaigns
      });
      return res.data;
    } catch (err) {
      console.error('[AI] Recommend error:', err.message);
      return { recommendations: [] };
    }
  }

  // ========== 8. SENTIMENT (Simple) ==========
  async analyzeSentiment(text: string): Promise<any> {
    const positive = ['great', 'amazing', 'love', 'excellent', 'perfect', 'awesome', 'fantastic'];
    const negative = ['bad', 'terrible', 'hate', 'awful', 'horrible', 'worst', 'disappointed'];
    const lower = text.toLowerCase();
    const posCount = positive.filter(w => lower.includes(w)).length;
    const negCount = negative.filter(w => lower.includes(w)).length;

    if (posCount > negCount) return { score: 1, label: 'positive', display: 'Positive' };
    if (negCount > posCount) return { score: -1, label: 'negative', display: 'Negative' };
    return { score: 0, label: 'neutral', display: 'Neutral' };
  }

  // ========== 9. DEEP RESEARCH (DL) ==========
  async deepResearch(body: any): Promise<any> {
    try {
      const res = await axios.post(`${PY}/deep-research`, {
        image_url: body.image_url || '',
        username: body.username || '',
        niche: body.niche || '',
        follower_count: body.follower_count || '',
        platform: body.platform || '',
        known_for: body.known_for || '',
      });
      return res.data;
    } catch (err) {
      console.error('[AI] Deep Research error:', err.message);
      return { 
        success: false, 
        error: 'Engine offline',
        analysis: {}
      };
    }
  }

  // ========== 10. TEAM PERFORMANCE SUMMARY ==========
  async generateTeamSummary(tasks: any[]): Promise<string> {
    try {
      // Build summary data for the LLM
      const byUser: Record<string, { name: string; total: number; completed: number; pending: number; links: string[] }> = {};
      for (const t of tasks) {
        const name = t.assignedTo?.email?.split('@')[0] || 'Unknown';
        const uid = t.assignedTo?.id || 'unknown';
        if (!byUser[uid]) byUser[uid] = { name, total: 0, completed: 0, pending: 0, links: [] };
        byUser[uid].total++;
        if (t.status === 'completed' || t.status === 'reviewed') byUser[uid].completed++;
        else byUser[uid].pending++;
        if (t.post_link) byUser[uid].links.push(t.post_link);
      }

      const prompt = `As a professional campaign manager AI, analyze the following team performance data and provide a concise executive summary with actionable insights:\n\n${
        Object.values(byUser).map(u => `• ${u.name}: ${u.completed}/${u.total} tasks completed, ${u.pending} pending, ${u.links.length} posts submitted`).join('\n')
      }\n\nProvide: 1) Overall team health rating (A-F), 2) Top performer, 3) Areas needing attention, 4) Recommendations. Keep it under 200 words.`;

      const res = await axios.post(`${PY}/generate`, { prompt, max_tokens: 300 });
      return res.data?.text || res.data?.response || 'AI summary unavailable.';
    } catch (err) {
      console.error('[AI] Team Summary error:', err.message);
      return 'Unable to generate team summary — AI engine offline.';
    }
  }

  // ========== 11. ANALYZE POST LINK ==========
  async analyzePostLink(url: string, taskTitle: string): Promise<string> {
    const cleanUrl = url ? url.trim().replace(/[\n\r]/g, '') : '';
    if (!cleanUrl || !cleanUrl.startsWith('http')) {
      return '⚠️ Analysis skipped: Invalid or missing post URL.';
    }
    
    console.log(`[AI] Starting analysis for: ${cleanUrl.substring(0, 50)}...`);
    
    try {
      // Use the real URL scraping endpoint for actual metrics
      const res = await axios.post(`${PY}/analyze-url`, {
        url: cleanUrl,
        campaign_keywords: taskTitle.split(/\s+/).filter(w => w.length > 3),
      }, { timeout: 120000 });

      const d = res.data;
      if (!d.success) {
        return `⚠️ Could not scrape post: ${d.error || 'Unknown error'}`;
      }

      const m = d.metrics || {};
      const parts = [
        `🤖 AI Bot Report — Platform: ${d.platform || 'Unknown'}`,
        `📊 Metrics: ${m.views ?? '—'} views · ${m.likes ?? '—'} likes · ${m.comments ?? '—'} comments · Engagement: ${m.engagement_rate || '—'}`,
        `🛡️ Brand Safety: ${d.brand_safety_score ?? '—'}/100 | Campaign Match: ${d.campaign_match ? '✅ Yes' : '❌ No'}`,
        `📝 ${d.ai_notes || 'Analysis complete.'}`,
      ];
      
      if (d.screenshot) {
        parts.push(`[BASE64_IMAGE]data:image/png;base64,${d.screenshot}`);
      }
      
      // Prepend job_id so the frontend can track live status
      if (d.job_id) {
        parts.unshift(`[JOB_ID]${d.job_id}`);
      }
      
      return parts.join('\n');
    } catch (err) {
      console.error('[AI] Post Analysis error:', err.message);
      // Fallback to LLM text analysis if scraping fails
      try {
        const res2 = await axios.post(`${PY}/generate`, {
          prompt: `Analyze this social media post link for the task "${taskTitle}": ${url}. What platform is it? Is the URL valid? Brief 2-3 sentence analysis.`,
          max_tokens: 200,
        }, { timeout: 45000 });
        return `🤖 ${res2.data?.response || 'Analysis unavailable.'}`;
      } catch {
        return 'Unable to analyze post — AI engine offline.';
      }
    }
  }

  // ========== 12. GET LIVE BOT STATUS ==========
  async getBotStatus(jobId: string): Promise<any> {
    try {
      const res = await axios.get(`${PY}/analyze-status/${jobId}`, { timeout: 5000 });
      return res.data;
    } catch {
      return { job_id: jobId, status: 'not_found' };
    }
  }
}
