/**
 * Payload Transformation Middleware
 *
 * Transforms WordPress snake_case payloads to camelCase expected by API
 */

import { Request, Response, NextFunction } from 'express';
import { logger } from '../utils/logger';

/**
 * Transform WordPress job payload from snake_case to camelCase
 */
export function transformWordPressJobPayload(
  req: Request,
  _res: Response,
  next: NextFunction
): void {
  try {
    if (req.body && (req.body.resource_type === 'site_content' || req.body.resourceType === 'site_content')) {
      const aliases: Record<string, string> = {
        resource_type: 'resourceType',
        contract_version: 'contractVersion',
        source_language: 'sourceLang',
        source_lang: 'sourceLang',
        target_language: 'targetLang',
        target_lang: 'targetLang',
        source_revision: 'sourceRevision',
        attempt_token: 'attemptToken',
        callback_url: 'callbackUrl',
        callback_secret: 'callbackSecret',
        client_job_id: 'clientJobId',
        job_id: 'clientJobId',
      };
      const transformed: Record<string, unknown> = Object.create(null);
      for (const [key, value] of Object.entries(req.body)) {
        const target = aliases[key] ?? key;
        if (Object.prototype.hasOwnProperty.call(transformed, target)) {
          transformed[`conflicting_${key}`] = value;
        } else {
          transformed[target] = value;
        }
      }
      req.body = transformed;
      logger.debug('Segmented Site Content payload transformed', {
        transformedFieldCount: Object.keys(transformed).length,
      });
      next();
      return;
    }

    // Check if this is a WordPress payload (has snake_case fields)
    if (req.body && req.body.source_lang) {
      logger.debug('Transforming WordPress payload to camelCase', {
        originalFields: Object.keys(req.body),
      });

      // Create new body with camelCase fields
      const transformed: any = {};

      // Required fields
      if (req.body.source_lang) transformed.sourceLang = req.body.source_lang;
      if (req.body.target_lang) transformed.targetLang = req.body.target_lang;
      // Structured fields (new API) — passed through as-is
      if (req.body.title !== undefined) transformed.title = req.body.title;
      if (req.body.excerpt !== undefined) transformed.excerpt = req.body.excerpt;
      if (req.body.content !== undefined) transformed.content = req.body.content;
      if (req.body.fields !== undefined) transformed.fields = req.body.fields;

      // Optional fields
      if (req.body.tone) transformed.tone = req.body.tone;
      if (req.body.format) transformed.format = req.body.format;
      if (req.body.preserve_tags !== undefined) transformed.preserveTags = req.body.preserve_tags;
      if (req.body.callback_url) transformed.callbackUrl = req.body.callback_url;
      if (req.body.callback_secret) transformed.callbackSecret = req.body.callback_secret;
      if (req.body.job_id) transformed.clientJobId = req.body.job_id;
      if (req.body.client_job_id) transformed.clientJobId = req.body.client_job_id;

      // Bulk translation fields (pass through as-is)
      if (req.body.strings) transformed.strings = req.body.strings;

      // Per-request exception list (pass through as-is)
      if (req.body.exceptions !== undefined) transformed.exceptions = req.body.exceptions;

      // Replace body with transformed version
      req.body = transformed;

      logger.debug('Payload transformed successfully', {
        transformedFields: Object.keys(transformed),
      });
    }

    next();
  } catch (error) {
    logger.error('Error transforming WordPress payload', { error });
    next(); // Continue anyway, let validation catch issues
  }
}

/**
 * Transform response from camelCase to snake_case for WordPress
 */
export function transformResponseForWordPress(
  req: Request,
  res: Response,
  next: NextFunction
): void {
  // Store original json method
  const originalJson = res.json.bind(res);

  // Override json method
  res.json = function (data: any): Response {
    // Check if request came from WordPress (has WP user agent or specific header)
    const isWordPress =
      req.headers['user-agent']?.includes('WordPress') ||
      req.headers['x-wp-source'] === 'true';

    if (isWordPress && data && typeof data === 'object') {
      // Transform camelCase to snake_case for WordPress compatibility
      const transformed = transformKeysToSnakeCase(data);
      return originalJson(transformed);
    }

    return originalJson(data);
  };

  next();
}

/**
 * Recursively transform object keys from camelCase to snake_case
 */
function transformKeysToSnakeCase(obj: any): any {
  if (Array.isArray(obj)) {
    return obj.map(transformKeysToSnakeCase);
  }

  if (obj !== null && typeof obj === 'object') {
    const result: any = {};
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase();
        result[snakeKey] = transformKeysToSnakeCase(obj[key]);
      }
    }
    return result;
  }

  return obj;
}
