/**
 * Brand Asset Guidelines API Routes
 *
 * API endpoints for generating text-based brand guidelines
 * (clear space, minimum size, usage rules, do's and don'ts).
 *
 * POST /generate — generate guidelines for a specific type
 * GET /status/:jobId — poll for async job status
 */

import express, { Request, Response } from 'express';
import { body, validationResult } from 'express-validator';
import { authenticate } from '../middleware/auth';
import { requirePermission } from '../middleware/permissions';
import { BrandAssetGuidelinesPipeline, type BrandGuidelinesPipelineResult } from '../services/aiContext/brandAssetGuidelinesPipeline';
import type { GuidelineType, BrandGuidelinesInputs } from '../services/aiContext/brandAssetGuidelinesPrompts';
import { buildHarmonyContext, mapHarmonyToPipelineInputs } from '../services/aiContext/harmonyContextService';
import { getModels } from '../models';
import { createJob, updateJobProgress, completeJob, failJob, getJob } from '../services/aiContext/aiJobManager';
import { aiContextService } from '../services/aiContext/aiContextService';

const router = express.Router();
router.use(authenticate);

// Valid guideline types
const VALID_GUIDELINE_TYPES: GuidelineType[] = [
  'clear-space-guidelines',
  'minimum-size-guidelines',
  'brand-usage-rules',
  'dos-and-donts',
];

// ============================================
// GET /status/:jobId — Poll for job status
// ============================================

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 /generate — Generate brand guidelines
// ============================================

router.post(
  '/generate',
  requirePermission('brand-manual', 'ai-generate'),
  [
    body('companyId').notEmpty().withMessage('Company ID is required'),
    body('guidelineType').isIn(VALID_GUIDELINE_TYPES).withMessage(`Invalid guideline type. Must be one of: ${VALID_GUIDELINE_TYPES.join(', ')}`),
    body('userInstructions').optional().trim(),
  ],
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.status(400).json({ errors: errors.array() });
      return;
    }

    const { companyId, guidelineType, userInstructions } = req.body;

    // Create async job
    const job = createJob('brand-asset-guidelines', companyId);

    // Return 202 Accepted immediately
    res.status(202).json({
      jobId: job.jobId,
      status: 'processing',
      guidelineType,
    });

    // Run pipeline asynchronously
    setImmediate(async () => {
      try {
        updateJobProgress(job.jobId, 10, 'Gathering brand context');

        // Build harmony context from all connected modules
        const harmonyContext = await buildHarmonyContext(companyId);

        updateJobProgress(job.jobId, 20, 'Preparing generation inputs');

        // Map harmony context to pipeline inputs
        const harmonyInputs = mapHarmonyToPipelineInputs(harmonyContext);

        // Build pipeline inputs
        const inputs: BrandGuidelinesInputs = {
          companyName: harmonyContext.companyName || '',
          companyDescription: harmonyContext.companyDescription,
          companyIndustry: harmonyContext.businessIndustry,
          businessModel: harmonyContext.businessModel,

          // Brand identity from Brand model (SOP 1.7)
          brandVoice: harmonyContext.brandVoice || harmonyContext.brandStrategyVoice,
          brandVoiceDos: harmonyContext.brandVoiceDos,
          brandVoiceDonts: harmonyContext.brandVoiceDonts,
          brandPersonalityPrimary: harmonyContext.brandPersonalityPrimary,
          brandPersonalitySecondary: harmonyContext.brandPersonalitySecondary,
          brandArchetype: harmonyContext.brandArchetype || harmonyContext.brandStrategyArchetype,
          brandPromise: harmonyContext.brandPromise,
          brandGuardrails: harmonyContext.brandGuardrails,
          brandForbiddenWords: harmonyContext.brandForbiddenWords,
          brandSymbols: harmonyContext.brandSymbols,
          brandSignatureExpressions: harmonyContext.brandSignatureExpressions,

          // Brand SOP 1.7 — visual direction and guardrails
          brandVisualDirection: harmonyContext.brandVisualDirection,
          brandVisualTheme: harmonyContext.brandVisualTheme,
          brandConsistencyGuardrails: harmonyContext.brandConsistencyGuardrails,
          brandForbiddenDesignPatterns: harmonyContext.brandForbiddenDesignPatterns,

          // Visual identity
          brandColors: harmonyContext.brandColors,
          brandFonts: harmonyContext.brandFonts,
          visualDescription: harmonyContext.visualDescription,

          // Visual identity from ModuleData
          visualIdentityColorPalette: harmonyContext.visualIdentityColorPalette,
          visualIdentityTypography: harmonyContext.visualIdentityTypography,
          visualIdentityDesignPrinciples: harmonyContext.visualIdentityDesignPrinciples,
          visualIdentityMood: harmonyContext.visualIdentityMood,
          visualIdentityStyle: harmonyContext.visualIdentityStyle,

          // Brand strategy
          brandStrategyPositioning: harmonyContext.brandStrategyPositioning,
          brandStrategyVoice: harmonyContext.brandStrategyVoice,
          brandStrategyValues: harmonyContext.brandStrategyValues,
          brandStrategyArchetype: harmonyContext.brandStrategyArchetype,
          brandStrategyTone: harmonyContext.brandStrategyTone,

          // Business profile
          businessMission: harmonyContext.businessMission,
          businessVision: harmonyContext.businessVision,
          businessCoreValues: harmonyContext.businessCoreValues,
          businessUsp: harmonyContext.businessUsp,

          // Brand guidelines (existing)
          brandGuidelinesDosAndDonts: harmonyContext.brandGuidelinesDosAndDonts,
          brandGuidelinesVoice: harmonyContext.brandGuidelinesVoice,
          brandGuidelinesDesignRules: harmonyContext.brandGuidelinesDesignRules,

          // Founder context
          founderNames: harmonyContext.founderNames,
          founderBios: harmonyContext.founderBios,
          founderResponsibilityAreas: harmonyContext.founderResponsibilityAreas,

          // Target guideline type
          guidelineType: guidelineType as GuidelineType,

          // User instructions
          userInstructions: userInstructions || undefined,
        };

        updateJobProgress(job.jobId, 30, `Generating ${guidelineType.replace(/-/g, ' ')}`);

        // Run the pipeline
        const pipeline = new BrandAssetGuidelinesPipeline(inputs);
        const result: BrandGuidelinesPipelineResult = await pipeline.run();

        if (result.errors.length > 0 && !result.content) {
          throw new Error(`Pipeline failed: ${result.errors.join('; ')}`);
        }

        updateJobProgress(job.jobId, 80, 'Saving guidelines');

        // Save as BrandAsset document
        const { BrandAsset } = getModels();
        const assetName = `${harmonyContext.companyName || 'Brand'} ${guidelineType.replace(/-/g, ' ').replace(/\b\w/g, (c: string) => c.toUpperCase())}`;

        const asset = await BrandAsset.create({
          companyId,
          name: assetName,
          type: guidelineType,
          description: result.content?.summary || `AI-generated ${guidelineType.replace(/-/g, ' ')} for ${harmonyContext.companyName || 'the brand'}`,
          format: 'content',
          source: 'ai-generation',
          contentData: JSON.stringify(result.content),
          isPrimary: false,
          tags: ['ai-generated', 'guidelines', guidelineType],
        });

        // Track this generation in AiContext so it appears in the AI Jobs report
        try {
          const ctx = await aiContextService.create({
            companyId,
            moduleSource: 'brand-asset-guidelines',
            analysisType: 'full-analysis',
            inputs: { companyName: harmonyContext.companyName || '', description: guidelineType.replace(/-/g, ' ') } as any,
            analysis: (result.content || {}) as any,
            metadata: {
              pipelineVersion: result.pipelineVersion,
              provider: result.provider,
              model: result.aiModel,
              tokensUsed: result.tokensUsed,
              inputTokens: result.inputTokens,
              outputTokens: result.outputTokens,
              processingTimeMs: result.processingTimeMs,
              latencyMs: result.processingTimeMs,
              overallConfidence: result.overallConfidence,
              fieldConfidences: {},
            },
          });
          await aiContextService.updateStatus(ctx.id, 'approved');
        } catch (ctxErr: any) {
          console.warn(`[BrandAssetGuidelines] AiContext save failed (non-fatal): ${ctxErr.message}`);
        }

        updateJobProgress(job.jobId, 100, 'Complete');

        completeJob(job.jobId, {
          name: asset.name,
          description: asset.description,
          type: guidelineType,
          format: 'content',
          source: 'ai-generation',
          contentData: result.content,
          assetId: asset._id,
        }, 'brand-asset-guidelines');

      } catch (error) {
        console.error('[BrandAssetGuidelines] Pipeline error:', error);
        failJob(job.jobId, (error as Error).message);
      }
    });
  }
);

export default router;