const Template = require('../models/Template');

// Presets formati standard
const FORMAT_PRESETS = {
  'A4': { width: 2480, height: 3508, dpi: 300 },
  'A4-landscape': { width: 3508, height: 2480, dpi: 300 },
  'A3': { width: 3508, height: 4961, dpi: 300 },
  'A3-landscape': { width: 4961, height: 3508, dpi: 300 },
  'instagram-post': { width: 1080, height: 1080, dpi: 72 },
  'instagram-story': { width: 1080, height: 1920, dpi: 72 },
  'instagram-portrait': { width: 1080, height: 1350, dpi: 72 },
  'facebook-post': { width: 1200, height: 630, dpi: 72 },
  'facebook-event': { width: 1920, height: 1080, dpi: 72 },
  'twitter-post': { width: 1200, height: 675, dpi: 72 },
  'poster-24x36': { width: 7200, height: 10800, dpi: 300 },
  'flyer-5x7': { width: 1500, height: 2100, dpi: 300 }
};

const templateController = {
  // POST /templates
  async create(req, res) {
    try {
      const { 
        name, 
        templateType, 
        description, 
        format, 
        safeArea, 
        backgroundColor,
        layers,
        logoSlots,
        palette,
        typography,
        defaultAiPromptHints,
        metadata 
      } = req.body;

      // Applica preset se specificato
      let finalFormat = format;
      if (format?.preset && FORMAT_PRESETS[format.preset]) {
        finalFormat = { 
          ...FORMAT_PRESETS[format.preset], 
          preset: format.preset,
          unit: 'px'
        };
      }

      // Valida layers
      if (!layers || !Array.isArray(layers) || layers.length === 0) {
        return res.status(400).json({ 
          success: false, 
          error: 'Almeno un layer è richiesto' 
        });
      }

      // Assicura ID unici per layer
      const layersWithIds = layers.map((layer, idx) => ({
        ...layer,
        id: layer.id || `layer_${layer.type}_${idx}`
      }));

      const template = new Template({
        name,
        templateType,
        description,
        format: finalFormat,
        safeArea: safeArea || {},
        backgroundColor: backgroundColor || '#1a1a2e',
        layers: layersWithIds,
        logoSlots: logoSlots || { enabled: false, slots: [] },
        palette: palette || {},
        typography: typography || {},
        defaultAiPromptHints: defaultAiPromptHints || {},
        metadata: {
          ...metadata,
          author: req.user?.name || 'System'
        },
        userId: req.user?._id
      });

      await template.save();

      res.status(201).json({
        success: true,
        data: template
      });
    } catch (error) {
      console.error('Template create error:', error);
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // GET /templates
  async list(req, res) {
    try {
      const { 
        type, 
        search, 
        tags, 
        page = 1, 
        limit = 20,
        sortBy = 'createdAt',
        sortOrder = 'desc'
      } = req.query;

      const query = { isActive: true };

      if (type) {
        query.templateType = type;
      }

      if (tags) {
        const tagArray = tags.split(',').map(t => t.trim());
        query['metadata.tags'] = { $in: tagArray };
      }

      if (search) {
        query.$text = { $search: search };
      }

      // Se utente autenticato, mostra anche i suoi privati
      if (req.user) {
        query.$or = [
          { 'metadata.isPublic': true },
          { userId: req.user._id }
        ];
      } else {
        query['metadata.isPublic'] = true;
      }

      const sort = { [sortBy]: sortOrder === 'asc' ? 1 : -1 };

      const [templates, total] = await Promise.all([
        Template.find(query)
          .sort(sort)
          .skip((page - 1) * limit)
          .limit(parseInt(limit))
          .select('-layers -logoSlots'), // Escludi dati pesanti per list
        Template.countDocuments(query)
      ]);

      res.json({
        success: true,
        data: templates,
        pagination: {
          page: parseInt(page),
          limit: parseInt(limit),
          total,
          pages: Math.ceil(total / limit)
        }
      });
    } catch (error) {
      console.error('Template list error:', error);
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // GET /templates/types
  async getTypes(req, res) {
    try {
      const types = await Template.distinct('templateType', { isActive: true });
      
      res.json({
        success: true,
        data: types.sort()
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // GET /templates/presets
  async getFormatPresets(req, res) {
    res.json({
      success: true,
      data: FORMAT_PRESETS
    });
  },

  // GET /templates/:id
  async getById(req, res) {
    try {
      const template = await Template.findById(req.params.id);

      if (!template) {
        return res.status(404).json({ 
          success: false, 
          error: 'Template non trovato' 
        });
      }

      // Check accesso
      if (!template.metadata.isPublic && 
          (!req.user || template.userId?.toString() !== req.user._id.toString())) {
        return res.status(403).json({ 
          success: false, 
          error: 'Accesso negato' 
        });
      }

      res.json({
        success: true,
        data: template
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // PUT /templates/:id
  async update(req, res) {
    try {
      const template = await Template.findById(req.params.id);

      if (!template) {
        return res.status(404).json({ 
          success: false, 
          error: 'Template non trovato' 
        });
      }

      // Check ownership
      if (template.userId?.toString() !== req.user._id.toString()) {
        return res.status(403).json({ 
          success: false, 
          error: 'Non autorizzato a modificare questo template' 
        });
      }

      const updateFields = [
        'name', 'description', 'templateType', 'format', 'safeArea',
        'backgroundColor', 'layers', 'logoSlots', 'palette', 
        'typography', 'defaultAiPromptHints', 'metadata', 'isActive'
      ];

      updateFields.forEach(field => {
        if (req.body[field] !== undefined) {
          template[field] = req.body[field];
        }
      });

      // Incrementa versione
      if (template.metadata) {
        const version = template.metadata.version || '1.0.0';
        const parts = version.split('.').map(Number);
        parts[2]++;
        template.metadata.version = parts.join('.');
      }

      await template.save();

      res.json({
        success: true,
        data: template
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // DELETE /templates/:id
  async delete(req, res) {
    try {
      const template = await Template.findById(req.params.id);

      if (!template) {
        return res.status(404).json({ 
          success: false, 
          error: 'Template non trovato' 
        });
      }

      if (template.userId?.toString() !== req.user._id.toString()) {
        return res.status(403).json({ 
          success: false, 
          error: 'Non autorizzato' 
        });
      }

      // Soft delete
      template.isActive = false;
      await template.save();

      res.json({
        success: true,
        message: 'Template eliminato'
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // POST /templates/:id/duplicate
  async duplicate(req, res) {
    try {
      const original = await Template.findById(req.params.id);

      if (!original) {
        return res.status(404).json({ 
          success: false, 
          error: 'Template non trovato' 
        });
      }

      const duplicateData = original.toObject();
      delete duplicateData._id;
      delete duplicateData.createdAt;
      delete duplicateData.updatedAt;

      duplicateData.name = `${original.name} (copia)`;
      duplicateData.userId = req.user._id;
      duplicateData.metadata = {
        ...duplicateData.metadata,
        isPublic: false,
        usageCount: 0,
        author: req.user?.name || 'System',
        version: '1.0.0'
      };

      const duplicate = new Template(duplicateData);
      await duplicate.save();

      res.status(201).json({
        success: true,
        data: duplicate
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  },

  // GET /templates/:id/preview
  async getPreview(req, res) {
    try {
      const template = await Template.findById(req.params.id)
        .select('previewUrl thumbnailUrl name');

      if (!template) {
        return res.status(404).json({ 
          success: false, 
          error: 'Template non trovato' 
        });
      }

      res.json({
        success: true,
        data: {
          previewUrl: template.previewUrl,
          thumbnailUrl: template.thumbnailUrl,
          name: template.name
        }
      });
    } catch (error) {
      res.status(500).json({ 
        success: false, 
        error: error.message 
      });
    }
  }
};

module.exports = templateController;