const db = require('../models');
const { sendResponse, sendError } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const { uploadDrawing, getFileUrl, getFilePath } = require('../middlewares/uploadMiddleware');
const path = require('path');
const fs = require('fs');

/**
 * Upload drawing for a material
 */
exports.uploadDrawing = asyncHandler(async (req, res) => {
  uploadDrawing(req, res, async (err) => {
    if (err) {
      return sendError(res, err.message, 400);
    }

    if (!req.file) {
      return sendError(res, 'No file uploaded', 400);
    }

    const { material_id, drawing_number, revision_number } = req.body;

    if (!material_id) {
      // Delete uploaded file if material_id is missing
      if (req.file.path) {
        fs.unlinkSync(req.file.path);
      }
      return sendError(res, 'Material ID is required', 400);
    }

    try {
      // Find the material
      const material = await db.Material.findByPk(material_id);
      if (!material) {
        // Delete uploaded file if material not found
        if (req.file.path) {
          fs.unlinkSync(req.file.path);
        }
        return sendError(res, 'Material not found', 404);
      }

      // Delete old drawing file if exists
      if (material.drawing_file_path) {
        const oldFilePath = getFilePath(material.drawing_file_path);
        if (fs.existsSync(oldFilePath)) {
          fs.unlinkSync(oldFilePath);
        }
      }

      // Calculate relative path from uploads directory
      const uploadsDir = path.join(__dirname, '../uploads');
      const relativePath = path.relative(uploadsDir, req.file.path).replace(/\\/g, '/');

      console.log('Upload Drawing - File Info:');
      console.log('  Original name:', req.file.originalname);
      console.log('  Saved filename:', req.file.filename);
      console.log('  Full path:', req.file.path);
      console.log('  Relative path:', relativePath);

      // Update material with drawing information
      await material.update({
        drawing_number: drawing_number || material.drawing_number || null,
        revision_number: revision_number || material.revision_number || null,
        drawing_file_path: relativePath,
        drawing_file_name: req.file.filename, // Use actual filename, not original
        drawing_file_size: req.file.size,
        drawing_file_type: req.file.mimetype,
        updated_by: req.user?.userId || null,
      });

      sendResponse(res, 200, true, 'Drawing uploaded successfully', {
        material_id: material.id,
        drawing_number: material.drawing_number,
        revision_number: material.revision_number,
        file_url: getFileUrl(req.file.path),
        file_name: req.file.originalname,
        file_size: req.file.size,
        file_type: req.file.mimetype,
      });
    } catch (error) {
      // Delete uploaded file on error
      if (req.file.path) {
        fs.unlinkSync(req.file.path);
      }
      throw error;
    }
  });
});

/**
 * Get drawing file for a material
 */
exports.getDrawing = asyncHandler(async (req, res) => {
  const { material_id } = req.params;

  const material = await db.Material.findByPk(material_id, {
    attributes: ['id', 'material_number', 'drawing_file_path', 'drawing_file_name', 'drawing_file_type']
  });

  if (!material) {
    return sendError(res, 'Material not found', 404);
  }

  if (!material.drawing_file_path) {
    return sendError(res, 'No drawing file found for this material', 404);
  }

  // Normalize the path - remove leading /uploads if present
  let normalizedPath = material.drawing_file_path;
  if (normalizedPath.startsWith('/uploads/')) {
    normalizedPath = normalizedPath.substring('/uploads/'.length);
  } else if (normalizedPath.startsWith('uploads/')) {
    normalizedPath = normalizedPath.substring('uploads/'.length);
  }

  const filePath = getFilePath(normalizedPath);

  console.log('Drawing request for material:', material_id);
  console.log('DB path:', material.drawing_file_path);
  console.log('Normalized path:', normalizedPath);
  console.log('Full file path:', filePath);
  console.log('File exists:', fs.existsSync(filePath));

  if (!fs.existsSync(filePath)) {
    console.error('Drawing file not found at:', filePath);
    return sendError(res, `Drawing file not found on server. Path: ${normalizedPath}`, 404);
  }

  // Set appropriate headers
  res.setHeader('Content-Type', material.drawing_file_type || 'application/octet-stream');
  res.setHeader('Content-Disposition', `inline; filename="${material.drawing_file_name || 'drawing'}"`);

  // Send file
  res.sendFile(filePath);
});

/**
 * Delete drawing for a material
 */
exports.deleteDrawing = asyncHandler(async (req, res) => {
  const { material_id } = req.params;

  const material = await db.Material.findByPk(material_id);

  if (!material) {
    return sendError(res, 'Material not found', 404);
  }

  if (!material.drawing_file_path) {
    return sendError(res, 'No drawing file found for this material', 404);
  }

  // Delete file from filesystem
  const filePath = getFilePath(material.drawing_file_path);
  if (fs.existsSync(filePath)) {
    fs.unlinkSync(filePath);
  }

  // Update material to remove drawing information
  await material.update({
    drawing_number: null,
    revision_number: null,
    drawing_file_path: null,
    drawing_file_name: null,
    drawing_file_size: null,
    drawing_file_type: null,
    updated_by: req.user?.userId || null,
  });

  sendResponse(res, 200, true, 'Drawing deleted successfully', null);
});

