const { imageExists } = require('../helpers/image-helper');
const { ListingImages } = require('../models');
const logger = require('./logger');

/**
 * Finds and optionally removes database records for images that don't exist on filesystem
 *
 * @param {object} options Cleanup options
 * @param {boolean} options.dryRun If true, only report what would be deleted without actually
 *   deleting
 * @param {string} options.folder Folder to check (default: 'host-uploads')
 * @returns {Promise<object>} Cleanup results
 */
async function cleanupMissingImages(options = {}) {
  const { dryRun = true, folder = 'host-uploads' } = options;

  try {
    logger.info(`Starting image cleanup (dryRun: ${dryRun}, folder: ${folder})`);

    // Get all listing images from database
    const allImages = await ListingImages.findAll({
      attributes: ['id', 'image', 'listing_id', 'category'],
    });

    logger.info(`Found ${allImages.length} image records in database`);

    const missingImages = [];
    const existingImages = [];

    // Check each image file
    const imageChecks = await Promise.all(
      allImages.map(async (imageRecord) => {
        const imagePath = `public/${folder}/${imageRecord.image}`;
        const exists = await imageExists(imagePath);

        if (!exists) {
          return {
            missing: true,
            data: {
              id: imageRecord.id,
              image: imageRecord.image,
              listing_id: imageRecord.listing_id,
              category: imageRecord.category,
              path: imagePath,
            },
          };
        }
        return {
          missing: false,
          data: imageRecord.id,
        };
      }),
    );

    imageChecks.forEach((check) => {
      if (check.missing) {
        missingImages.push(check.data);
      } else {
        existingImages.push(check.data);
      }
    });

    logger.info(`Found ${missingImages.length} missing images`);
    logger.info(`Found ${existingImages.length} existing images`);

    let deletedCount = 0;

    if (!dryRun && missingImages.length > 0) {
      // Delete records with missing images
      const idsToDelete = missingImages.map((img) => img.id);

      const result = await ListingImages.destroy({
        where: {
          id: idsToDelete,
        },
      });

      deletedCount = result;
      logger.info(`Deleted ${deletedCount} image records with missing files`);
    }

    return {
      success: true,
      dryRun,
      totalRecords: allImages.length,
      missingImages: missingImages.length,
      existingImages: existingImages.length,
      deletedRecords: deletedCount,
      missingImagesList: missingImages,
    };
  } catch (error) {
    logger.error('Error cleaning up missing images:', error);
    throw error;
  }
}

/**
 * Express controller to handle cleanup endpoint
 *
 * @param {import('express').Request} req The Express request object
 * @param {import('express').Response} res The Express response object
 * @param {import('express').NextFunction} next The Express next middleware function
 * @returns {Promise<import('express').Response>} JSON response with cleanup results
 */
const cleanupMissingImagesController = async (req, res, next) => {
  try {
    const { dryRun = 'true', folder = 'host-uploads' } = req.query;

    const isDryRun = dryRun === 'true';

    const result = await cleanupMissingImages({
      dryRun: isDryRun,
      folder,
    });

    return res.status(200).json({
      success: true,
      message: isDryRun
        ? 'Dry run completed - no records were deleted'
        : `Cleanup completed - ${result.deletedRecords} records deleted`,
      data: {
        totalRecords: result.totalRecords,
        missingImages: result.missingImages,
        existingImages: result.existingImages,
        deletedRecords: result.deletedRecords,
        dryRun: result.dryRun,
        missingImagesList: result.missingImagesList.map((img) => ({
          id: img.id,
          image: img.image,
          listingId: img.listing_id,
          category: img.category,
        })),
      },
    });
  } catch (error) {
    return next(error);
  }
};

module.exports = {
  cleanupMissingImages,
  cleanupMissingImagesController,
};
