import os
from django.core.management.base import BaseCommand
from apps.parks.models import ParkPhoto
from apps.rides.models import RidePhoto
from django.conf import settings
import shutil


class Command(BaseCommand):
    help = "Move photo files to their normalized locations for domain-specific photos"

    def handle(self, *args, **kwargs):
        self.stdout.write("Moving photo files to normalized locations...")

        # Get all domain-specific photos
        park_photos = ParkPhoto.objects.all()
        ride_photos = RidePhoto.objects.all()
        photos = list(park_photos) + list(ride_photos)

        # Track processed files to clean up later
        processed_files = set()

        for photo in photos:
            try:
                # Get current file path
                current_name = photo.image.name
                current_path = os.path.join(settings.MEDIA_ROOT, current_name)

                # Try to find the actual file
                if not os.path.exists(current_path):
                    # Check if file exists in the old location structure
                    parts = current_name.split("/")
                    if len(parts) >= 2:
                        content_type = parts[0]  # 'park' or 'ride'
                        identifier = parts[1]  # e.g., 'alton-towers'

                        # Look for any files in that directory
                        old_dir = os.path.join(
                            settings.MEDIA_ROOT, content_type, identifier
                        )
                        if os.path.exists(old_dir):
                            files = [
                                f
                                for f in os.listdir(old_dir)
                                if not f.startswith(".")  # Skip hidden files
                                and not f.startswith("tmp")  # Skip temp files
                                and os.path.isfile(os.path.join(old_dir, f))
                            ]
                            if files:
                                current_path = os.path.join(old_dir, files[0])

                # If file still not found, set placeholder and continue
                if not os.path.exists(current_path):
                    placeholder = os.path.join("placeholders", "default.svg")
                    try:
                        photo.image.name = placeholder
                        photo.save()
                        self.stdout.write(
                            f"File for {current_name} not found; set placeholder {placeholder} for photo {photo.id}"
                        )
                    except Exception as e:
                        self.stdout.write(f"Error setting placeholder for photo {photo.id}: {e}")
                    continue

                # Get content type and object
                content_type_model = photo.content_type.model
                obj = photo.content_object
                identifier = getattr(obj, "slug", obj.id)

                # Get photo number based on photo type
                if isinstance(photo, ParkPhoto):
                    photo_number = ParkPhoto.objects.filter(
                        park=photo.park,
                        created_at__lte=photo.created_at,
                    ).count()
                else:  # RidePhoto
                    photo_number = RidePhoto.objects.filter(
                        ride=photo.ride,
                        created_at__lte=photo.created_at,
                    ).count()

                # Create new filename
                _, ext = os.path.splitext(current_path)
                if not ext:
                    ext = ".jpg"
                ext = ext.lower()
                new_filename = f"{identifier}_{photo_number}{ext}"

                # Create new path
                new_relative_path = f"{content_type_model}/{identifier}/{new_filename}"
                new_full_path = os.path.join(settings.MEDIA_ROOT, new_relative_path)

                # Create directory if it doesn't exist
                os.makedirs(os.path.dirname(new_full_path), exist_ok=True)

                # Move the file
                if current_path != new_full_path:
                    shutil.copy2(
                        current_path, new_full_path
                    )  # Use copy2 to preserve metadata
                    processed_files.add(current_path)
                else:
                    processed_files.add(current_path)

                # Update database
                photo.image.name = new_relative_path
                photo.save()

                self.stdout.write(f"Moved {current_name} to {new_relative_path}")

            except Exception as e:
                self.stdout.write(f"Error moving photo {photo.id}: {str(e)}")
                continue

        # Clean up old files
        self.stdout.write("Cleaning up old files...")
        for content_type in ["park", "ride"]:
            base_dir = os.path.join(settings.MEDIA_ROOT, content_type)
            if os.path.exists(base_dir):
                for root, dirs, files in os.walk(base_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        if file_path not in processed_files:
                            try:
                                os.remove(file_path)
                                self.stdout.write(f"Removed old file: {file_path}")
                            except Exception as e:
                                self.stdout.write(
                                    f"Error removing {file_path}: {str(e)}"
                                )

        self.stdout.write("Finished moving photo files and cleaning up")
