/**
 * Guerrilla Marketing AI Context Routes
 *
 * API endpoints for Guerrilla Marketing AI generation.
 * POST /auto-fill — generate guerrilla marketing strategy, ideas, execution plan, scoring
 * POST /regenerate — regenerate guerrilla marketing content
 * POST /generate-ideas — generate ideas only (with count: 20/50/100)
 * POST /generate-scoring — generate scoring only
 * POST /generate-content — generate marketing content by type
 */

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';
import { authenticate } from '../middleware/auth';
import { requirePermission } from '../middleware/permissions';
import { GuerrillaMarketingPipeline, runGuerrillaMarketingPipeline } from '../services/aiContext/guerrillaMarketingPipeline';
import { GuerrillaMarketingPipelineInputs } from '../services/aiContext/guerrillaMarketingPrompts';
import { generateGuerrillaContent, GuerrillaContentType } from '../services/aiContext/guerrillaMarketingContentGeneration';
import { aiContextService } from '../services/aiContext/aiContextService';
import { getModels } from '../models';
import { createJob, updateJobProgress, completeJob, failJob, getJob } from '../services/aiContext/aiJobManager';
import { buildHarmonyContext, mapHarmonyToPipelineInputs } from '../services/aiContext/harmonyContextService';

const router = express.Router();
router.use(authenticate);

// ============================================
// GET /status/:jobId
// ============================================

router.get(
  '/status/:jobId',
  async (req: Request, res: Response) => {
    const { jobId } = req.params;
    const job = getJob(jobId);

    if (!job) {
      res.status(404).json({ error: 'Job not found' });
      return;
    }

    res.json({
      jobId: job.jobId,
      status: job.status,
      progress: job.progress,
      step: job.step,
      result: job.result,
      error: job.error,
    });
  }
);

// ============================================
// POST /auto-fill
// ============================================

router.post(
  '/auto-fill',
  requirePermission('guerrilla-marketing', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    const { companyId, customInstructions } = req.body;
    const ideaCount = req.body.ideaCount || 20;

    try {
      const job = createJob('guerrilla-marketing', companyId, req.body._moduleId);
      res.status(202).json({ jobId: job.jobId, status: 'processing' });

      setImmediate(async () => {
        try {
          const { Company, BusinessProfile, ICP, Product } = getModels();
          const company = await Company.findById(companyId);
          if (!company) {
            failJob(job.jobId, 'Company not found');
            return;
          }

          let businessProfile: any = null;
          try { businessProfile = await BusinessProfile.findOne({ companyId }); } catch {}

          // Gather context from various modules
          const companyContexts = await aiContextService.getByCompany(companyId, 'company-creation');
          const latestCompanyContext = companyContexts.find((c: any) => {
            const a = c.analysis?.toObject?.() || c.analysis || {};
            return c.status === 'approved' || a.industryType || a.businessModel || a.businessSummary;
          });

          let icpData: any = null;
          try { icpData = await ICP.findOne({ companyId, isActive: true }).sort({ createdAt: -1 }); } catch {}

          let brandStrategyData: any = null;
          try {
            const { ModuleData } = getModels();
            const brandStrategyDoc = await ModuleData.findOne({ moduleId: 'brand-strategy', companyId });
            if (brandStrategyDoc?.data) {
              brandStrategyData = brandStrategyDoc.data;
            }
          } catch {}

          let productNames: string[] | undefined;
          let productDescriptions: string[] | undefined;
          try {
            const products = await Product.find({ companyId }).limit(10);
            if (products.length > 0) {
              productNames = products.map((p: any) => p.name);
              productDescriptions = products.map((p: any) => p.description || p.shortDescription || '');
            }
          } catch {}

          let icpNames: string[] | undefined;
          let icpDescriptions: string[] | undefined;
          try {
            const icps = await ICP.find({ companyId }).limit(10);
            if (icps.length > 0) {
              icpNames = icps.map((i: any) => i.name || i.firmographicSnapshot?.companySize || 'ICP');
              icpDescriptions = icps.map((i: any) => i.description || i.painPoints || '');
            }
          } catch {}

          let personaNames: string[] | undefined;
          let personaDescriptions: string[] | undefined;
          try {
            const { Persona } = getModels();
            const personas = await Persona.find({ companyId }).limit(10);
            if (personas.length > 0) {
              personaNames = personas.map((p: any) => p.name || p.demographicSnapshot?.jobTitle || 'Persona');
              personaDescriptions = personas.map((p: any) => p.description || '');
            }
          } catch {}

          let competitorNames: string[] | undefined;
          let competitorDescriptions: string[] | undefined;
          try {
            const { Competitor } = getModels();
            const competitors = await Competitor.find({ companyId }).limit(10);
            if (competitors.length > 0) {
              competitorNames = competitors.map((c: any) => c.name);
              competitorDescriptions = competitors.map((c: any) => c.description || c.strengths || '');
            }
          } catch {}

          // Build pipeline inputs
          const pipelineInputs: GuerrillaMarketingPipelineInputs = {
            // The user's own brief from the "Generate with AI" popup or the AI Chat
            // generation flow. Stated as the highest-priority instruction in the
            // prompt, so it wins over the derived company context.
            customInstructions:
              typeof customInstructions === 'string' && customInstructions.trim()
                ? customInstructions.trim()
                : undefined,
            companyName: company.name,
            companyDescription: company.description || businessProfile?.description || undefined,
            companyIndustry: businessProfile?.primaryIndustry || undefined,
            companyBusinessModel: businessProfile?.businessModel || undefined,
            companyTargetAudience: undefined,
            companyPrimaryOffering: undefined,
            companyUsps: undefined,
            // Campaign specifics from request body
            campaignCategory: req.body.campaignCategory,
            campaignGoals: req.body.campaignGoals,
            targetAudienceType: req.body.targetAudienceType,
            budgetRange: req.body.budgetRange,
            locationType: req.body.locationType,
            campaignDuration: req.body.campaignDuration,
            toneStyle: req.body.toneStyle,
            linkedData: req.body.linkedData,
          };

          if (latestCompanyContext) {
            const analysis = (latestCompanyContext as any).analysis?.toObject?.() || (latestCompanyContext as any).analysis || {};
            if (analysis.industryType && !pipelineInputs.companyIndustry) pipelineInputs.companyIndustry = analysis.industryType;
            if (analysis.businessModel && !pipelineInputs.companyBusinessModel) pipelineInputs.companyBusinessModel = analysis.businessModel;
            if (analysis.targetAudience?.primary) pipelineInputs.companyTargetAudience = analysis.targetAudience.primary;
            if (analysis.primaryOffering) pipelineInputs.companyPrimaryOffering = analysis.primaryOffering;
            if (analysis.uspSuggestions?.length) pipelineInputs.companyUsps = analysis.uspSuggestions;
          }

          if (brandStrategyData) {
            pipelineInputs.brandVoice = brandStrategyData.brandVoice || undefined;
          }

          if (productNames?.length) {
            pipelineInputs.productNames = productNames;
            pipelineInputs.productDescriptions = productDescriptions;
          }
          if (icpNames?.length) {
            pipelineInputs.icpNames = icpNames;
            pipelineInputs.icpDescriptions = icpDescriptions;
          }
          if (personaNames?.length) {
            pipelineInputs.personaNames = personaNames;
            pipelineInputs.personaDescriptions = personaDescriptions;
          }
          if (competitorNames?.length) {
            pipelineInputs.competitorNames = competitorNames;
            pipelineInputs.competitorDescriptions = competitorDescriptions;
          }

          // === Harmony: Enrich pipeline inputs with cross-module brand context ===
          try {
            const harmonyCtx = await buildHarmonyContext(companyId);
            const harmonyFields = mapHarmonyToPipelineInputs(harmonyCtx);

            if (harmonyFields.brandVoice && !pipelineInputs.brandVoice) pipelineInputs.brandVoice = harmonyFields.brandVoice;
            if (harmonyFields.brandPersonality) pipelineInputs.brandPersonality = harmonyFields.brandPersonality;
            if (harmonyFields.brandArchetype) pipelineInputs.brandArchetype = harmonyFields.brandArchetype;
            if (harmonyFields.brandValues) pipelineInputs.brandValues = harmonyFields.brandValues;
            if (harmonyFields.brandPromise) pipelineInputs.brandPromise = harmonyFields.brandPromise;
            if (harmonyFields.brandGuardrails) pipelineInputs.brandGuardrails = harmonyFields.brandGuardrails;
            if (harmonyFields.brandForbiddenWords) pipelineInputs.brandForbiddenWords = harmonyFields.brandForbiddenWords;
            if (harmonyFields.brandVoiceDos) pipelineInputs.brandVoiceDos = harmonyFields.brandVoiceDos;
            if (harmonyFields.brandVoiceDonts) pipelineInputs.brandVoiceDonts = harmonyFields.brandVoiceDonts;
            if (harmonyFields.brandSymbols) pipelineInputs.brandSymbols = harmonyFields.brandSymbols;
            if (harmonyFields.brandSignatureExpressions) pipelineInputs.brandSignatureExpressions = harmonyFields.brandSignatureExpressions;
            if (harmonyFields.brandColors) pipelineInputs.brandColors = harmonyFields.brandColors;
            if (harmonyFields.brandFonts) pipelineInputs.brandFonts = harmonyFields.brandFonts;
            if (harmonyFields.visualDescription) pipelineInputs.visualDescription = harmonyFields.visualDescription;
            if (harmonyFields.businessMission) pipelineInputs.businessMission = harmonyFields.businessMission;
            if (harmonyFields.businessVision) pipelineInputs.businessVision = harmonyFields.businessVision;
            if (harmonyFields.businessCoreValues) pipelineInputs.businessCoreValues = harmonyFields.businessCoreValues;
            if (harmonyFields.icpDescription) pipelineInputs.icpDescription = harmonyFields.icpDescription;
            if (harmonyFields.icpPainPoints) pipelineInputs.icpPainPoints = harmonyFields.icpPainPoints;
            if (harmonyFields.personaJobTitles) pipelineInputs.personaJobTitles = harmonyFields.personaJobTitles;
            if (harmonyFields.personaPainPoints) pipelineInputs.personaPainPoints = harmonyFields.personaPainPoints;

            console.log(`[GuerrillaMarketing-AutoFill] Harmony context enrichment applied: ${Object.keys(harmonyFields).length} fields`);
          } catch (harmonyErr: any) {
            console.warn(`[GuerrillaMarketing-AutoFill] Harmony context enrichment failed (non-fatal): ${harmonyErr.message}`);
          }

          updateJobProgress(job.jobId, 10, 'Preparing context...');
          const result = await runGuerrillaMarketingPipeline(
            pipelineInputs,
            ideaCount,
            (progress, step) => { updateJobProgress(job.jobId, progress, step); }
          );

          if (!result.success) {
            failJob(job.jobId, result.error || 'Pipeline failed');
            return;
          }

          // Store full analysis in AiContext
          try {
            const context = await aiContextService.create({
              companyId,
              moduleSource: 'guerrilla-marketing',
              analysisType: 'full-analysis',
              inputs: { companyName: company.name, description: pipelineInputs.companyDescription } as any,
              analysis: {
                strategy: result.strategy,
                ideas: result.ideas,
                executionPlan: result.executionPlan,
                scoring: result.scoring,
              },
              metadata: {
                pipelineVersion: '1.0',
                provider: result.provider,
                model: result.model,
                tokensUsed: result.tokensUsed,
                inputTokens: result.inputTokens,
                outputTokens: result.outputTokens,
                latencyMs: result.latencyMs,
                processingTimeMs: result.latencyMs || 0,
                overallConfidence: 0.85,
                fieldConfidences: {},
              } as any,
            });
            await aiContextService.updateStatus(context.id, 'approved');
          } catch (ctxErr: any) {
            console.warn(`[GuerrillaMarketing-AutoFill] AiContext save failed (non-fatal): ${ctxErr.message}`);
          }

          // Compose auto-fill data
          const autoFillData: Record<string, any> = {
            aiStrategySummary: '',
            ...result.strategy,
            ideas: result.ideas || [],
            executionPlan: result.executionPlan || [],
            scoring: result.scoring || {},
          };

          // Compose aiStrategySummary from strategy fields if not already present
          const strategy = result.strategy || {};
          if (!autoFillData.aiStrategySummary) {
            const strategyParts: string[] = [];
            if (strategy.name) strategyParts.push(`Strategy: ${strategy.name}`);
            if (strategy.summary) strategyParts.push(strategy.summary);
            if (strategy.coreConcept) strategyParts.push(`Core Concept: ${strategy.coreConcept}`);
            if (strategy.toneAndVoice?.primaryTone) strategyParts.push(`Tone: ${strategy.toneAndVoice.primaryTone}`);
            if (strategyParts.length > 0) {
              autoFillData.aiStrategySummary = strategyParts.join('\n\n');
            }
          }

          console.log(`[GuerrillaMarketing-AutoFill] Pipeline result: ideas=${result.ideas?.length || 0}, plan phases=${result.executionPlan?.length || 0}`);
          completeJob(job.jobId, autoFillData, 'generated');

        } catch (err: any) {
          console.error(`[GuerrillaMarketing-AutoFill] Error: ${err.message}`);
          failJob(job.jobId, err.message);
        }
      });

    } catch (err: any) {
      console.error(`[GuerrillaMarketing-AutoFill] Outer error: ${err.message}`);
      res.status(500).json({ error: 'Failed to start auto-fill', details: err.message });
    }
  }
);

// ============================================
// POST /regenerate
// ============================================

router.post(
  '/regenerate',
  requirePermission('guerrilla-marketing', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    const { companyId } = req.body;
    const ideaCount = req.body.ideaCount || 20;

    try {
      const job = createJob('guerrilla-marketing', companyId, req.body._moduleId);
      res.status(202).json({ jobId: job.jobId, status: 'processing' });

      setImmediate(async () => {
        try {
          const { Company, BusinessProfile, ICP, Product } = getModels();
          const company = await Company.findById(companyId);
          if (!company) {
            failJob(job.jobId, 'Company not found');
            return;
          }

          let businessProfile: any = null;
          try { businessProfile = await BusinessProfile.findOne({ companyId }); } catch {}

          let icpData: any = null;
          try { icpData = await ICP.findOne({ companyId, isActive: true }).sort({ createdAt: -1 }); } catch {}

          let productNames: string[] | undefined;
          try {
            const products = await Product.find({ companyId }).limit(10);
            if (products.length > 0) {
              productNames = products.map((p: any) => p.name);
            }
          } catch {}

          let icpNames: string[] | undefined;
          try {
            const icps = await ICP.find({ companyId }).limit(10);
            if (icps.length > 0) {
              icpNames = icps.map((i: any) => i.name || 'ICP');
            }
          } catch {}

          let personaNames: string[] | undefined;
          try {
            const { Persona } = getModels();
            const personas = await Persona.find({ companyId }).limit(10);
            if (personas.length > 0) {
              personaNames = personas.map((p: any) => p.name || 'Persona');
            }
          } catch {}

          let competitorNames: string[] | undefined;
          try {
            const { Competitor } = getModels();
            const competitors = await Competitor.find({ companyId }).limit(10);
            if (competitors.length > 0) {
              competitorNames = competitors.map((c: any) => c.name);
            }
          } catch {}

          const pipelineInputs: GuerrillaMarketingPipelineInputs = {
            companyName: company.name,
            companyDescription: company.description || businessProfile?.description || undefined,
            companyIndustry: businessProfile?.primaryIndustry || undefined,
            companyBusinessModel: businessProfile?.businessModel || undefined,
            campaignCategory: req.body.campaignCategory,
            campaignGoals: req.body.campaignGoals,
            targetAudienceType: req.body.targetAudienceType,
            budgetRange: req.body.budgetRange,
            locationType: req.body.locationType,
            campaignDuration: req.body.campaignDuration,
            toneStyle: req.body.toneStyle,
            linkedData: req.body.linkedData,
          };

          if (productNames?.length) pipelineInputs.productNames = productNames;
          if (icpNames?.length) pipelineInputs.icpNames = icpNames;
          if (personaNames?.length) pipelineInputs.personaNames = personaNames;
          if (competitorNames?.length) pipelineInputs.competitorNames = competitorNames;

          // Harmony enrichment
          try {
            const harmonyCtx = await buildHarmonyContext(companyId);
            const harmonyFields = mapHarmonyToPipelineInputs(harmonyCtx);
            if (harmonyFields.brandPersonality) pipelineInputs.brandPersonality = harmonyFields.brandPersonality;
            if (harmonyFields.brandArchetype) pipelineInputs.brandArchetype = harmonyFields.brandArchetype;
            if (harmonyFields.brandValues) pipelineInputs.brandValues = harmonyFields.brandValues;
            if (harmonyFields.brandPromise) pipelineInputs.brandPromise = harmonyFields.brandPromise;
            if (harmonyFields.brandGuardrails) pipelineInputs.brandGuardrails = harmonyFields.brandGuardrails;
            if (harmonyFields.brandForbiddenWords) pipelineInputs.brandForbiddenWords = harmonyFields.brandForbiddenWords;
            if (harmonyFields.businessMission) pipelineInputs.businessMission = harmonyFields.businessMission;
            if (harmonyFields.businessVision) pipelineInputs.businessVision = harmonyFields.businessVision;
            if (harmonyFields.businessCoreValues) pipelineInputs.businessCoreValues = harmonyFields.businessCoreValues;
          } catch (harmonyErr: any) {
            console.warn(`[GuerrillaMarketing-Regenerate] Harmony enrichment failed (non-fatal): ${harmonyErr.message}`);
          }

          updateJobProgress(job.jobId, 10, 'Preparing context...');
          const result = await runGuerrillaMarketingPipeline(
            pipelineInputs,
            ideaCount,
            (progress, step) => { updateJobProgress(job.jobId, progress, step); }
          );

          if (!result.success) {
            failJob(job.jobId, result.error || 'Pipeline failed');
            return;
          }

          const autoFillData: Record<string, any> = {
            ...result.strategy,
            ideas: result.ideas || [],
            executionPlan: result.executionPlan || [],
            scoring: result.scoring || {},
          };

          console.log(`[GuerrillaMarketing-Regenerate] Pipeline result: ideas=${result.ideas?.length || 0}, plan phases=${result.executionPlan?.length || 0}`);
          completeJob(job.jobId, autoFillData, 'regenerated');

        } catch (err: any) {
          console.error(`[GuerrillaMarketing-Regenerate] Error: ${err.message}`);
          failJob(job.jobId, err.message);
        }
      });

    } catch (err: any) {
      console.error(`[GuerrillaMarketing-Regenerate] Outer error: ${err.message}`);
      res.status(500).json({ error: 'Failed to start regeneration', details: err.message });
    }
  }
);

// ============================================
// POST /generate-ideas
// ============================================

router.post(
  '/generate-ideas',
  requirePermission('guerrilla-marketing', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    const { companyId } = req.body;
    const ideaCount = req.body.ideaCount || 20;

    try {
      const job = createJob('guerrilla-marketing', companyId, req.body._moduleId);
      res.status(202).json({ jobId: job.jobId, status: 'processing' });

      setImmediate(async () => {
        try {
          const { Company, BusinessProfile } = getModels();
          const company = await Company.findById(companyId);
          if (!company) {
            failJob(job.jobId, 'Company not found');
            return;
          }

          let businessProfile: any = null;
          try { businessProfile = await BusinessProfile.findOne({ companyId }); } catch {}

          // Build minimal inputs for idea generation
          const pipelineInputs: GuerrillaMarketingPipelineInputs = {
            companyName: company.name,
            companyDescription: company.description || businessProfile?.description || undefined,
            companyIndustry: businessProfile?.primaryIndustry || undefined,
            campaignCategory: req.body.campaignCategory,
            campaignGoals: req.body.campaignGoals,
            targetAudienceType: req.body.targetAudienceType,
            budgetRange: req.body.budgetRange,
            toneStyle: req.body.toneStyle,
            linkedData: req.body.linkedData,
          };

          // Use existing strategy if provided
          const existingStrategy = req.body.strategy || {};

          updateJobProgress(job.jobId, 10, 'Generating ideas...');
          const result = await runGuerrillaMarketingPipeline(
            pipelineInputs,
            ideaCount,
            (progress, step) => { updateJobProgress(job.jobId, progress, step); }
          );

          if (!result.success) {
            failJob(job.jobId, result.error || 'Pipeline failed');
            return;
          }

          completeJob(job.jobId, { ideas: result.ideas || [] }, 'generated');

        } catch (err: any) {
          console.error(`[GuerrillaMarketing-GenerateIdeas] Error: ${err.message}`);
          failJob(job.jobId, err.message);
        }
      });

    } catch (err: any) {
      console.error(`[GuerrillaMarketing-GenerateIdeas] Outer error: ${err.message}`);
      res.status(500).json({ error: 'Failed to start idea generation', details: err.message });
    }
  }
);

// ============================================
// POST /generate-scoring
// ============================================

router.post(
  '/generate-scoring',
  requirePermission('guerrilla-marketing', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    const { companyId } = req.body;

    try {
      const job = createJob('guerrilla-marketing', companyId, req.body._moduleId);
      res.status(202).json({ jobId: job.jobId, status: 'processing' });

      setImmediate(async () => {
        try {
          const { Company, BusinessProfile } = getModels();
          const company = await Company.findById(companyId);
          if (!company) {
            failJob(job.jobId, 'Company not found');
            return;
          }

          let businessProfile: any = null;
          try { businessProfile = await BusinessProfile.findOne({ companyId }); } catch {}

          const pipelineInputs: GuerrillaMarketingPipelineInputs = {
            companyName: company.name,
            companyDescription: company.description || businessProfile?.description || undefined,
            companyIndustry: businessProfile?.primaryIndustry || undefined,
            campaignCategory: req.body.campaignCategory,
            campaignGoals: req.body.campaignGoals,
            budgetRange: req.body.budgetRange,
            toneStyle: req.body.toneStyle,
          };

          const strategy = req.body.strategy || {};
          const ideas = req.body.ideas || [];
          const executionPlan = req.body.executionPlan || [];

          updateJobProgress(job.jobId, 10, 'Evaluating campaign...');
          const { buildGuerrillaScoringPrompt } = await import('../services/aiContext/guerrillaMarketingPrompts');
          const { generateWithAI } = await import('../utils/aiProvider');
          const { parseJsonFromAI } = await import('../services/aiContext/parseJsonFromAI');

          const { systemPrompt, userPrompt, maxTokens } = buildGuerrillaScoringPrompt(
            pipelineInputs,
            { strategy, ideas, executionPlan }
          );

          const userId = req.user?._id?.toString() || req.user?.id;
          const aiResult = await generateWithAI(userPrompt, systemPrompt, maxTokens, 0.7, 'json', undefined, undefined, userId);
          let scoring: any = {};

          if (aiResult?.content) {
            const parsed = parseJsonFromAI(aiResult.content);
            if (parsed) {
              scoring = parsed.scoring || parsed;
            }
          }

          completeJob(job.jobId, { scoring }, 'generated');

        } catch (err: any) {
          console.error(`[GuerrillaMarketing-GenerateScoring] Error: ${err.message}`);
          failJob(job.jobId, err.message);
        }
      });

    } catch (err: any) {
      console.error(`[GuerrillaMarketing-GenerateScoring] Outer error: ${err.message}`);
      res.status(500).json({ error: 'Failed to start scoring generation', details: err.message });
    }
  }
);

// ============================================
// POST /generate-content
// ============================================

router.post(
  '/generate-content',
  requirePermission('guerrilla-marketing', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ error: 'Validation failed', details: errors.array() });
      return;
    }

    const { companyId } = req.body;
    const contentType: GuerrillaContentType | 'all' = req.body.contentType || 'all';
    // BUG #101: capture the requesting user so content generation uses the
    // organization's configured AI provider/keys (same pattern as scoring route).
    const userId = req.user?._id?.toString() || req.user?.id;

    try {
      const job = createJob('guerrilla-marketing', companyId, req.body._moduleId);
      res.status(202).json({ jobId: job.jobId, status: 'processing' });

      setImmediate(async () => {
        try {
          const { Company, BusinessProfile } = getModels();
          const company = await Company.findById(companyId);
          if (!company) {
            failJob(job.jobId, 'Company not found');
            return;
          }

          let businessProfile: any = null;
          try { businessProfile = await BusinessProfile.findOne({ companyId }); } catch {}

          // Build pipeline inputs for content generation
          const pipelineInputs: GuerrillaMarketingPipelineInputs = {
            companyName: company.name,
            companyDescription: company.description || businessProfile?.description || undefined,
            companyIndustry: businessProfile?.primaryIndustry || undefined,
            companyBusinessModel: businessProfile?.businessModel || undefined,
            campaignCategory: req.body.campaignCategory,
            campaignGoals: req.body.campaignGoals,
            budgetRange: req.body.budgetRange,
            toneStyle: req.body.toneStyle,
          };

          // Use provided strategy and ideas, or fetch from campaign
          const strategy = req.body.strategy || {};
          const selectedIdeas = req.body.selectedIdeas || req.body.ideas || [];

          updateJobProgress(job.jobId, 10, 'Generating content...');

          const result = await generateGuerrillaContent(
            pipelineInputs,
            strategy,
            selectedIdeas,
            contentType,
            (progress, step) => { updateJobProgress(job.jobId, progress, step); },
            userId,
            companyId,
          );

          console.log(`[GuerrillaMarketing-ContentGen] Generated ${result.items.length} content items of type: ${result.contentType}`);

          // BUG #101: don't report an empty generation as success. If the AI
          // produced zero items (provider error, unparseable output, etc.) fail
          // the job so the frontend surfaces a real error instead of silently
          // "succeeding" with no content.
          if (!result.items.length) {
            failJob(job.jobId, 'No content could be generated. Please check your AI provider configuration and try again.');
            return;
          }

          completeJob(job.jobId, { contentItems: result.items, contentType: result.contentType }, 'generated');

        } catch (err: any) {
          console.error(`[GuerrillaMarketing-ContentGen] Error: ${err.message}`);
          failJob(job.jobId, err.message);
        }
      });

    } catch (err: any) {
      console.error(`[GuerrillaMarketing-ContentGen] Outer error: ${err.message}`);
      res.status(500).json({ error: 'Failed to start content generation', details: err.message });
    }
  }
);

export default router;