import path from 'path';
import sharp from 'sharp';
import { FileMetadata, ImageMetadata, ResourceProcessor } from '../types';
import { Resource, ResourceStatus, db } from '@nice/common';
import { getUploadFilePath } from '@server/utils/file';
import { BaseProcessor } from './BaseProcessor';

export class ImageProcessor extends BaseProcessor {
  constructor() {
    super();
  }

  async process(resource: Resource): Promise<Resource> {
    const { url } = resource;
    const filepath = getUploadFilePath(url);
    const originMeta = resource.metadata as unknown as FileMetadata;
    if (!originMeta.mimeType?.startsWith('image/')) {
      this.logger.log(`Skipping non-image resource: ${resource.id}`);
      return resource;
    }
    try {
      const image = sharp(filepath);
      const metadata = await image.metadata();
      if (!metadata) {
        throw new Error(`Failed to get metadata for image: ${url}`);
      }
      // Create WebP compressed version
      const compressedDir = this.createOutputDir(filepath, 'compressed');
      const compressedPath = path.join(
        compressedDir,
        `${path.basename(filepath, path.extname(filepath))}.webp`,
      );
      await image
        .webp({
          quality: 80,
          lossless: false,
          effort: 5, // Range 0-6, higher means slower but better compression
        })
        .toFile(compressedPath);
      const imageMeta: ImageMetadata = {
        width: metadata.width || 0,
        height: metadata.height || 0,
        orientation: metadata.orientation,
        space: metadata.space,
        hasAlpha: metadata.hasAlpha,
      };
      const updatedResource = await db.resource.update({
        where: { id: resource.id },
        data: {
          metadata: {
            ...originMeta,
            ...imageMeta,
          },
        },
      });

      return updatedResource;
    } catch (error: any) {
      throw new Error(`Failed to process image: ${error.message}`);
    }
  }
}
