import express from 'express';
import multer from 'multer';
import path from 'node:path';
import fs from 'node:fs';
import { requirePermission } from '../../shared/auth/middleware.js';

const router = express.Router();

// Phase 6.2: uploads + deletions of reusable images require image_admin.
router.use((req, res, next) => {
  if (req.method === 'GET' || req.method === 'HEAD' || req.method === 'OPTIONS') return next();
  return requirePermission('image_admin')(req, res, next);
});

// Create reusable uploads directory if it doesn't exist
const uploadsDir = path.join('/var/www/inventory/uploads/reusable');
fs.mkdirSync(uploadsDir, { recursive: true });

// Configure multer for file uploads
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    console.log(`Saving reusable image to: ${uploadsDir}`);
    cb(null, uploadsDir);
  },
  filename: function (req, file, cb) {
    // Create unique filename with original extension
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    
    // Make sure we preserve the original file extension
    let fileExt = path.extname(file.originalname).toLowerCase();
    
    // Ensure there is a proper extension based on mimetype if none exists
    if (!fileExt) {
      switch (file.mimetype) {
        case 'image/jpeg': fileExt = '.jpg'; break;
        case 'image/png': fileExt = '.png'; break;
        case 'image/gif': fileExt = '.gif'; break;
        case 'image/webp': fileExt = '.webp'; break;
        default: fileExt = '.jpg'; // Default to jpg
      }
    }
    
    const fileName = `reusable-${uniqueSuffix}${fileExt}`;
    console.log(`Generated filename: ${fileName} with mimetype: ${file.mimetype}`);
    cb(null, fileName);
  }
});

// Phase 6.7: exact-match MIME + extension allowlist.
const ALLOWED_MIME_TYPES = new Set([
  'image/jpeg', 'image/png', 'image/gif', 'image/webp',
]);
const ALLOWED_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.webp']);

const upload = multer({
  storage: storage,
  limits: {
    fileSize: 5 * 1024 * 1024,
    files: 1,
  },
  fileFilter: function (req, file, cb) {
    const ext = path.extname(file.originalname).toLowerCase();
    if (!ALLOWED_MIME_TYPES.has(file.mimetype) || !ALLOWED_EXTENSIONS.has(ext)) {
      return cb(new Error('Only image files are allowed (jpg, png, gif, webp)'));
    }
    cb(null, true);
  }
});

// Get all reusable images
router.get('/', async (req, res) => {
  try {
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    const result = await pool.query(`
      SELECT * FROM reusable_images 
      ORDER BY created_at DESC
    `);
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching reusable images:', error);
    res.status(500).json({ 
      error: 'Failed to fetch reusable images',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Get images by company or global images
router.get('/by-company/:companyId', async (req, res) => {
  try {
    const { companyId } = req.params;
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    // Get images that are either global or belong to this company
    const result = await pool.query(`
      SELECT * FROM reusable_images 
      WHERE is_global = true OR company = $1
      ORDER BY created_at DESC
    `, [companyId]);
    
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching reusable images by company:', error);
    res.status(500).json({ 
      error: 'Failed to fetch reusable images by company',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Get global images only
router.get('/global', async (req, res) => {
  try {
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    const result = await pool.query(`
      SELECT * FROM reusable_images 
      WHERE is_global = true
      ORDER BY created_at DESC
    `);
    
    res.json(result.rows);
  } catch (error) {
    console.error('Error fetching global reusable images:', error);
    res.status(500).json({ 
      error: 'Failed to fetch global reusable images',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Get a single image by ID
router.get('/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    const result = await pool.query(`
      SELECT * FROM reusable_images 
      WHERE id = $1
    `, [id]);

    if (result.rows.length === 0) {
      return res.status(404).json({ error: 'Reusable image not found' });
    }

    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error fetching reusable image:', error);
    res.status(500).json({ 
      error: 'Failed to fetch reusable image',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Upload a new reusable image
router.post('/upload', upload.single('image'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: 'No image file provided' });
    }

    const { name, is_global, company } = req.body;
    
    // Validate required fields
    if (!name) {
      return res.status(400).json({ error: 'Image name is required' });
    }
    
    // Convert is_global from string to boolean
    const isGlobal = is_global === 'true' || is_global === true;
    
    // Validate company is provided for non-global images
    if (!isGlobal && !company) {
      return res.status(400).json({ error: 'Company is required for non-global images' });
    }

    // Log file information
    console.log('Reusable image uploaded:', {
      filename: req.file.filename,
      originalname: req.file.originalname,
      mimetype: req.file.mimetype,
      size: req.file.size,
      path: req.file.path
    });

    // Ensure the file exists
    const filePath = path.join(uploadsDir, req.file.filename);
    if (!fs.existsSync(filePath)) {
      return res.status(500).json({ error: 'File was not saved correctly' });
    }

    // Create URL for the uploaded file
    const baseUrl = 'https://tools.acherryontop.com';
    const imageUrl = `${baseUrl}/uploads/reusable/${req.file.filename}`;
    
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    // Insert record into database
    const result = await pool.query(`
      INSERT INTO reusable_images (
        name,
        filename,
        file_path,
        image_url,
        is_global,
        company,
        mime_type,
        file_size
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
      RETURNING *
    `, [
      name,
      req.file.filename,
      filePath,
      imageUrl,
      isGlobal,
      isGlobal ? null : company,
      req.file.mimetype,
      req.file.size
    ]);

    // Return success response with image data
    res.status(201).json({
      success: true,
      image: result.rows[0],
      message: 'Image uploaded successfully'
    });
    
  } catch (error) {
    console.error('Error uploading reusable image:', error);
    res.status(500).json({ error: error.message || 'Failed to upload image' });
  }
});

// Update image details (name, is_global, company)
router.put('/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const { name, is_global, company } = req.body;
    
    // Validate required fields
    if (!name) {
      return res.status(400).json({ error: 'Image name is required' });
    }
    
    // Convert is_global from string to boolean if necessary
    const isGlobal = typeof is_global === 'string' ? is_global === 'true' : !!is_global;
    
    // Validate company is provided for non-global images
    if (!isGlobal && !company) {
      return res.status(400).json({ error: 'Company is required for non-global images' });
    }
    
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    // Check if the image exists
    const checkResult = await pool.query('SELECT * FROM reusable_images WHERE id = $1', [id]);
    if (checkResult.rows.length === 0) {
      return res.status(404).json({ error: 'Reusable image not found' });
    }
    
    const result = await pool.query(`
      UPDATE reusable_images 
      SET 
        name = $1,
        is_global = $2,
        company = $3
      WHERE id = $4
      RETURNING *
    `, [
      name,
      isGlobal,
      isGlobal ? null : company,
      id
    ]);

    res.json(result.rows[0]);
  } catch (error) {
    console.error('Error updating reusable image:', error);
    res.status(500).json({ 
      error: 'Failed to update reusable image',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Delete a reusable image
router.delete('/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const pool = req.app.locals.pool;
    if (!pool) {
      throw new Error('Database pool not initialized');
    }
    
    // Get the image data first to get the filename
    const imageResult = await pool.query('SELECT * FROM reusable_images WHERE id = $1', [id]);
    
    if (imageResult.rows.length === 0) {
      return res.status(404).json({ error: 'Reusable image not found' });
    }
    
    const image = imageResult.rows[0];
    
    // Delete from database
    await pool.query('DELETE FROM reusable_images WHERE id = $1', [id]);
    
    // Delete the file from filesystem
    const filePath = path.join(uploadsDir, image.filename);
    if (fs.existsSync(filePath)) {
      fs.unlinkSync(filePath);
    }

    res.json({ 
      message: 'Reusable image deleted successfully',
      image
    });
  } catch (error) {
    console.error('Error deleting reusable image:', error);
    res.status(500).json({ 
      error: 'Failed to delete reusable image',
      details: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

// Check if file exists and permissions
router.get('/check-file/:filename', (req, res) => {
  const { filename } = req.params;
  
  // Prevent directory traversal
  if (filename.includes('..') || filename.includes('/')) {
    return res.status(400).json({ error: 'Invalid filename' });
  }
  
  const filePath = path.join(uploadsDir, filename);
  
  try {
    // Check if file exists
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ 
        error: 'File not found', 
        path: filePath,
        exists: false,
        readable: false 
      });
    }
    
    // Check if file is readable
    fs.accessSync(filePath, fs.constants.R_OK);
    
    // Get file stats
    const stats = fs.statSync(filePath);
    
    return res.json({
      filename,
      path: filePath,
      exists: true,
      readable: true,
      isFile: stats.isFile(),
      isDirectory: stats.isDirectory(),
      size: stats.size,
      created: stats.birthtime,
      modified: stats.mtime,
      permissions: stats.mode.toString(8)
    });
  } catch (error) {
    return res.status(500).json({ 
      error: error.message,
      path: filePath,
      exists: fs.existsSync(filePath),
      readable: false
    });
  }
});

// Error handling middleware
router.use((err, req, res, next) => {
  console.error('Reusable images route error:', err);
  res.status(500).json({ 
    error: 'Internal server error',
    details: err.message
  });
});

export default router;
