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

/**
 * Upload logo for print header
 */
exports.uploadLogo = asyncHandler(async (req, res) => {
  uploadPrintHeaderLogo(req, res, async (err) => {
    if (err) {
      return sendError(res, err.message, 400);
    }

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

    const { header_id, file_type } = req.body;
    const headerId = req.params.header_id || header_id;

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

    try {
      // Find the print header
      const printHeader = await db.PrintHeader.findByPk(headerId);
      if (!printHeader) {
        // Delete uploaded file if header not found
        if (req.file.path) {
          fs.unlinkSync(req.file.path);
        }
        return sendError(res, 'Print Header not found', 404);
      }

      const fileType = file_type || 'logo';
      const isLogo = fileType === 'logo';
      const isCertification = fileType === 'certification';

      // Delete old file if exists
      if (isLogo && printHeader.logo_path) {
        const oldFilePath = getFilePath(printHeader.logo_path);
        if (fs.existsSync(oldFilePath)) {
          fs.unlinkSync(oldFilePath);
        }
      }
      if (isCertification && printHeader.quality_certification_logo_path) {
        const oldFilePath = getFilePath(printHeader.quality_certification_logo_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, '/');

      // Update print header with file information
      const updateData = {
        updated_by: req.user?.userId || null,
      };

      if (isLogo) {
        updateData.logo_path = relativePath;
        updateData.logo_file_name = req.file.originalname;
      } else if (isCertification) {
        updateData.quality_certification_logo_path = relativePath;
        updateData.quality_certification_logo_file_name = req.file.originalname;
      }

      await printHeader.update(updateData);

      // Construct file URL
      // Use configured base URL (without /api/v1 for static files)
      let baseUrl = process.env.API_BASE_URL || process.env.BASE_URL || 'http://localhost:5006';
      // Remove /api/v1 if present to get the base server URL for static files
      baseUrl = baseUrl.replace(/\/api\/v1$/, '');
      
      // Ensure baseUrl has protocol
      if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {
        baseUrl = `http://${baseUrl}`;
      }
      
      const fileUrl = relativePath.startsWith('/uploads') 
        ? `${baseUrl}${relativePath}` 
        : `${baseUrl}/uploads/${relativePath}`;

      sendResponse(res, 200, true, `${fileType === 'logo' ? 'Logo' : 'Certification logo'} uploaded successfully`, {
        header_id: printHeader.id,
        file_url: fileUrl,
        file_name: req.file.originalname,
        file_size: req.file.size,
        file_type: req.file.mimetype,
        file_path: relativePath,
      });
    } catch (error) {
      // Delete uploaded file on error
      if (req.file.path) {
        fs.unlinkSync(req.file.path);
      }
      throw error;
    }
  });
});

/**
 * Get print header for printing
 */
exports.getPrintHeader = asyncHandler(async (req, res) => {
  const { id } = req.params;

  const printHeader = await db.PrintHeader.findByPk(id, {
    include: [
      {
        model: db.Company,
        as: 'company',
        attributes: ['id', 'code', 'name']
      }
    ]
  });

  if (!printHeader) {
    return sendError(res, 'Print Header not found', 404);
  }

  // Convert file paths to URLs
  // Use request origin or configured base URL (without /api/v1 for static files)
  let baseUrl = process.env.API_BASE_URL || process.env.BASE_URL || 'http://localhost:5006';
  // Remove /api/v1 if present to get the base server URL for static files
  baseUrl = baseUrl.replace(/\/api\/v1$/, '');
  
  // Ensure baseUrl has protocol
  if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {
    baseUrl = `http://${baseUrl}`;
  }
  
  // Helper function to construct file URL
  const constructFileUrl = (filePath) => {
    if (!filePath) return null;
    // If already a full URL, return as is
    if (filePath.startsWith('http')) return filePath;
    // If already starts with /uploads, use it directly
    if (filePath.startsWith('/uploads')) {
      return `${baseUrl}${filePath}`;
    }
    // Otherwise, prepend /uploads/ to the path
    const normalizedPath = filePath.replace(/\\/g, '/');
    const uploadsPath = normalizedPath.startsWith('/') ? normalizedPath : `/${normalizedPath}`;
    return `${baseUrl}/uploads${uploadsPath}`;
  };
  
  const data = {
    ...printHeader.toJSON(),
    logo_url: constructFileUrl(printHeader.logo_path),
    certification_logo_url: constructFileUrl(printHeader.quality_certification_logo_path),
  };

  sendResponse(res, 200, true, 'Print Header retrieved successfully', data);
});

/**
 * Delete print header (hard delete with file cleanup)
 */
exports.delete = asyncHandler(async (req, res) => {
  const { id } = req.params;

  const printHeader = await db.PrintHeader.findByPk(id);
  if (!printHeader) {
    return sendError(res, 'Print Header not found', 404);
  }

  try {
    // Delete logo file if exists
    if (printHeader.logo_path) {
      const logoFilePath = getFilePath(printHeader.logo_path);
      if (fs.existsSync(logoFilePath)) {
        fs.unlinkSync(logoFilePath);
      }
      // Also try to delete the directory if it's empty
      const logoDir = path.dirname(logoFilePath);
      try {
        if (fs.existsSync(logoDir) && fs.readdirSync(logoDir).length === 0) {
          fs.rmdirSync(logoDir);
        }
      } catch (err) {
        // Ignore directory deletion errors
        console.warn('Could not delete logo directory:', err.message);
      }
    }

    // Delete certification logo file if exists
    if (printHeader.quality_certification_logo_path) {
      const certFilePath = getFilePath(printHeader.quality_certification_logo_path);
      if (fs.existsSync(certFilePath)) {
        fs.unlinkSync(certFilePath);
      }
      // Also try to delete the directory if it's empty
      const certDir = path.dirname(certFilePath);
      try {
        if (fs.existsSync(certDir) && fs.readdirSync(certDir).length === 0) {
          fs.rmdirSync(certDir);
        }
      } catch (err) {
        // Ignore directory deletion errors
        console.warn('Could not delete certification logo directory:', err.message);
      }
    }

    // Delete the record from database
    await printHeader.destroy();

    sendResponse(res, 200, true, 'Print Header deleted successfully', null);
  } catch (error) {
    console.error('Error deleting print header:', error);
    throw error;
  }
});

