"""
KTP Image Processor - Enhanced Version
Crop, resize, dan enhanced preprocessing untuk OCR yang lebih akurat

Standar e-KTP: 85.6mm x 53.98mm = 1011x638 px @300dpi

Improvements based on Context7 documentation:
- Pillow ImageEnhance for contrast/sharpness
- OpenCV CLAHE for adaptive histogram equalization
- Denoising for cleaner text detection
"""

import cv2
import numpy as np
import os
from PIL import Image, ImageEnhance, ImageFilter

KTP_WIDTH = 1011
KTP_HEIGHT = 638


def enhance_image_pil(image_path: str, output_path: str = None) -> str:
    """
    Enhance image using Pillow (from Context7 docs)
    - Contrast enhancement
    - Sharpness enhancement  
    - Detail filter for text clarity
    
    Args:
        image_path: Path to input image
        output_path: Optional path to save enhanced image
        
    Returns:
        Path to enhanced image
    """
    try:
        img = Image.open(image_path)
        
        # Contrast enhancement (factor 1.3 from Context7)
        contrast = ImageEnhance.Contrast(img)
        img = contrast.enhance(1.3)
        
        # Sharpness enhancement
        sharpness = ImageEnhance.Sharpness(img)
        img = sharpness.enhance(1.2)
        
        # Apply detail filter for text clarity
        img = img.filter(ImageFilter.DETAIL)
        
        # Save
        if output_path is None:
            base, ext = os.path.splitext(image_path)
            output_path = f"{base}_enhanced.jpg"
        
        img.save(output_path, quality=95)
        print(f"  [ENHANCE] Pillow enhanced: {output_path}")
        
        return output_path
        
    except Exception as e:
        print(f"  [ENHANCE] Pillow error: {e}")
        return image_path  # Return original if enhancement fails


def enhance_image_cv(image: np.ndarray) -> np.ndarray:
    """
    Enhance image using OpenCV (from Context7 docs)
    - CLAHE for adaptive histogram equalization
    - Denoising
    - Sharpening using Laplacian kernel
    
    Args:
        image: OpenCV image (BGR)
        
    Returns:
        Enhanced image (BGR)
    """
    try:
        # Convert to grayscale for processing
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        
        # Denoise (from Context7)
        denoised = cv2.fastNlMeansDenoising(gray, None, 10, 7, 21)
        
        # Enhanced CLAHE for documents
        clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
        enhanced = clahe.apply(denoised)
        
        # Sharpen using kernel (from Context7)
        kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], dtype=np.float32)
        sharpened = cv2.filter2D(enhanced, -1, kernel)
        
        # Convert back to BGR
        return cv2.cvtColor(sharpened, cv2.COLOR_GRAY2BGR)
        
    except Exception as e:
        print(f"  [ENHANCE] OpenCV error: {e}")
        return image  # Return original if enhancement fails


def crop_by_ocr_bounds(image, ocr_results, padding=0.03):
    """Crop image based on OCR bounding boxes"""
    if not ocr_results:
        return image
    
    h, w = image.shape[:2]
    all_x = []
    all_y = []
    
    for r in ocr_results:
        box = r.get('box', [])
        if len(box) >= 4:
            try:
                for point in box:
                    if isinstance(point, (list, tuple)) and len(point) >= 2:
                        all_x.append(float(point[0]))
                        all_y.append(float(point[1]))
            except:
                continue
    
    if not all_x or not all_y:
        return image
    
    x1 = int(max(0, min(all_x) - w * padding))
    y1 = int(max(0, min(all_y) - h * padding))
    x2 = int(min(w, max(all_x) + w * padding))
    y2 = int(min(h, max(all_y) + h * padding))
    
    return image[y1:y2, x1:x2]


def normalize_ktp_image(image_path, output_path=None, ocr_results=None):
    """
    Normalisasi gambar KTP:
    1. Crop berdasarkan OCR bounds
    2. Ensure landscape
    3. Resize ke ukuran standar
    """
    try:
        image = cv2.imread(image_path)
        if image is None:
            return None, False, "Gagal membaca gambar"
        
        h, w = image.shape[:2]
        print(f"  [IMAGE] Original: {w}x{h}")
        
        # Crop
        if ocr_results:
            image = crop_by_ocr_bounds(image, ocr_results)
            h, w = image.shape[:2]
            print(f"  [IMAGE] Cropped: {w}x{h}")
        
        # Landscape
        if h > w:
            image = cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)
        
        # Resize
        resized = cv2.resize(image, (KTP_WIDTH, KTP_HEIGHT),
                            interpolation=cv2.INTER_LANCZOS4)
        
        # Save
        if output_path is None:
            base, ext = os.path.splitext(image_path)
            output_path = f"{base}_normalized.jpg"
        
        cv2.imwrite(output_path, resized, [cv2.IMWRITE_JPEG_QUALITY, 95])
        print(f"  [IMAGE] Saved: {output_path}")
        
        return output_path, True, f"Normalized to {KTP_WIDTH}x{KTP_HEIGHT}"
        
    except Exception as e:
        import traceback
        traceback.print_exc()
        return None, False, f"Error: {str(e)}"
