import sharp from 'sharp';

export interface SmartThumbnailResult {
  success: boolean;
  faces_detected: number;
  primary_face_confidence: number;
  crop_info: {
    x: number;
    y: number;
    width: number;
    height: number;
  };
  original_dimensions: {
    width: number;
    height: number;
  };
  processing_strategy: 'face_centered' | 'center_crop' | 'smart_crop';
  error?: string;
}

export class SmartThumbnailService {
  /**
   * Download image and get metadata
   */
  private async downloadImage(imageUrl: string): Promise<{ sharpInstance: sharp.Sharp; width: number; height: number }> {
    try {
      const response = await fetch(imageUrl);
      if (!response.ok) {
        throw new Error(`Failed to download image: ${response.statusText}`);
      }
      
      const buffer = Buffer.from(await response.arrayBuffer());
      const sharpInstance = sharp(buffer);
      const metadata = await sharpInstance.metadata();
      
      return {
        sharpInstance,
        width: metadata.width || 0,
        height: metadata.height || 0
      };
    } catch (error) {
      throw new Error(`Image download failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }

  /**
   * Analyze image using Sharp's built-in stats to find areas of interest
   */
  private async analyzeImageContent(sharpInstance: sharp.Sharp, width: number, height: number): Promise<{ x: number; y: number; confidence: number }[]> {
    try {
      const focalPoints: { x: number; y: number; confidence: number }[] = [];
      
      // Analyze different regions of the image
      const gridSize = 3; // 3x3 grid
      const regionWidth = Math.floor(width / gridSize);
      const regionHeight = Math.floor(height / gridSize);
      
      for (let row = 0; row < gridSize; row++) {
        for (let col = 0; col < gridSize; col++) {
          const x = col * regionWidth;
          const y = row * regionHeight;
          
          try {
            // Extract region and analyze
            const regionStats = await sharpInstance
              .clone()
              .extract({ left: x, top: y, width: regionWidth, height: regionHeight })
              .stats();

            // Calculate region score based on contrast and brightness distribution
            let regionScore = 0;
            
            if (regionStats.channels && regionStats.channels.length > 0) {
              const channel = regionStats.channels[0]; // Use first channel (or grayscale)
              
              // Good regions typically have:
              // 1. Moderate mean brightness (not too dark/bright)
              // 2. Good standard deviation (contrast)
              // 3. Balanced distribution
              
              const meanBrightness = channel.mean;
              const contrast = channel.std;
              
              // Score brightness (prefer middle range 80-180)
              const brightnessScore = meanBrightness > 80 && meanBrightness < 180 ? 
                1 - Math.abs(meanBrightness - 130) / 130 : 0.2;
              
              // Score contrast (higher is better, up to a point)
              const contrastScore = Math.min(contrast / 50, 1);
              
              // Combine scores
              regionScore = (brightnessScore * 0.4 + contrastScore * 0.6);
              
              // Boost center regions slightly (faces often in center)
              if (row === 1 && col === 1) {
                regionScore *= 1.2;
              }
              
              // Boost upper-center region (faces often in upper portion)
              if (row === 0 && col === 1) {
                regionScore *= 1.1;
              }
            }
            
            if (regionScore > 0.3) {
              focalPoints.push({
                x: x + regionWidth / 2,  // Center of region
                y: y + regionHeight / 2,
                confidence: regionScore
              });
            }
          } catch (regionError) {
            // Skip this region if analysis fails
            console.warn(`Failed to analyze region ${row},${col}:`, regionError);
          }
        }
      }
      
      // Sort by confidence
      return focalPoints.sort((a, b) => b.confidence - a.confidence);
      
    } catch (error) {
      console.error('Error analyzing image content:', error);
      return [];
    }
  }

  /**
   * Calculate smart crop based on focal points
   */
  private calculateSmartCrop(
    imageWidth: number,
    imageHeight: number,
    focalPoints: { x: number; y: number; confidence: number }[],
    targetAspect: number = 9/16
  ): { x: number; y: number; width: number; height: number } {
    
    if (focalPoints.length === 0) {
      return this.calculateCenterCrop(imageWidth, imageHeight, targetAspect);
    }
    
    const primaryFocalPoint = focalPoints[0];
    
    let cropWidth: number, cropHeight: number, cropX: number, cropY: number;

    if (imageWidth / imageHeight > targetAspect) {
      // Image is wider - crop horizontally
      cropWidth = Math.floor(imageHeight * targetAspect);
      cropHeight = imageHeight;
      
      // Center crop around focal point, but keep within bounds
      cropX = Math.max(0, Math.min(
        Math.floor(primaryFocalPoint.x - cropWidth / 2),
        imageWidth - cropWidth
      ));
      cropY = 0;
    } else {
      // Image is taller - crop vertically
      cropWidth = imageWidth;
      cropHeight = Math.floor(imageWidth / targetAspect);
      
      // Center crop around focal point vertically
      cropY = Math.max(0, Math.min(
        Math.floor(primaryFocalPoint.y - cropHeight / 2),
        imageHeight - cropHeight
      ));
      cropX = 0;
    }

    return { x: cropX, y: cropY, width: cropWidth, height: cropHeight };
  }

  /**
   * Calculate standard center crop
   */
  private calculateCenterCrop(
    imageWidth: number,
    imageHeight: number,
    targetAspect: number = 9/16
  ): { x: number; y: number; width: number; height: number } {
    let cropWidth: number, cropHeight: number, cropX: number, cropY: number;

    if (imageWidth / imageHeight > targetAspect) {
      cropWidth = Math.floor(imageHeight * targetAspect);
      cropHeight = imageHeight;
      cropX = Math.floor((imageWidth - cropWidth) / 2);
      cropY = 0;
    } else {
      cropWidth = imageWidth;
      cropHeight = Math.floor(imageWidth / targetAspect);
      cropX = 0;
      cropY = Math.floor((imageHeight - cropHeight) / 2);
    }

    return { x: cropX, y: cropY, width: cropWidth, height: cropHeight };
  }

  /**
   * Process thumbnail to find optimal crop position
   */
  public async processThumbnail(thumbnailUrl: string): Promise<SmartThumbnailResult> {
    try {
      console.log(`🔍 Analyzing thumbnail: ${thumbnailUrl}`);
      
      const { sharpInstance, width, height } = await this.downloadImage(thumbnailUrl);
      
      if (width === 0 || height === 0) {
        throw new Error('Invalid image dimensions');
      }

      // Analyze image content for focal points
      const focalPoints = await this.analyzeImageContent(sharpInstance, width, height);
      
      console.log(`🎯 Found ${focalPoints.length} focal points`);

      let cropInfo: { x: number; y: number; width: number; height: number };
      let strategy: 'face_centered' | 'center_crop' | 'smart_crop';
      let confidence = 0;
      let facesDetected = 0;

      if (focalPoints.length > 0) {
        const primaryFocalPoint = focalPoints[0];
        confidence = primaryFocalPoint.confidence;
        
        // Consider high-confidence focal points as potential faces
        if (confidence > 0.7) {
          facesDetected = 1;
          strategy = 'face_centered';
        } else {
          strategy = 'smart_crop';
        }
        
        cropInfo = this.calculateSmartCrop(width, height, focalPoints);
        
        console.log(`✅ Smart crop calculated with confidence: ${confidence.toFixed(2)}`);
      } else {
        cropInfo = this.calculateCenterCrop(width, height);
        strategy = 'center_crop';
        
        console.log(`📐 Center crop calculated (no focal points detected)`);
      }

      return {
        success: true,
        faces_detected: facesDetected,
        primary_face_confidence: confidence,
        crop_info: cropInfo,
        original_dimensions: { width, height },
        processing_strategy: strategy
      };

    } catch (error) {
      console.error(`❌ Error processing thumbnail ${thumbnailUrl}:`, error);
      return {
        success: false,
        faces_detected: 0,
        primary_face_confidence: 0,
        crop_info: { x: 0, y: 0, width: 0, height: 0 },
        original_dimensions: { width: 0, height: 0 },
        processing_strategy: 'center_crop',
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }

  /**
   * Calculate CSS object-position
   */
  public calculateObjectPosition(
    cropInfo: { x: number; y: number; width: number; height: number },
    originalDimensions: { width: number; height: number }
  ): string {
    if (!cropInfo || !originalDimensions.width || !originalDimensions.height) {
      return 'center center';
    }

    const cropCenterX = cropInfo.x + cropInfo.width / 2;
    const cropCenterY = cropInfo.y + cropInfo.height / 2;
    
    const positionX = (cropCenterX / originalDimensions.width) * 100;
    const positionY = (cropCenterY / originalDimensions.height) * 100;
    
    return `${Math.max(0, Math.min(100, positionX)).toFixed(1)}% ${Math.max(0, Math.min(100, positionY)).toFixed(1)}%`;
  }

  /**
   * Get optimized thumbnail information
   */
  public async getOptimizedThumbnailInfo(thumbnailUrl: string) {
    try {
      const result = await this.processThumbnail(thumbnailUrl);
      
      return {
        originalUrl: thumbnailUrl,
        faceCenterPosition: this.calculateObjectPosition(result.crop_info, result.original_dimensions),
        facesDetected: result.faces_detected,
        confidence: result.primary_face_confidence,
        strategy: result.processing_strategy,
        processedSuccessfully: result.success
      };
    } catch (error) {
      console.error('Error optimizing thumbnail:', error);
      return {
        originalUrl: thumbnailUrl,
        faceCenterPosition: 'center center',
        facesDetected: 0,
        confidence: 0,
        strategy: 'center_crop' as const,
        processedSuccessfully: false
      };
    }
  }
}

// Export singleton instance
export const smartThumbnailService = new SmartThumbnailService();