const Poster = require('../models/Poster');
const Template = require('../models/Template');
const Asset = require('../models/Asset');
const posterRenderer = require('../services/posterRenderer');
const imageGenerator = require('../services/imageGenerator');
const path = require('path');
const fs = require('fs').promises;

const UPLOAD_DIR = process.env.UPLOAD_DIR || './upload';

const posterController = {
  // POST /posters
  async create(req, res) {
    try {
      const {
        templateId,
        name,
        description,
        content,
        assets,
        layerOverrides,
        autoRender = false
      } = req.body;

      // Carica template
      const template = await Template.findById(templateId);
      if (!template) {
        return res.status(404).json({
          success: false,
          error: 'Template non trovato'
        });
      }

      // Valida contenuti richiesti
      const requiredLayers = template.layers.filter(l => l.required);
      for (const layer of requiredLayers) {
        if (layer.type === 'title' && !content?.title) {
          return res.status(400).json({
            success: false,
            error: `Campo richiesto: ${layer.type}`
          });
        }
      }

      const poster = new Poster({
        templateId,
        templateSnapshot: template.toObject(), // Snapshot per retrocompatibilità
        name: name || content?.title || 'Nuova Locandina',
        description,
        status: 'draft',
        content: content || {},
        assets: assets || {},
        layerOverrides: layerOverrides || {},
        renderEngineVersion: '1.0.0',
        metadata: {
          userId: req.user._id
        }
      });

      await poster.save();

      // Incrementa uso template
      await template.incrementUsage();

      // Auto-render se richiesto
      if (autoRender) {
        await posterController._renderPoster(poster);
        await poster.save();
      }

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

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

      const query = { 'metadata.userId': req.user._id };

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

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

      const [posters, total] = await Promise.all([
        Poster.find(query)
          .populate('templateId', 'name templateType thumbnailUrl')
          .sort(sort)
          .skip((page - 1) * limit)
          .limit(parseInt(limit))
          .select('-templateSnapshot -history'),
        Poster.countDocuments(query)
      ]);

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

  // GET /posters/favorites
  async listFavorites(req, res) {
    try {
      const posters = await Poster.findFavorites(req.user._id);
      
      res.json({
        success: true,
        data: posters
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // GET /posters/recent
  async listRecent(req, res) {
    try {
      const { limit = 10 } = req.query;
      const posters = await Poster.findRecent(req.user._id, parseInt(limit));
      
      res.json({
        success: true,
        data: posters
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // GET /posters/:id
  async getById(req, res) {
    try {
      const poster = await Poster.findById(req.params.id)
        .populate('templateId')
        .populate('assets.backgroundImage.assetId')
        .populate('assets.mainImage.assetId')
        .populate('assets.logos.assetId');

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

      // Check ownership
      if (poster.metadata.userId.toString() !== req.user._id.toString()) {
        return res.status(403).json({
          success: false,
          error: 'Accesso negato'
        });
      }

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

  // PUT /posters/:id
  async update(req, res) {
    try {
      const poster = await Poster.findById(req.params.id);

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

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

      const updateFields = [
        'name', 'description', 'content', 'assets', 'layerOverrides'
      ];

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

      // Invalida render precedente se contenuto modificato
      if (req.body.content || req.body.assets || req.body.layerOverrides) {
        poster.status = 'draft';
        poster.addHistory('updated', { fields: Object.keys(req.body) });
      }

      await poster.save();

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

  // DELETE /posters/:id
  async delete(req, res) {
    try {
      const poster = await Poster.findById(req.params.id);

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

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

      // Elimina file renderizzati
      if (poster.renderOutput) {
        const filesToDelete = [
          poster.renderOutput.png?.path,
          poster.renderOutput.jpg?.path,
          poster.renderOutput.webp?.path
        ].filter(Boolean);

        for (const filePath of filesToDelete) {
          try {
            await fs.unlink(filePath);
          } catch (e) {
            console.warn('File not found:', filePath);
          }
        }
      }

      await Poster.deleteOne({ _id: poster._id });

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

  // POST /posters/:id/render
  async render(req, res) {
    try {
      const poster = await Poster.findById(req.params.id)
        .populate('templateId');

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

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

      poster.status = 'processing';
      await poster.save();

      try {
        await posterController._renderPoster(poster);
        await poster.save();

        res.json({
          success: true,
          data: {
            status: poster.status,
            renderOutput: poster.renderOutput
          }
        });
      } catch (renderError) {
        poster.setError(renderError.message);
        await poster.save();
        throw renderError;
      }
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // POST /posters/:id/regenerate-ai
  async regenerateAi(req, res) {
    try {
      const { assetType, prompt, provider = 'hf' } = req.body;
      const poster = await Poster.findById(req.params.id);

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

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

      // Genera nuova immagine AI
      const startTime = Date.now();
      const imageUrl = await imageGenerator.generate(provider, prompt);
      const generationTime = Date.now() - startTime;

      // Salva su filesystem
      const fileName = `${poster._id}_${assetType}_${Date.now()}.jpg`;
      const filePath = path.join(UPLOAD_DIR, 'ai-generated', fileName);
      
      await fs.mkdir(path.dirname(filePath), { recursive: true });
      
      // Se è base64, converti
      let savedPath;
      if (imageUrl.startsWith('data:')) {
        const base64Data = imageUrl.replace(/^data:image\/\w+;base64,/, '');
        await fs.writeFile(filePath, base64Data, 'base64');
        savedPath = filePath;
      } else {
        // Se è URL, scarica
        const fetch = require('node-fetch');
        const response = await fetch(imageUrl);
        const buffer = await response.buffer();
        await fs.writeFile(filePath, buffer);
        savedPath = filePath;
      }

      // Aggiorna asset nel poster
      const assetData = {
        sourceType: 'ai',
        url: `/upload/ai-generated/${fileName}`,
        mimeType: 'image/jpeg',
        aiParams: {
          prompt,
          provider,
          generatedAt: new Date()
        }
      };

      if (assetType === 'backgroundImage') {
        poster.assets.backgroundImage = assetData;
        poster.addHistory('ai_background_generated', { provider, duration: generationTime });
      } else if (assetType === 'mainImage') {
        poster.assets.mainImage = assetData;
        poster.addHistory('ai_main_generated', { provider, duration: generationTime });
      }

      poster.status = 'draft';
      await poster.save();

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

  // GET /posters/:id/download/:format
  async download(req, res) {
    try {
      const { format } = req.params;
      const poster = await Poster.findById(req.params.id);

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

      const outputFile = poster.renderOutput?.[format];
      if (!outputFile?.path) {
        return res.status(404).json({
          success: false,
          error: `Formato ${format} non disponibile`
        });
      }

      // Incrementa download count
      await poster.incrementDownload();

      const fileName = `${poster.name.replace(/[^a-z0-9]/gi, '_')}_poster.${format}`;
      
      res.download(outputFile.path, fileName);
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // POST /posters/:id/favorite
  async toggleFavorite(req, res) {
    try {
      const poster = await Poster.findById(req.params.id);

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

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

      await poster.toggleFavorite();

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

  // POST /posters/quick-generate (compatibile con la tua bozza)
  async quickGenerate(req, res) {
    try {
      const {
        templateId,
        titolo,
        descrizione,
        data,
        ora,
        luogo,
        contatti,
        fotoDescrizione,
        stile,
        provider = 'hf',
        aspectRatio = '9:16'
      } = req.body;

      // Validazione base
      if (!titolo || !data || !luogo) {
        return res.status(400).json({
          success: false,
          error: 'Compila titolo, data e luogo'
        });
      }

      // Usa template default o quello specificato
      let template;
      if (templateId) {
        template = await Template.findById(templateId);
      } else {
        // Template default per quick-generate
        template = await Template.findOne({ 
          templateType: 'quick-generate',
          isActive: true 
        });
      }

      // Genera prompt per AI background
      const aiPrompt = `Vertical event poster background, ${stile || 'modern style, vivid colors'}. Subject: ${fotoDescrizione || 'abstract artistic shapes'}. Composition: Central empty space suitable for text overlay. NO TEXT, NO LETTERS, clean illustration, high quality, 4k.`;

      // Genera immagine AI
      const startTime = Date.now();
      const rawImageUrl = await imageGenerator.generate(provider, aiPrompt);
      const generationTime = Date.now() - startTime;

      // Salva asset generato
      const fileName = `quick_${Date.now()}.jpg`;
      const filePath = path.join(UPLOAD_DIR, 'ai-generated', fileName);
      await fs.mkdir(path.dirname(filePath), { recursive: true });

      if (rawImageUrl.startsWith('data:')) {
        const base64Data = rawImageUrl.replace(/^data:image\/\w+;base64,/, '');
        await fs.writeFile(filePath, base64Data, 'base64');
      }

      // Crea poster
      const poster = new Poster({
        templateId: template?._id,
        name: titolo,
        status: 'processing',
        content: {
          title: titolo,
          subtitle: descrizione,
          eventDate: data,
          eventTime: ora,
          location: luogo,
          contacts: contatti
        },
        assets: {
          backgroundImage: {
            sourceType: 'ai',
            url: `/upload/ai-generated/${fileName}`,
            mimeType: 'image/jpeg',
            aiParams: {
              prompt: aiPrompt,
              provider,
              generatedAt: new Date()
            }
          }
        },
        originalPrompt: aiPrompt,
        styleUsed: stile,
        aspectRatio,
        provider,
        metadata: {
          userId: req.user._id
        }
      });

      poster.addHistory('ai_background_generated', { provider, duration: generationTime });

      // Render con testi sovrapposti
      await posterController._renderPoster(poster, { useQuickRender: true });
      await poster.save();

      res.json({
        success: true,
        data: {
          posterId: poster._id,
          imageUrl: poster.renderOutput?.png?.url || rawImageUrl,
          status: poster.status
        }
      });
    } catch (error) {
      console.error('Quick generate error:', error);
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // Helper interno: renderizza poster
  async _renderPoster(poster, options = {}) {
    const template = poster.templateId || poster.templateSnapshot;
    
    const result = await posterRenderer.render({
      template,
      content: poster.content,
      assets: poster.assets,
      layerOverrides: Object.fromEntries(poster.layerOverrides || new Map()),
      outputDir: path.join(UPLOAD_DIR, 'posters', 'final'),
      posterId: poster._id.toString()
    });

    poster.setRenderOutput({
      png: {
        path: result.pngPath,
        url: `/upload/posters/final/${path.basename(result.pngPath)}`,
        size: result.pngSize
      },
      jpg: {
        path: result.jpgPath,
        url: `/upload/posters/final/${path.basename(result.jpgPath)}`,
        size: result.jpgSize,
        quality: 95
      },
      dimensions: result.dimensions,
      duration: result.duration
    });
  }
};

module.exports = posterController;