import express from 'express';
import { authenticateToken } from '../middleware/auth.js';
import TranslationService from '../services/TranslationService.js';

const router = express.Router();

// ========== Dictionary Operations ==========

/**
 * GET /api/translations
 * List all translation dictionaries with pagination
 */
router.get('/', authenticateToken, async (req, res, next) => {
  try {
    const filters = {
      projectId: req.query.projectId,
      status: req.query.status,
      createdBy: req.query.createdBy,
      limit: parseInt(req.query.limit) || 50,
      offset: parseInt(req.query.offset) || 0
    };

    const result = await TranslationService.listDictionaries(filters);

    res.status(200).json({
      status: 'success',
      code: 'DICTIONARIES_RETRIEVED',
      message: 'Translation dictionaries retrieved successfully',
      data: {
        dictionaries: result.dictionaries,
        total: result.total,
        limit: filters.limit,
        offset: filters.offset
      }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * GET /api/translations/:id
 * Get a single translation dictionary with mappings
 */
router.get('/:id', authenticateToken, async (req, res, next) => {
  try {
    const dictionary = await TranslationService.getDictionary(req.params.id);

    res.status(200).json({
      status: 'success',
      code: 'DICTIONARY_RETRIEVED',
      message: 'Translation dictionary retrieved successfully',
      data: { dictionary }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * POST /api/translations
 * Create a new translation dictionary
 */
router.post('/', authenticateToken, async (req, res, next) => {
  try {
    const { name, description, projectId, sourceSystem, targetSystem, tags, status } = req.body;

    if (!name || !projectId) {
      return res.status(400).json({
        status: 'error',
        code: 'VALIDATION_ERROR',
        message: 'Name and projectId are required',
        data: null
      });
    }

    const dictionary = await TranslationService.createDictionary({
      name,
      description,
      projectId,
      sourceSystem,
      targetSystem,
      tags,
      status
    }, req.user.id);

    res.status(201).json({
      status: 'success',
      code: 'DICTIONARY_CREATED',
      message: 'Translation dictionary created successfully',
      data: { dictionary }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * PUT /api/translations/:id
 * Update a translation dictionary
 */
router.put('/:id', authenticateToken, async (req, res, next) => {
  try {
    const { name, description, status, sourceSystem, targetSystem, tags } = req.body;

    const dictionary = await TranslationService.updateDictionary(req.params.id, {
      name,
      description,
      status,
      sourceSystem,
      targetSystem,
      tags
    }, req.user.id);

    res.status(200).json({
      status: 'success',
      code: 'DICTIONARY_UPDATED',
      message: 'Translation dictionary updated successfully',
      data: { dictionary }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * DELETE /api/translations/:id
 * Soft delete (archive) a translation dictionary
 */
router.delete('/:id', authenticateToken, async (req, res, next) => {
  try {
    await TranslationService.deleteDictionary(req.params.id, req.user.id);

    res.status(200).json({
      status: 'success',
      code: 'DICTIONARY_ARCHIVED',
      message: 'Translation dictionary archived successfully',
      data: null
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

// ========== Mapping Operations ==========

/**
 * POST /api/translations/:id/mappings
 * Create a new mapping in a dictionary
 */
router.post('/:id/mappings', authenticateToken, async (req, res, next) => {
  try {
    const { sourceToken, targetToken, transformRule, validated, confidence, notes } = req.body;

    if (!sourceToken || !targetToken) {
      return res.status(400).json({
        status: 'error',
        code: 'VALIDATION_ERROR',
        message: 'sourceToken and targetToken are required',
        data: null
      });
    }

    const mapping = await TranslationService.createMapping(req.params.id, {
      sourceToken,
      targetToken,
      transformRule,
      validated,
      confidence,
      notes
    }, req.user.id);

    res.status(201).json({
      status: 'success',
      code: 'MAPPING_CREATED',
      message: 'Translation mapping created successfully',
      data: { mapping }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    if (error.name === 'SequelizeUniqueConstraintError') {
      return res.status(409).json({
        status: 'error',
        code: 'DUPLICATE_MAPPING',
        message: 'A mapping for this source token already exists in this dictionary',
        data: null
      });
    }
    next(error);
  }
});

/**
 * PUT /api/translations/:id/mappings/:mappingId
 * Update a mapping
 */
router.put('/:id/mappings/:mappingId', authenticateToken, async (req, res, next) => {
  try {
    const { sourceToken, targetToken, transformRule, validated, confidence, notes } = req.body;

    const mapping = await TranslationService.updateMapping(req.params.id, req.params.mappingId, {
      sourceToken,
      targetToken,
      transformRule,
      validated,
      confidence,
      notes
    }, req.user.id);

    res.status(200).json({
      status: 'success',
      code: 'MAPPING_UPDATED',
      message: 'Translation mapping updated successfully',
      data: { mapping }
    });
  } catch (error) {
    if (error.message === 'Mapping not found') {
      return res.status(404).json({
        status: 'error',
        code: 'MAPPING_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * DELETE /api/translations/:id/mappings/:mappingId
 * Delete a mapping
 */
router.delete('/:id/mappings/:mappingId', authenticateToken, async (req, res, next) => {
  try {
    await TranslationService.deleteMapping(req.params.id, req.params.mappingId, req.user.id);

    res.status(200).json({
      status: 'success',
      code: 'MAPPING_DELETED',
      message: 'Translation mapping deleted successfully',
      data: null
    });
  } catch (error) {
    if (error.message === 'Mapping not found') {
      return res.status(404).json({
        status: 'error',
        code: 'MAPPING_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * POST /api/translations/:id/mappings/bulk
 * Bulk import mappings
 */
router.post('/:id/mappings/bulk', authenticateToken, async (req, res, next) => {
  try {
    const { mappings } = req.body;

    if (!Array.isArray(mappings) || mappings.length === 0) {
      return res.status(400).json({
        status: 'error',
        code: 'VALIDATION_ERROR',
        message: 'mappings must be a non-empty array',
        data: null
      });
    }

    const result = await TranslationService.bulkImportMappings(req.params.id, mappings, req.user.id);

    res.status(200).json({
      status: 'success',
      code: 'BULK_IMPORT_COMPLETED',
      message: `Bulk import completed: ${result.created} created, ${result.updated} updated, ${result.errors.length} errors`,
      data: result
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

// ========== Validation & Analysis ==========

/**
 * GET /api/translations/:id/validate
 * Validate dictionary mappings
 */
router.get('/:id/validate', authenticateToken, async (req, res, next) => {
  try {
    const validation = await TranslationService.validateDictionary(req.params.id);

    res.status(200).json({
      status: 'success',
      code: 'VALIDATION_COMPLETED',
      message: 'Dictionary validation completed',
      data: { validation }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * GET /api/translations/:id/coverage
 * Calculate token coverage percentage
 */
router.get('/:id/coverage', authenticateToken, async (req, res, next) => {
  try {
    const coverage = await TranslationService.calculateCoverage(req.params.id);

    res.status(200).json({
      status: 'success',
      code: 'COVERAGE_CALCULATED',
      message: 'Coverage calculated successfully',
      data: { coverage }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

/**
 * GET /api/translations/:id/export
 * Export dictionary as JSON
 */
router.get('/:id/export', authenticateToken, async (req, res, next) => {
  try {
    const exportData = await TranslationService.exportDictionary(req.params.id);

    res.status(200).json({
      status: 'success',
      code: 'DICTIONARY_EXPORTED',
      message: 'Dictionary exported successfully',
      data: { export: exportData }
    });
  } catch (error) {
    if (error.message === 'Dictionary not found') {
      return res.status(404).json({
        status: 'error',
        code: 'DICTIONARY_NOT_FOUND',
        message: error.message,
        data: null
      });
    }
    next(error);
  }
});

export default router;
