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

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

const assetController = {
  // POST /assets/upload
  async upload(req, res) {
    try {
      if (!req.file) {
        return res.status(400).json({
          success: false,
          error: 'Nessun file caricato'
        });
      }

      const { category = 'other', tags, description, isReusable = true } = req.body;
      const file = req.file;

      // Ottieni dimensioni immagine
      let dimensions = {};
      try {
        const metadata = await sharp(file.path).metadata();
        dimensions = { width: metadata.width, height: metadata.height };
      } catch (e) {
        console.warn('Cannot read image dimensions');
      }

      // Genera thumbnail
      const thumbDir = path.join(UPLOAD_DIR, 'thumbs');
      await fs.mkdir(thumbDir, { recursive: true });
      const thumbName = `thumb_${file.filename}`;
      const thumbPath = path.join(thumbDir, thumbName);

      try {
        await sharp(file.path)
          .resize(300, 300, { fit: 'cover' })
          .jpeg({ quality: 80 })
          .toFile(thumbPath);
      } catch (e) {
        console.warn('Cannot create thumbnail');
      }

      const asset = new Asset({
        type: 'image',
        category,
        sourceType: 'upload',
        file: {
          path: file.path,
          url: `/upload/${file.filename}`,
          thumbnailPath: thumbPath,
          thumbnailUrl: `/upload/thumbs/${thumbName}`,
          originalName: file.originalname,
          mimeType: file.mimetype,
          size: file.size,
          dimensions
        },
        metadata: {
          userId: req.user._id,
          tags: tags ? tags.split(',').map(t => t.trim()) : [],
          description,
          isReusable: isReusable === 'true' || isReusable === true
        }
      });

      await asset.save();

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

  // POST /assets/upload-multiple
  async uploadMultiple(req, res) {
    try {
      if (!req.files || req.files.length === 0) {
        return res.status(400).json({
          success: false,
          error: 'Nessun file caricato'
        });
      }

      const { category = 'other' } = req.body;
      const assets = [];

      for (const file of req.files) {
        let dimensions = {};
        try {
          const metadata = await sharp(file.path).metadata();
          dimensions = { width: metadata.width, height: metadata.height };
        } catch (e) {}

        const asset = new Asset({
          type: 'image',
          category,
          sourceType: 'upload',
          file: {
            path: file.path,
            url: `/upload/${file.filename}`,
            originalName: file.originalname,
            mimeType: file.mimetype,
            size: file.size,
            dimensions
          },
          metadata: {
            userId: req.user._id
          }
        });

        await asset.save();
        assets.push(asset);
      }

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

  // POST /assets/generate-ai
  async generateAi(req, res) {
    try {
      const {
        prompt,
        negativePrompt,
        provider = 'hf',
        category = 'other',
        aspectRatio = '9:16',
        model,
        seed,
        steps,
        cfg
      } = req.body;

      if (!prompt) {
        return res.status(400).json({
          success: false,
          error: 'Prompt richiesto'
        });
      }

      const startTime = Date.now();
      const imageUrl = await imageGenerator.generate(provider, prompt, {
        negativePrompt,
        aspectRatio,
        model,
        seed,
        steps,
        cfg
      });
      const generationTime = Date.now() - startTime;

      // Salva file
      const fileName = `ai_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`;
      const filePath = path.join(UPLOAD_DIR, 'ai-generated', fileName);
      await fs.mkdir(path.dirname(filePath), { recursive: true });

      let fileSize = 0;
      let dimensions = {};

      if (imageUrl.startsWith('data:')) {
        const base64Data = imageUrl.replace(/^data:image\/\w+;base64,/, '');
        const buffer = Buffer.from(base64Data, 'base64');
        await fs.writeFile(filePath, buffer);
        fileSize = buffer.length;

        const metadata = await sharp(buffer).metadata();
        dimensions = { width: metadata.width, height: metadata.height };
      } else {
        const fetch = require('node-fetch');
        const response = await fetch(imageUrl);
        const buffer = await response.buffer();
        await fs.writeFile(filePath, buffer);
        fileSize = buffer.length;

        const metadata = await sharp(buffer).metadata();
        dimensions = { width: metadata.width, height: metadata.height };
      }

      const asset = new Asset({
        type: 'image',
        category,
        sourceType: 'ai',
        file: {
          path: filePath,
          url: `/upload/ai-generated/${fileName}`,
          mimeType: 'image/jpeg',
          size: fileSize,
          dimensions
        },
        aiGeneration: {
          prompt,
          negativePrompt,
          provider,
          model,
          seed,
          steps,
          cfg,
          requestedSize: aspectRatio,
          generationTime
        },
        metadata: {
          userId: req.user._id,
          isReusable: true
        }
      });

      await asset.save();

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

  // GET /assets
  async list(req, res) {
    try {
      const {
        category,
        sourceType,
        page = 1,
        limit = 50
      } = req.query;

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

      if (category) query.category = category;
      if (sourceType) query.sourceType = sourceType;

      const [assets, total] = await Promise.all([
        Asset.find(query)
          .sort({ createdAt: -1 })
          .skip((page - 1) * limit)
          .limit(parseInt(limit)),
        Asset.countDocuments(query)
      ]);

      res.json({
        success: true,
        data: assets,
        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 /assets/:id
  async getById(req, res) {
    try {
      const asset = await Asset.findById(req.params.id);

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

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

  // GET /assets/:id/file
  async getFile(req, res) {
    try {
      const asset = await Asset.findById(req.params.id);

      if (!asset || !asset.file?.path) {
        return res.status(404).json({
          success: false,
          error: 'File non trovato'
        });
      }

      res.sendFile(path.resolve(asset.file.path));
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // GET /assets/:id/thumbnail
  async getThumbnail(req, res) {
    try {
      const asset = await Asset.findById(req.params.id);

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

      const thumbPath = asset.file?.thumbnailPath || asset.file?.path;
      if (!thumbPath) {
        return res.status(404).json({
          success: false,
          error: 'Thumbnail non disponibile'
        });
      }

      res.sendFile(path.resolve(thumbPath));
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message
      });
    }
  },

  // DELETE /assets/:id
  async delete(req, res) {
    try {
      const asset = await Asset.findById(req.params.id);

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

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

      // Elimina file
      try {
        if (asset.file?.path) await fs.unlink(asset.file.path);
        if (asset.file?.thumbnailPath) await fs.unlink(asset.file.thumbnailPath);
      } catch (e) {
        console.warn('File deletion warning:', e.message);
      }

      await Asset.deleteOne({ _id: asset._id });

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

module.exports = assetController;