import { Router, Request, Response } from 'express';
import multer from 'multer';
import { generateElementorJSON } from '../services/imageAnalysis';
import { adaptToVersion } from '../services/versionAdapter';
import { validateGenerationResult } from '../services/validator';
import { getVersionDefinition, getLatestVersion, getSupportedVersions } from '../services/versionRegistry';
import { isDatabaseConnected } from '../config/database';
import GenerationHistoryModel from '../models/GenerationHistory';

const router = Router();

const MAX_MB = parseInt(process.env.MAX_IMAGE_SIZE_MB ?? '10', 10);
const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: MAX_MB * 1024 * 1024 },
  fileFilter: (_req, file, cb) => {
    const allowed = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
    if (allowed.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error(`Unsupported file type: ${file.mimetype}. Use JPEG, PNG, WebP, or GIF.`));
    }
  },
});

router.post('/', upload.single('image'), async (req: Request, res: Response): Promise<void> => {
  try {
    if (!req.file) {
      res.status(400).json({ error: 'No image file provided.' });
      return;
    }

    const requestedVersion = (req.body.version as string | undefined)?.trim();
    const supported = getSupportedVersions();
    const latestVersion = getLatestVersion().version;

    const versionWarnings: string[] = [];
    let targetVersion = latestVersion;

    if (requestedVersion) {
      if (supported.includes(requestedVersion)) {
        targetVersion = requestedVersion;
      } else {
        versionWarnings.push(
          `Version "${requestedVersion}" is not in the supported registry. Falling back to latest (${latestVersion}).`
        );
      }
    }

    const versionDef = getVersionDefinition(targetVersion) ?? getLatestVersion();
    const imageBase64 = req.file.buffer.toString('base64');
    const mimeType = req.file.mimetype;

    // Generate Elementor JSON directly from the image (single Claude call)
    let result;
    try {
      result = await generateElementorJSON(imageBase64, mimeType, versionDef);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      res.status(502).json({ error: `Generation failed: ${msg}` });
      return;
    }

    // Adapt to target version if downgrading
    const adaptedResult = adaptToVersion(result, targetVersion);
    adaptedResult.warnings = [...versionWarnings, ...adaptedResult.warnings];

    // Validate
    const validation = validateGenerationResult(adaptedResult);
    if (!validation.valid) {
      res.status(422).json({
        error: 'Generated JSON failed validation.',
        validationErrors: validation.errors,
        warnings: validation.warnings,
      });
      return;
    }

    // Persist to MongoDB if available
    if (isDatabaseConnected()) {
      try {
        await GenerationHistoryModel.create({
          imageFileName: req.file.originalname,
          imageMimeType: mimeType,
          targetVersion,
          confidence: adaptedResult.confidence,
          sectionsCount: adaptedResult.metadata.sectionsCount,
          widgetsCount: adaptedResult.metadata.widgetsCount,
          usesContainers: adaptedResult.metadata.usesContainers,
          warnings: adaptedResult.warnings,
          outputJson: adaptedResult.template,
        });
      } catch {
        // Non-fatal
      }
    }

    res.json({
      success: true,
      template: adaptedResult.template,
      targetVersion,
      confidence: adaptedResult.confidence,
      warnings: [...adaptedResult.warnings, ...validation.warnings],
      metadata: adaptedResult.metadata,
    });
  } catch (err) {
    const message = err instanceof Error ? err.message : 'Unknown error';
    res.status(500).json({ error: `Generation failed: ${message}` });
  }
});

export default router;
