/**
 * AI Generated Version History Routes
 *
 * Tracks version history for AI-generated content across all Foundation modules.
 * Each successful AI generation creates a versioned record while the frontend
 * always displays only the latest version.
 *
 * Supports modules: business-profile, founder, employee, product, icp, persona, competitor
 */

import express, { Request, Response } from 'express';
import { authenticate } from '../middleware/auth';
import { requirePermission } from '../middleware/permissions';
import { getModels } from '../models';

const router = express.Router();

// All routes require authentication
router.use(authenticate);

// Allowed modules
const ALLOWED_MODULES = ['business-profile', 'founder', 'employee', 'product', 'icp', 'persona', 'competitor'] as const;

// Allowed sources
const ALLOWED_SOURCES = ['ai-generate-field', 'ai-generate-popup', 'business-profile-header', 'quick-generate', 'auto-fill', 'regenerate', 'upload', 'bulk-generate'] as const;

/**
 * POST / — Create a new version record
 * Auto-increments version number based on existing records for the entity+module+field combo
 */
router.post(
  '/',
  requirePermission('ai-processing', 'create'),
  async (req: Request, res: Response) => {
    try {
      const { companyId, entityId, module, field, content, generatedBy, source, promptContext } = req.body;

      // Validate required fields
      if (!companyId || !entityId || !module || !field || !content) {
        res.status(400).json({ error: 'companyId, entityId, module, field, and content are required' });
        return;
      }

      // Validate module enum
      if (!ALLOWED_MODULES.includes(module)) {
        res.status(400).json({ error: `Invalid module. Must be one of: ${ALLOWED_MODULES.join(', ')}` });
        return;
      }

      // Validate source enum
      if (source && !ALLOWED_SOURCES.includes(source)) {
        res.status(400).json({ error: `Invalid source. Must be one of: ${ALLOWED_SOURCES.join(', ')}` });
        return;
      }

      // Company access check
      if (!req.user!.companyIds.includes(companyId) && req.user!.role !== 'admin') {
        res.status(403).json({ error: 'Access denied' });
        return;
      }

      const { AiGeneratedVersion } = getModels();

      // Auto-increment version: find the current max version for this entity+module+field
      const latestVersion = await (AiGeneratedVersion as any)
        .findOne({ entityId, module, field })
        .sort({ version: -1 })
        .select('version')
        .lean();

      const nextVersion = (latestVersion?.version || 0) + 1;

      const versionRecord = await (AiGeneratedVersion as any).create({
        companyId,
        entityId,
        module,
        field,
        version: nextVersion,
        content,
        generatedBy: generatedBy || req.user!.id,
        source: source || 'ai-generate-field',
        promptContext: promptContext || undefined,
      });

      res.status(201).json(versionRecord);
    } catch (error: any) {
      console.error('[AiGeneratedVersion] Create error:', error);
      res.status(500).json({ error: 'Failed to create version record' });
    }
  }
);

/**
 * GET /:entityId/versions/:module/:field — Get all versions for a specific module+field
 * Sorted by version descending (newest first)
 */
router.get(
  '/:entityId/versions/:module/:field',
  async (req: Request, res: Response) => {
    try {
      const { entityId, module, field } = req.params;

      if (!ALLOWED_MODULES.includes(module as any)) {
        res.status(400).json({ error: `Invalid module. Must be one of: ${ALLOWED_MODULES.join(', ')}` });
        return;
      }

      const { AiGeneratedVersion } = getModels();

      const versions = await (AiGeneratedVersion as any)
        .find({ entityId, module, field })
        .sort({ version: -1 })
        .lean();

      res.json(versions);
    } catch (error: any) {
      console.error('[AiGeneratedVersion] Get versions error:', error);
      res.status(500).json({ error: 'Failed to get versions' });
    }
  }
);

/**
 * GET /:entityId/latest/:module/:field — Get the latest version for a specific module+field
 */
router.get(
  '/:entityId/latest/:module/:field',
  async (req: Request, res: Response) => {
    try {
      const { entityId, module, field } = req.params;

      if (!ALLOWED_MODULES.includes(module as any)) {
        res.status(400).json({ error: `Invalid module. Must be one of: ${ALLOWED_MODULES.join(', ')}` });
        return;
      }

      const { AiGeneratedVersion } = getModels();

      const latestVersion = await (AiGeneratedVersion as any)
        .findOne({ entityId, module, field })
        .sort({ version: -1 })
        .lean();

      if (!latestVersion) {
        res.status(404).json({ error: 'No version found for this field' });
        return;
      }

      res.json(latestVersion);
    } catch (error: any) {
      console.error('[AiGeneratedVersion] Get latest error:', error);
      res.status(500).json({ error: 'Failed to get latest version' });
    }
  }
);

/**
 * GET /:entityId/versions/:module — Get all versions for a module, grouped by field
 */
router.get(
  '/:entityId/versions/:module',
  async (req: Request, res: Response) => {
    try {
      const { entityId, module } = req.params;

      if (!ALLOWED_MODULES.includes(module as any)) {
        res.status(400).json({ error: `Invalid module. Must be one of: ${ALLOWED_MODULES.join(', ')}` });
        return;
      }

      const { AiGeneratedVersion } = getModels();

      const versions = await (AiGeneratedVersion as any)
        .find({ entityId, module })
        .sort({ field: 1, version: -1 })
        .lean();

      // Group by field
      const grouped: Record<string, any[]> = {};
      for (const v of versions) {
        if (!grouped[v.field]) grouped[v.field] = [];
        grouped[v.field].push(v);
      }

      res.json(grouped);
    } catch (error: any) {
      console.error('[AiGeneratedVersion] Get all versions error:', error);
      res.status(500).json({ error: 'Failed to get versions' });
    }
  }
);

/**
 * DELETE /:id — Delete a specific version record (admin only)
 */
router.delete(
  '/:id',
  requirePermission('ai-processing', 'delete'),
  async (req: Request, res: Response) => {
    try {
      const { id } = req.params;

      const { AiGeneratedVersion } = getModels();

      const deleted = await (AiGeneratedVersion as any).findByIdAndDelete(id);

      if (!deleted) {
        res.status(404).json({ error: 'Version record not found' });
        return;
      }

      res.json({ message: 'Version record deleted successfully' });
    } catch (error: any) {
      console.error('[AiGeneratedVersion] Delete error:', error);
      res.status(500).json({ error: 'Failed to delete version record' });
    }
  }
);

export default router;