"""Core media processing logic."""

import hashlib
import json
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, Optional

from PIL import Image
from PIL.PngImagePlugin import PngInfo

from .signature import SignatureEngine
from .watermark import WatermarkEngine


class MediaProcessor:
    """Processes media files with watermarks and compliance metadata."""

    def __init__(self, watermark_engine: Optional[WatermarkEngine], sign: bool = True):
        self.watermark_engine = watermark_engine
        self.sign = sign
        self.signature_engine = SignatureEngine() if sign else None

    def process_file(
        self, input_path: Path, output_path: Path, metadata: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Process a single file."""

        file_type = self._detect_file_type(input_path)

        if file_type == "image":
            return self._process_image(input_path, output_path, metadata)
        elif file_type == "video":
            return self._process_video(input_path, output_path, metadata)
        elif file_type == "audio":
            return self._process_audio(input_path, output_path, metadata)
        else:
            raise ValueError(f"Unsupported file type: {input_path.suffix}")

    def _detect_file_type(self, path: Path) -> str:
        """Detect media type from extension."""
        ext = path.suffix.lower()
        if ext in {".jpg", ".jpeg", ".png", ".webp", ".bmp"}:
            return "image"
        elif ext in {".mp4", ".mov", ".avi", ".mkv", ".webm"}:
            return "video"
        elif ext in {".mp3", ".wav", ".ogg", ".flac", ".m4a"}:
            return "audio"
        return "unknown"

    def _process_image(
        self, input_path: Path, output_path: Path, metadata: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Process image file."""

        img = Image.open(input_path)

        # Apply watermark if engine provided
        if self.watermark_engine:
            img = self.watermark_engine.apply_to_image(img)

        # Prepare metadata
        full_metadata = {
            **metadata,
            "original_file": str(input_path),
            "processed_date": datetime.utcnow().isoformat(),
            "file_hash": self._compute_hash(input_path),
            "dimensions": f"{img.width}x{img.height}",
            "format": img.format or input_path.suffix[1:].upper(),
        }

        # Embed metadata
        if output_path.suffix.lower() == ".png":
            png_info = PngInfo()
            png_info.add_text("compliance", json.dumps(full_metadata))
            img.save(output_path, pnginfo=png_info, optimize=True)
        else:
            # For JPEG, use EXIF
            img.save(output_path, quality=95, optimize=True)
            # Note: Full EXIF writing would require piexif library

        # Sign if enabled
        signature = None
        if self.sign and self.signature_engine:
            signature = self.signature_engine.sign_file(output_path)
            # Store signature in sidecar file
            signature_path = output_path.with_suffix(output_path.suffix + ".sig")
            signature_path.write_text(json.dumps(signature, indent=2))

        return {
            "file": str(input_path),
            "output": str(output_path),
            "success": True,
            "timestamp": datetime.utcnow().isoformat(),
            "metadata": full_metadata,
            "signature": signature.get("signature") if signature else None,
        }

    def _process_video(
        self, input_path: Path, output_path: Path, metadata: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Process video file using OpenCV."""

        import cv2

        # Open video
        cap = cv2.VideoCapture(str(input_path))
        if not cap.isOpened():
            raise ValueError(f"Cannot open video: {input_path}")

        # Get properties
        fps = cap.get(cv2.CAP_PROP_FPS)
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        fourcc = cv2.VideoWriter_fourcc(*"mp4v")

        # Create writer
        out = cv2.VideoWriter(str(output_path), fourcc, fps, (width, height))

        # Process frames
        frame_count = 0
        while True:
            ret, frame = cap.read()
            if not ret:
                break

            # Apply watermark to frame
            if self.watermark_engine:
                # Convert BGR to RGB for PIL
                frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                pil_image = Image.fromarray(frame_rgb)
                watermarked = self.watermark_engine.apply_to_image(pil_image)
                # Convert back to BGR
                frame = cv2.cvtColor(np.array(watermarked), cv2.COLOR_RGB2BGR)

            out.write(frame)
            frame_count += 1

        cap.release()
        out.release()

        # Metadata
        full_metadata = {
            **metadata,
            "original_file": str(input_path),
            "processed_date": datetime.utcnow().isoformat(),
            "file_hash": self._compute_hash(input_path),
            "dimensions": f"{width}x{height}",
            "fps": fps,
            "frames": frame_count,
        }

        # Store metadata in sidecar JSON
        metadata_path = output_path.with_suffix(".json")
        metadata_path.write_text(json.dumps(full_metadata, indent=2))

        # Sign
        signature = None
        if self.sign and self.signature_engine:
            signature = self.signature_engine.sign_file(output_path)
            signature_path = output_path.with_suffix(output_path.suffix + ".sig")
            signature_path.write_text(json.dumps(signature, indent=2))

        return {
            "file": str(input_path),
            "output": str(output_path),
            "success": True,
            "timestamp": datetime.utcnow().isoformat(),
            "metadata": full_metadata,
            "signature": signature.get("signature") if signature else None,
        }

    def _process_audio(
        self, input_path: Path, output_path: Path, metadata: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Process audio file."""

        from pydub import AudioSegment

        # Load audio
        audio = AudioSegment.from_file(input_path)

        # Metadata
        full_metadata = {
            **metadata,
            "original_file": str(input_path),
            "processed_date": datetime.utcnow().isoformat(),
            "file_hash": self._compute_hash(input_path),
            "duration_ms": len(audio),
            "channels": audio.channels,
            "sample_width": audio.sample_width,
            "frame_rate": audio.frame_rate,
        }

        # Export with metadata tags
        tags = {
            "comment": json.dumps(full_metadata),
            "genre": "AI-Generated",
        }

        audio.export(output_path, format=output_path.suffix[1:], tags=tags)

        # Sign
        signature = None
        if self.sign and self.signature_engine:
            signature = self.signature_engine.sign_file(output_path)
            signature_path = output_path.with_suffix(output_path.suffix + ".sig")
            signature_path.write_text(json.dumps(signature, indent=2))

        return {
            "file": str(input_path),
            "output": str(output_path),
            "success": True,
            "timestamp": datetime.utcnow().isoformat(),
            "metadata": full_metadata,
            "signature": signature.get("signature") if signature else None,
        }

    def verify_file(self, file_path: Path) -> Dict[str, Any]:
        """Verify watermark and signature on a file."""

        verification = {}

        # Check signature
        signature_path = file_path.with_suffix(file_path.suffix + ".sig")
        if signature_path.exists() and self.signature_engine:
            signature_data = json.loads(signature_path.read_text())
            is_valid = self.signature_engine.verify_file(file_path, signature_data["signature"])
            verification["signature"] = {"valid": is_valid, "details": signature_data.get("metadata")}
        else:
            verification["signature"] = {"valid": False, "details": "No signature file found"}

        # Check metadata
        metadata_path = file_path.with_suffix(".json")
        if metadata_path.exists():
            metadata = json.loads(metadata_path.read_text())
            verification["metadata"] = {"valid": True, "details": metadata}
        else:
            verification["metadata"] = {"valid": False, "details": "No metadata file found"}

        # Check watermark presence (basic hash-based check)
        current_hash = self._compute_hash(file_path)
        verification["file_integrity"] = {
            "valid": True,
            "details": f"SHA-256: {current_hash[:16]}...",
        }

        return verification

    def _compute_hash(self, file_path: Path) -> str:
        """Compute SHA-256 hash of file."""
        sha256 = hashlib.sha256()
        with open(file_path, "rb") as f:
            for chunk in iter(lambda: f.read(8192), b""):
                sha256.update(chunk)
        return sha256.hexdigest()


# Import numpy here to avoid circular import
try:
    import numpy as np
except ImportError:
    np = None
