"""
Comprehensive data seeding script for ThrillWiki.

This script creates realistic test data for all models in the system,
including users, parks, rides, companies, reviews, and all related data.
Designed for maximum testing coverage and realistic scenarios.

Usage:
    uv run manage.py seed_data
    uv run manage.py seed_data --clear  # Clear existing data first
    uv run manage.py seed_data --users 50 --parks 20 --rides 100  # Custom counts
"""

import random
from datetime import date
from decimal import Decimal

from django.contrib.auth import get_user_model
from django.contrib.gis.geos import Point
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from django.utils.text import slugify

# Import all models
from apps.accounts.models import NotificationPreference, UserDeletionRequest, UserNotification, UserProfile
from apps.core.history import HistoricalSlug
from apps.parks.models import Park, ParkArea, ParkLocation, ParkPhoto, ParkReview
from apps.parks.models.companies import Company as ParkCompany
from apps.parks.models.companies import CompanyHeadquarters
from apps.rides.models import Ride, RideLocation, RideModel, RidePhoto, RideReview, RollerCoasterStats
from apps.rides.models.company import Company as RideCompany

# Try to import optional models that may not exist
try:
    from apps.rides.models import RideModelPhoto, RideModelTechnicalSpec, RideModelVariant
except ImportError:
    RideModelVariant = None
    RideModelPhoto = None
    RideModelTechnicalSpec = None

try:
    from apps.rides.models import RideRanking
except ImportError:
    RideRanking = None

try:
    from apps.moderation.models import ModerationAction, ModerationQueue
except ImportError:
    ModerationQueue = None
    ModerationAction = None

try:
    from django_cloudflareimages_toolkit.models import CloudflareImage
except ImportError:
    CloudflareImage = None

User = get_user_model()


class Command(BaseCommand):
    help = "Seed the database with comprehensive test data for all models"

    def add_arguments(self, parser):
        parser.add_argument(
            "--clear",
            action="store_true",
            help="Clear existing data before seeding",
        )
        parser.add_argument(
            "--users",
            type=int,
            default=25,
            help="Number of users to create (default: 25)",
        )
        parser.add_argument(
            "--companies",
            type=int,
            default=15,
            help="Number of companies to create (default: 15)",
        )
        parser.add_argument(
            "--parks",
            type=int,
            default=10,
            help="Number of parks to create (default: 10)",
        )
        parser.add_argument(
            "--rides",
            type=int,
            default=50,
            help="Number of rides to create (default: 50)",
        )
        parser.add_argument(
            "--ride-models",
            type=int,
            default=20,
            help="Number of ride models to create (default: 20)",
        )
        parser.add_argument(
            "--reviews",
            type=int,
            default=100,
            help="Number of reviews to create (default: 100)",
        )

    def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS("Starting comprehensive data seeding..."))

        if options["clear"]:
            self.clear_data()

        with transaction.atomic():
            # Create data in dependency order
            users = self.create_users(options["users"])
            companies = self.create_companies(options["companies"])
            ride_models = self.create_ride_models(options["ride_models"], companies)
            parks = self.create_parks(options["parks"], companies)
            rides = self.create_rides(options["rides"], parks, companies, ride_models)

            # Create content and interactions
            self.create_reviews(options["reviews"], users, parks, rides)

            self.create_notifications(users)
            self.create_moderation_data(users, parks, rides)

            # Create media and photos
            self.create_photos(parks, rides, ride_models)

            # Create rankings and statistics
            self.create_rankings(rides)

        self.stdout.write(self.style.SUCCESS("✅ Data seeding completed successfully!"))
        self.print_summary()

    def clear_data(self):
        """Clear existing data in reverse dependency order"""
        self.stdout.write("🗑️  Clearing existing data...")

        models_to_clear = [
            # Content and interactions (clear first)
            UserNotification,
            NotificationPreference,
            ParkReview,
            RideReview,
            ModerationAction,
            ModerationQueue,
            # Media
            ParkPhoto,
            RidePhoto,
            CloudflareImage,
            # Core entities
            RollerCoasterStats,
            Ride,
            ParkArea,
            Park,
            ParkLocation,
            RideModel,
            CompanyHeadquarters,
            ParkCompany,
            RideCompany,
            # Users (clear last due to foreign key dependencies)
            UserDeletionRequest,
            UserProfile,
            User,
            # History
            HistoricalSlug,
        ]

        # Add optional models if they exist
        if RideRanking:
            models_to_clear.insert(4, RideRanking)
        if RideLocation:
            models_to_clear.insert(-6, RideLocation)
        if RideModelPhoto:
            models_to_clear.insert(6, RideModelPhoto)
        if RideModelTechnicalSpec:
            models_to_clear.insert(-6, RideModelTechnicalSpec)
        if RideModelVariant:
            models_to_clear.insert(-6, RideModelVariant)
        if ModerationQueue:
            models_to_clear.insert(4, ModerationQueue)

        for model in models_to_clear:
            try:
                count = model.objects.count()
                if count > 0:
                    model.objects.all().delete()
                    self.stdout.write(f"  Cleared {count} {model._meta.verbose_name_plural}")
            except Exception as e:
                self.stdout.write(
                    self.style.WARNING(f"  ⚠️  Could not clear {model._meta.verbose_name_plural}: {str(e)}")
                )
                # Continue with other models
                continue

    def create_users(self, count: int) -> list[User]:
        """Create diverse users with comprehensive profiles"""
        self.stdout.write(f"👥 Creating {count} users...")

        users = []

        # Create admin user if it doesn't exist
        admin, created = User.objects.get_or_create(
            username="admin",
            defaults={
                "email": "admin@thrillwiki.com",
                "role": "ADMIN",
                "is_staff": True,
                "is_superuser": True,
                "display_name": "ThrillWiki Admin",
                "theme_preference": "dark",
                "privacy_level": "public",
            },
        )
        if created:
            admin.set_password("admin123")
            admin.save()
        users.append(admin)

        # Create moderator if it doesn't exist
        moderator, created = User.objects.get_or_create(
            username="moderator",
            defaults={
                "email": "mod@thrillwiki.com",
                "role": "MODERATOR",
                "is_staff": True,
                "display_name": "Site Moderator",
                "theme_preference": "light",
                "privacy_level": "public",
            },
        )
        if created:
            moderator.set_password("mod123")
            moderator.save()
        users.append(moderator)

        # Sample user data
        first_names = [
            "Alex",
            "Jordan",
            "Taylor",
            "Casey",
            "Morgan",
            "Riley",
            "Avery",
            "Quinn",
            "Blake",
            "Cameron",
            "Drew",
            "Emery",
            "Finley",
            "Harper",
            "Hayden",
            "Jamie",
            "Kendall",
            "Logan",
            "Parker",
            "Peyton",
            "Reese",
            "Sage",
            "Skyler",
            "Sydney",
            "Tanner",
        ]

        last_names = [
            "Smith",
            "Johnson",
            "Williams",
            "Brown",
            "Jones",
            "Garcia",
            "Miller",
            "Davis",
            "Rodriguez",
            "Martinez",
            "Hernandez",
            "Lopez",
            "Gonzalez",
            "Wilson",
            "Anderson",
            "Thomas",
            "Taylor",
            "Moore",
            "Jackson",
            "Martin",
            "Lee",
            "Perez",
            "Thompson",
            "White",
            "Harris",
        ]

        domains = ["gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "icloud.com"]

        # Create regular users
        for _i in range(count - 2):  # -2 for admin and moderator
            first_name = random.choice(first_names)
            last_name = random.choice(last_names)
            username = f"{first_name.lower()}{last_name.lower()}{random.randint(1, 999)}"
            email = f"{username}@{random.choice(domains)}"

            user = User.objects.create_user(
                username=username,
                email=email,
                password="password123",
                display_name=f"{first_name} {last_name}",
                role=random.choice(["USER"] * 8 + ["MODERATOR"]),
                theme_preference=random.choice(["light", "dark"]),
                privacy_level=random.choice(["public", "friends", "private"]),
                email_notifications=random.choice([True, False]),
                push_notifications=random.choice([True, False]),
                show_email=random.choice([True, False]),
                show_real_name=random.choice([True, False]),
                show_statistics=random.choice([True, False]),
                allow_friend_requests=random.choice([True, False]),
                two_factor_enabled=random.choice([True, False]),
                login_notifications=random.choice([True, False]),
            )

            # Create detailed notification preferences
            user.notification_preferences = {
                "email": {
                    "reviews": random.choice([True, False]),
                    "submissions": random.choice([True, False]),
                    "social": random.choice([True, False]),
                    "system": random.choice([True, False]),
                },
                "push": {
                    "reviews": random.choice([True, False]),
                    "submissions": random.choice([True, False]),
                    "social": random.choice([True, False]),
                    "achievements": random.choice([True, False]),
                },
                "in_app": {
                    "all": random.choice([True, False]),
                },
            }
            user.save()

            # Create user profile with ride credits
            profile = UserProfile.objects.get(user=user)
            profile.bio = f"Thrill seeker from {random.choice(['California', 'Florida', 'Ohio', 'Pennsylvania', 'Texas'])}. Love roller coasters!"
            profile.pronouns = random.choice(["he/him", "she/her", "they/them", ""])
            profile.coaster_credits = random.randint(0, 500)
            profile.dark_ride_credits = random.randint(0, 100)
            profile.flat_ride_credits = random.randint(0, 200)
            profile.water_ride_credits = random.randint(0, 50)

            # Add social media links for some users
            if random.random() < 0.3:
                profile.twitter = f"https://twitter.com/{username}"
            if random.random() < 0.2:
                profile.instagram = f"https://instagram.com/{username}"
            if random.random() < 0.1:
                profile.youtube = f"https://youtube.com/@{username}"

            profile.save()
            users.append(user)

        self.stdout.write(f"  ✅ Created {len(users)} users")
        return users

    def create_companies(self, count: int) -> list:
        """Create companies with different roles"""
        self.stdout.write(f"🏢 Creating {count} companies...")

        companies = []

        # Major theme park operators
        operators_data = [
            ("Walt Disney Company", ["OPERATOR", "PROPERTY_OWNER"], 1923, "Burbank, CA, USA"),
            ("Universal Parks & Resorts", ["OPERATOR", "PROPERTY_OWNER"], 1964, "Orlando, FL, USA"),
            ("Six Flags Entertainment", ["OPERATOR"], 1961, "Arlington, TX, USA"),
            ("Cedar Fair", ["OPERATOR"], 1983, "Sandusky, OH, USA"),
            ("SeaWorld Parks", ["OPERATOR"], 1964, "Orlando, FL, USA"),
            ("Busch Gardens", ["OPERATOR"], 1959, "Tampa, FL, USA"),
            ("Knott's Berry Farm", ["OPERATOR"], 1920, "Buena Park, CA, USA"),
        ]

        # Major ride manufacturers
        manufacturers_data = [
            ("Bolliger & Mabillard", ["MANUFACTURER"], 1988, "Monthey, Switzerland"),
            ("Intamin", ["MANUFACTURER"], 1967, "Schaan, Liechtenstein"),
            ("Vekoma", ["MANUFACTURER"], 1926, "Vlodrop, Netherlands"),
            ("Rocky Mountain Construction", ["MANUFACTURER"], 2001, "Hayden, ID, USA"),
            ("Mack Rides", ["MANUFACTURER"], 1780, "Waldkirch, Germany"),
            ("Gerstlauer", ["MANUFACTURER"], 1982, "Münsterhausen, Germany"),
            ("Premier Rides", ["MANUFACTURER"], 1994, "Baltimore, MD, USA"),
            ("S&S Worldwide", ["MANUFACTURER"], 1994, "Logan, UT, USA"),
        ]

        # Ride designers
        designers_data = [
            ("Werner Stengel", ["DESIGNER"], 1965, "Munich, Germany"),
            ("Alan Schilke", ["DESIGNER"], 1990, "Hayden, ID, USA"),
            ("John Wardley", ["DESIGNER"], 1970, "London, UK"),
        ]

        all_company_data = operators_data + manufacturers_data + designers_data

        for name, roles, founded_year, location in all_company_data:
            # Determine which Company model to use based on roles
            if "OPERATOR" in roles or "PROPERTY_OWNER" in roles:
                # Use ParkCompany for park operators and property owners
                company, created = ParkCompany.objects.get_or_create(
                    name=name,
                    defaults={
                        "slug": slugify(name),
                        "roles": roles,
                        "founded_year": founded_year,
                        "description": f"{name} is a leading {'park operator' if 'OPERATOR' in roles else 'property owner'} in the theme park industry.",
                        "website": f"https://{slugify(name).replace('-', '')}.com",
                        "parks_count": random.randint(1, 20) if "OPERATOR" in roles else 0,
                        "rides_count": random.randint(10, 500) if "MANUFACTURER" in roles else 0,
                    },
                )
            else:
                # Use RideCompany for manufacturers and designers
                company, created = RideCompany.objects.get_or_create(
                    name=name,
                    defaults={
                        "slug": slugify(name),
                        "roles": roles,
                        "founded_date": date(founded_year, 1, 1) if founded_year else None,
                        "description": f"{name} is a leading {'ride manufacturer' if 'MANUFACTURER' in roles else 'ride designer'} in the theme park industry.",
                        "website": f"https://{slugify(name).replace('-', '')}.com",
                        "rides_count": random.randint(10, 500) if "MANUFACTURER" in roles else 0,
                        "coasters_count": random.randint(5, 100) if "MANUFACTURER" in roles else 0,
                    },
                )

            # Create headquarters if company was created and is a ParkCompany
            if created and isinstance(company, ParkCompany):
                city, state_country = location.rsplit(", ", 1)
                if ", " in city:
                    city, state = city.split(", ")
                    country = state_country
                else:
                    state = ""
                    country = state_country

                CompanyHeadquarters.objects.get_or_create(
                    company=company,
                    defaults={
                        "city": city,
                        "state_province": state,
                        "country": country,
                        "street_address": f"{random.randint(100, 9999)} {random.choice(['Main', 'Park', 'Industry', 'Corporate'])} {random.choice(['St', 'Ave', 'Blvd', 'Dr'])}",
                        "postal_code": f"{random.randint(10000, 99999)}" if country == "USA" else "",
                    },
                )

            companies.append(company)

        # Create additional random companies to reach the target count
        company_types = ["Theme Parks", "Amusements", "Entertainment", "Rides", "Design", "Engineering"]

        for _i in range(len(all_company_data), count):
            company_type = random.choice(company_types)
            name = f"{random.choice(['Global', 'International', 'Premier', 'Elite', 'Advanced', 'Creative'])} {company_type} {'Group' if random.random() < 0.5 else 'Corporation'}"

            roles = []
            if "Theme Parks" in name or "Amusements" in name:
                roles = ["OPERATOR"]
                if random.random() < 0.5:
                    roles.append("PROPERTY_OWNER")
            elif "Rides" in name or "Engineering" in name:
                roles = ["MANUFACTURER"]
            elif "Design" in name:
                roles = ["DESIGNER"]
            else:
                roles = [random.choice(["OPERATOR", "MANUFACTURER", "DESIGNER"])]

            # Use appropriate company model based on roles
            if "OPERATOR" in roles or "PROPERTY_OWNER" in roles:
                company = ParkCompany.objects.create(
                    name=name,
                    slug=slugify(name),
                    roles=roles,
                    founded_year=random.randint(1950, 2020),
                    description=f"{name} specializes in {'theme park operations' if 'OPERATOR' in roles else 'property ownership'}.",
                    website=f"https://{slugify(name).replace('-', '')}.com",
                    parks_count=random.randint(1, 10) if "OPERATOR" in roles else 0,
                    rides_count=random.randint(5, 100) if "MANUFACTURER" in roles else 0,
                )
            else:
                company = RideCompany.objects.create(
                    name=name,
                    slug=slugify(name),
                    roles=roles,
                    founded_date=date(random.randint(1950, 2020), 1, 1),
                    description=f"{name} specializes in {'ride manufacturing' if 'MANUFACTURER' in roles else 'ride design'}.",
                    website=f"https://{slugify(name).replace('-', '')}.com",
                    rides_count=random.randint(5, 100) if "MANUFACTURER" in roles else 0,
                    coasters_count=random.randint(2, 50) if "MANUFACTURER" in roles else 0,
                )

            # Create headquarters
            cities = [
                "Los Angeles",
                "New York",
                "Chicago",
                "Houston",
                "Phoenix",
                "Philadelphia",
                "San Antonio",
                "San Diego",
                "Dallas",
                "San Jose",
            ]
            states = ["CA", "NY", "IL", "TX", "AZ", "PA", "TX", "CA", "TX", "CA"]
            city_state = random.choice(list(zip(cities, states, strict=False)))

            CompanyHeadquarters.objects.create(
                company=company,
                city=city_state[0],
                state_province=city_state[1],
                country="USA",
                street_address=f"{random.randint(100, 9999)} {random.choice(['Business', 'Corporate', 'Industry', 'Commerce'])} {random.choice(['Pkwy', 'Blvd', 'Dr', 'Way'])}",
                postal_code=f"{random.randint(10000, 99999)}",
            )

            companies.append(company)

        self.stdout.write(f"  ✅ Created {len(companies)} companies")
        return companies

    def create_ride_models(self, count: int, companies: list) -> list[RideModel]:
        """Create ride models from manufacturers"""
        self.stdout.write(f"🎢 Creating {count} ride models...")

        manufacturers = [c for c in companies if "MANUFACTURER" in c.roles]
        if not manufacturers:
            self.stdout.write("  ⚠️  No manufacturers found, skipping ride models")
            return []

        ride_models = []

        # Famous ride models
        famous_models = [
            ("Dive Coaster", "RC", "Bolliger & Mabillard", "Vertical drop roller coaster with holding brake"),
            ("Hyper Coaster", "RC", "Bolliger & Mabillard", "High-speed out-and-back roller coaster"),
            ("Wing Coaster", "RC", "Bolliger & Mabillard", "Seats positioned on sides of track"),
            ("Accelerator Coaster", "RC", "Intamin", "Hydraulic launch roller coaster"),
            ("Mega Coaster", "RC", "Intamin", "High-speed steel roller coaster"),
            ("Boomerang", "RC", "Vekoma", "Shuttle roller coaster with inversions"),
            ("SLC", "RC", "Vekoma", "Suspended Looping Coaster"),
            ("I-Box Track", "RC", "Rocky Mountain Construction", "Steel track on wooden structure"),
            ("Raptor Track", "RC", "Rocky Mountain Construction", "Single rail roller coaster"),
            ("BigDipper", "RC", "Mack Rides", "Family roller coaster"),
            ("Launched Coaster", "RC", "Mack Rides", "LSM launched roller coaster"),
            ("Infinity Coaster", "RC", "Gerstlauer", "Compact looping roller coaster"),
            ("Sky Rocket II", "RC", "Premier Rides", "Compact launched roller coaster"),
            ("Air Coaster", "RC", "S&S Worldwide", "Compressed air launched coaster"),
            ("Dark Ride System", "DR", "Mack Rides", "Trackless dark ride vehicles"),
            ("Omnimover", "DR", "Walt Disney Company", "Continuous loading dark ride system"),
            ("Log Flume", "WR", "Mack Rides", "Water ride with drops"),
            ("Rapids Ride", "WR", "Intamin", "Whitewater rafting experience"),
            ("Drop Tower", "FR", "Intamin", "Vertical drop ride"),
            ("Gyro Drop", "FR", "Intamin", "Tilting drop tower"),
        ]

        for model_name, category, manufacturer_name, description in famous_models:
            manufacturer = next((c for c in manufacturers if manufacturer_name in c.name), None)
            if not manufacturer:
                manufacturer = random.choice(manufacturers)

            ride_model, created = RideModel.objects.get_or_create(
                name=model_name,
                manufacturer=manufacturer,
                defaults={
                    "description": description,
                    "category": category,
                    "first_installation_year": random.randint(1980, 2020),
                    "is_discontinued": random.choice([True, False]),
                    "target_market": random.choice(["FAMILY", "THRILL", "EXTREME"]),
                    "typical_height_range_min_ft": (
                        random.randint(50, 200) if category == "RC" else random.randint(20, 100)
                    ),
                    "typical_height_range_max_ft": (
                        random.randint(200, 400) if category == "RC" else random.randint(100, 200)
                    ),
                    "typical_speed_range_min_mph": (
                        random.randint(20, 60) if category == "RC" else random.randint(5, 30)
                    ),
                    "typical_speed_range_max_mph": (
                        random.randint(60, 120) if category == "RC" else random.randint(30, 60)
                    ),
                    "typical_capacity_range_min": random.randint(500, 1000),
                    "typical_capacity_range_max": random.randint(1000, 2000),
                    "track_type": random.choice(["Steel", "Wood", "Hybrid"]) if category == "RC" else "Steel",
                    "support_structure": random.choice(["Steel", "Wood", "Concrete"]),
                    "train_configuration": f"{random.randint(2, 4)} trains, {random.randint(6, 8)} cars per train",
                    "restraint_system": random.choice(["Over-shoulder", "Lap bar", "Vest", "None"]),
                    "notable_features": "High-speed elements, smooth ride experience",
                    "total_installations": random.randint(1, 50),
                },
            )

            # Create technical specs if model exists
            if category == "RC" and RideModelTechnicalSpec:
                specs = [
                    ("DIMENSIONS", "Track Length", f"{random.randint(2000, 8000)}", "ft"),
                    ("PERFORMANCE", "Max G-Force", f"{random.uniform(3.0, 5.0):.1f}", "G"),
                    ("CAPACITY", "Riders per Train", f"{random.randint(20, 32)}", "people"),
                    ("SAFETY", "Block Zones", f"{random.randint(4, 8)}", "zones"),
                ]

                for spec_category, spec_name, spec_value, spec_unit in specs:
                    RideModelTechnicalSpec.objects.create(
                        ride_model=ride_model,
                        spec_category=spec_category,
                        spec_name=spec_name,
                        spec_value=spec_value,
                        spec_unit=spec_unit,
                    )

            # Create variants for some models if model exists
            if random.random() < 0.3 and RideModelVariant:
                variant_names = ["Compact", "Extended", "Family", "Extreme", "Custom"]
                variant_name = random.choice(variant_names)

                RideModelVariant.objects.create(
                    ride_model=ride_model,
                    name=f"{variant_name} Version",
                    description=f"Modified version of {model_name} for {variant_name.lower()} installations",
                    distinguishing_features=f"Optimized for {variant_name.lower()} market segment",
                )

            ride_models.append(ride_model)

        # Create additional random models
        model_types = ["Coaster", "Ride", "System", "Experience", "Adventure"]
        prefixes = ["Mega", "Super", "Ultra", "Hyper", "Giga", "Extreme", "Family", "Junior"]

        for _i in range(len(famous_models), count):
            manufacturer = random.choice(manufacturers)
            category = random.choice(["RC", "DR", "FR", "WR", "TR"])

            model_name = f"{random.choice(prefixes)} {random.choice(model_types)}"

            ride_model = RideModel.objects.create(
                name=model_name,
                manufacturer=manufacturer,
                description=f"Advanced {model_name.lower()} system designed for modern theme parks",
                category=category,
                first_installation_year=random.randint(1990, 2023),
                is_discontinued=random.choice([True, False]),
                target_market=random.choice(["FAMILY", "THRILL", "EXTREME", "ALL_AGES"]),
                typical_height_range_min_ft=random.randint(20, 150),
                typical_height_range_max_ft=random.randint(150, 350),
                typical_speed_range_min_mph=random.randint(10, 50),
                typical_speed_range_max_mph=random.randint(50, 100),
                typical_capacity_range_min=random.randint(400, 800),
                typical_capacity_range_max=random.randint(800, 1800),
                track_type=random.choice(["Steel", "Wood", "Hybrid", "Trackless"]),
                support_structure=random.choice(["Steel", "Wood", "Concrete", "Hybrid"]),
                train_configuration=f"{random.randint(1, 3)} trains, {random.randint(4, 12)} cars per train",
                restraint_system=random.choice(["Over-shoulder", "Lap bar", "Vest", "Seatbelt", "None"]),
                notable_features=random.choice(
                    [
                        "Smooth ride experience",
                        "High-speed elements",
                        "Family-friendly design",
                        "Innovative technology",
                        "Compact footprint",
                    ]
                ),
                total_installations=random.randint(0, 25),
            )

            ride_models.append(ride_model)

        self.stdout.write(f"  ✅ Created {len(ride_models)} ride models")
        return ride_models

    def create_parks(self, count: int, companies: list) -> list[Park]:
        """Create parks with locations and areas"""
        self.stdout.write(f"🏰 Creating {count} parks...")

        if count == 0:
            self.stdout.write("  ℹ️  Skipping park creation (count = 0)")
            return []

        operators = [c for c in companies if "OPERATOR" in c.roles]
        property_owners = [c for c in companies if "PROPERTY_OWNER" in c.roles]

        if not operators:
            raise CommandError("No operators found. Create companies first.")

        parks = []

        # Famous theme parks with timezone information
        famous_parks = [
            (
                "Magic Kingdom",
                "Walt Disney World's flagship theme park",
                "THEME_PARK",
                "OPERATING",
                date(1971, 10, 1),
                107,
                "Orlando",
                "FL",
                "USA",
                28.4177,
                -81.5812,
                "America/New_York",
            ),
            (
                "Disneyland",
                "The original Disney theme park",
                "THEME_PARK",
                "OPERATING",
                date(1955, 7, 17),
                85,
                "Anaheim",
                "CA",
                "USA",
                33.8121,
                -117.9190,
                "America/Los_Angeles",
            ),
            (
                "Universal Studios Hollywood",
                "Movie studio and theme park",
                "THEME_PARK",
                "OPERATING",
                date(1964, 7, 15),
                415,
                "Universal City",
                "CA",
                "USA",
                34.1381,
                -118.3534,
                "America/Los_Angeles",
            ),
            (
                "Cedar Point",
                "Roller coaster capital of the world",
                "AMUSEMENT_PARK",
                "OPERATING",
                date(1870, 5, 30),
                364,
                "Sandusky",
                "OH",
                "USA",
                41.4814,
                -82.6838,
                "America/New_York",
            ),
            (
                "Six Flags Magic Mountain",
                "Thrill capital of the world",
                "THEME_PARK",
                "OPERATING",
                date(1971, 5, 29),
                262,
                "Valencia",
                "CA",
                "USA",
                34.4244,
                -118.5969,
                "America/Los_Angeles",
            ),
            (
                "Knott's Berry Farm",
                "America's first theme park",
                "THEME_PARK",
                "OPERATING",
                date(1920, 6, 1),
                57,
                "Buena Park",
                "CA",
                "USA",
                33.8442,
                -117.9981,
                "America/Los_Angeles",
            ),
            (
                "Busch Gardens Tampa",
                "African-themed adventure park",
                "THEME_PARK",
                "OPERATING",
                date(1959, 3, 31),
                335,
                "Tampa",
                "FL",
                "USA",
                28.0373,
                -82.4194,
                "America/New_York",
            ),
            (
                "SeaWorld Orlando",
                "Marine life theme park",
                "THEME_PARK",
                "OPERATING",
                date(1973, 12, 15),
                200,
                "Orlando",
                "FL",
                "USA",
                28.4110,
                -81.4610,
                "America/New_York",
            ),
        ]

        for (
            park_name,
            description,
            park_type,
            status,
            opening_date,
            size_acres,
            city,
            state,
            country,
            lat,
            lng,
            timezone_str,
        ) in famous_parks:
            # Find appropriate operator
            operator = None
            if "Disney" in park_name:
                operator = next((c for c in operators if "Disney" in c.name), None)
            elif "Universal" in park_name:
                operator = next((c for c in operators if "Universal" in c.name), None)
            elif "Cedar Point" in park_name:
                operator = next((c for c in operators if "Cedar Fair" in c.name), None)
            elif "Six Flags" in park_name:
                operator = next((c for c in operators if "Six Flags" in c.name), None)
            elif "Knott" in park_name:
                operator = next((c for c in operators if "Knott" in c.name), None)
            elif "Busch" in park_name:
                operator = next((c for c in operators if "Busch" in c.name), None)
            elif "SeaWorld" in park_name:
                operator = next((c for c in operators if "SeaWorld" in c.name), None)

            if not operator:
                operator = random.choice(operators)

            # Find property owner (could be same as operator)
            property_owner = None
            if property_owners and random.random() < 0.7:
                property_owner = random.choice(property_owners)

            # Use get_or_create to avoid duplicates
            park, created = Park.objects.get_or_create(
                name=park_name,
                defaults={
                    "description": description,
                    "park_type": park_type,
                    "status": status,
                    "opening_date": opening_date,
                    "size_acres": Decimal(str(size_acres)),
                    "operator": operator,
                    "property_owner": property_owner,
                    "average_rating": Decimal(str(random.uniform(7.5, 9.5))),
                    "ride_count": random.randint(20, 60),
                    "coaster_count": random.randint(5, 20),
                    "timezone": timezone_str,
                },
            )
            if not created:
                self.stdout.write(f"  ℹ️  Using existing park: {park_name}")

            # Create park location only if it doesn't exist
            location_exists = False
            try:
                location_exists = hasattr(park, "location") and park.location is not None
            except Exception:
                location_exists = False

            if created or not location_exists:
                ParkLocation.objects.get_or_create(
                    park=park,
                    defaults={
                        "point": Point(lng, lat),
                        "street_address": f"{random.randint(100, 9999)} {park_name} Dr",
                        "city": city,
                        "state": state,
                        "country": country,
                        "postal_code": f"{random.randint(10000, 99999)}" if country == "USA" else "",
                    },
                )

            # Create park areas only if park was created
            if created:
                area_names = ["Main Street", "Fantasyland", "Tomorrowland", "Adventureland", "Frontierland"]
                for area_name in random.sample(area_names, random.randint(2, 4)):
                    ParkArea.objects.get_or_create(
                        park=park,
                        name=area_name,
                        defaults={
                            "description": f"Themed area within {park_name}",
                        },
                    )

            parks.append(park)

        # Create additional random parks
        park_types = ["THEME_PARK", "AMUSEMENT_PARK", "WATER_PARK", "FAMILY_ENTERTAINMENT_CENTER"]
        cities_data = [
            ("Los Angeles", "CA", "USA", 34.0522, -118.2437),
            ("New York", "NY", "USA", 40.7128, -74.0060),
            ("Chicago", "IL", "USA", 41.8781, -87.6298),
            ("Houston", "TX", "USA", 29.7604, -95.3698),
            ("Phoenix", "AZ", "USA", 33.4484, -112.0740),
            ("Philadelphia", "PA", "USA", 39.9526, -75.1652),
            ("San Antonio", "TX", "USA", 29.4241, -98.4936),
            ("San Diego", "CA", "USA", 32.7157, -117.1611),
        ]

        for i in range(len(famous_parks), count):
            park_type = random.choice(park_types)
            # Make park names more unique by adding a number
            park_name = f"{random.choice(['Adventure', 'Magic', 'Wonder', 'Fantasy', 'Thrill', 'Family'])} {random.choice(['World', 'Land', 'Park', 'Kingdom', 'Gardens'])} {i + 1}"

            operator = random.choice(operators)
            property_owner = random.choice(property_owners) if property_owners and random.random() < 0.5 else None

            city, state, country, lat, lng = random.choice(cities_data)

            # Determine timezone based on state
            timezone_map = {
                "CA": "America/Los_Angeles",
                "NY": "America/New_York",
                "IL": "America/Chicago",
                "TX": "America/Chicago",
                "AZ": "America/Phoenix",
                "PA": "America/New_York",
            }
            park_timezone = timezone_map.get(state, "America/New_York")

            park = Park.objects.create(
                name=park_name,
                description=f"Exciting {park_type.lower().replace('_', ' ')} featuring thrilling rides and family entertainment",
                park_type=park_type,
                status=random.choice(["OPERATING", "OPERATING", "OPERATING", "CLOSED_TEMP"]),
                opening_date=date(random.randint(1950, 2020), random.randint(1, 12), random.randint(1, 28)),
                size_acres=Decimal(str(random.randint(50, 500))),
                operator=operator,
                property_owner=property_owner,
                average_rating=Decimal(str(random.uniform(6.0, 9.0))),
                ride_count=random.randint(10, 40),
                coaster_count=random.randint(2, 15),
                timezone=park_timezone,
            )

            # Create park location with slight coordinate variation
            lat_offset = random.uniform(-0.1, 0.1)
            lng_offset = random.uniform(-0.1, 0.1)

            ParkLocation.objects.create(
                park=park,
                point=Point(lng + lng_offset, lat + lat_offset),
                street_address=f"{random.randint(100, 9999)} {random.choice(['Park', 'Theme', 'Fun', 'Adventure'])} {random.choice(['Way', 'Dr', 'Blvd', 'Ave'])}",
                city=city,
                state=state,
                country=country,
                postal_code=f"{random.randint(10000, 99999)}",
            )

            # Create park areas
            area_names = ["Main Plaza", "Adventure Zone", "Family Area", "Thrill Section", "Water World", "Kids Corner"]
            for area_name in random.sample(area_names, random.randint(2, 4)):
                ParkArea.objects.create(
                    park=park,
                    name=area_name,
                    description=f"Themed area within {park_name}",
                )

            parks.append(park)

        self.stdout.write(f"  ✅ Created {len(parks)} parks")
        return parks

    def create_rides(self, count: int, parks: list[Park], companies: list, ride_models: list[RideModel]) -> list[Ride]:
        """Create rides with comprehensive details"""
        self.stdout.write(f"🎠 Creating {count} rides...")

        if not parks:
            self.stdout.write("  ⚠️  No parks found, skipping rides")
            return []

        manufacturers = [c for c in companies if "MANUFACTURER" in c.roles]
        designers = [c for c in companies if "DESIGNER" in c.roles]

        rides = []

        # Famous roller coasters
        famous_coasters = [
            ("Steel Vengeance", "RC", "Hybrid steel-wood roller coaster", "Rocky Mountain Construction"),
            ("Millennium Force", "RC", "Giga coaster with 300-foot drop", "Intamin"),
            ("The Beast", "RC", "Legendary wooden roller coaster", None),
            ("Fury 325", "RC", "Giga coaster with 325-foot height", "Bolliger & Mabillard"),
            ("Lightning Rod", "RC", "Launched wooden roller coaster", "Rocky Mountain Construction"),
            ("Maverick", "RC", "Multi-launch roller coaster", "Intamin"),
            ("El Toro", "RC", "Wooden roller coaster with steep drops", "Intamin"),
            ("Intimidator 305", "RC", "Giga coaster with intense elements", "Intamin"),
            ("Twisted Timbers", "RC", "RMC conversion of wooden coaster", "Rocky Mountain Construction"),
            ("Goliath", "RC", "Hyper coaster with massive drops", "Bolliger & Mabillard"),
        ]

        # Create famous coasters
        for coaster_name, category, description, manufacturer_name in famous_coasters:
            park = random.choice(parks)
            manufacturer = None
            if manufacturer_name:
                manufacturer = next((c for c in manufacturers if manufacturer_name in c.name), None)
            if not manufacturer and manufacturers:
                manufacturer = random.choice(manufacturers)

            designer = random.choice(designers) if designers and random.random() < 0.3 else None
            ride_model = random.choice(ride_models) if ride_models and random.random() < 0.5 else None

            # Get park areas for this park
            park_areas = list(park.areas.all())
            park_area = random.choice(park_areas) if park_areas else None

            ride = Ride.objects.create(
                name=coaster_name,
                description=description,
                park=park,
                park_area=park_area,
                category=category,
                manufacturer=manufacturer,
                designer=designer,
                ride_model=ride_model,
                status=random.choice(["OPERATING"] * 8 + ["CLOSED_TEMP", "SBNO"]),
                opening_date=date(random.randint(1990, 2023), random.randint(1, 12), random.randint(1, 28)),
                min_height_in=random.choice([48, 52, 54, 60]),
                capacity_per_hour=random.randint(800, 1800),
                ride_duration_seconds=random.randint(90, 240),
                average_rating=Decimal(str(random.uniform(7.0, 9.5))),
            )

            # Create roller coaster stats
            if category == "RC":
                RollerCoasterStats.objects.create(
                    ride=ride,
                    height_ft=Decimal(str(random.randint(100, 350))),
                    length_ft=Decimal(str(random.randint(2000, 8000))),
                    speed_mph=Decimal(str(random.randint(45, 120))),
                    inversions=random.randint(0, 8),
                    ride_time_seconds=random.randint(90, 240),
                    track_type=random.choice(["Steel", "Wood", "Hybrid"]),
                    track_material=random.choice(["STEEL", "WOOD", "HYBRID"]),
                    roller_coaster_type=random.choice(["SITDOWN", "INVERTED", "WING", "DIVE", "FLYING"]),
                    max_drop_height_ft=Decimal(str(random.randint(80, 300))),
                    propulsion_system=random.choice(["CHAIN", "LSM", "HYDRAULIC"]),
                    train_style=random.choice(["Traditional", "Floorless", "Wing", "Flying"]),
                    trains_count=random.randint(2, 4),
                    cars_per_train=random.randint(6, 8),
                    seats_per_car=random.randint(2, 4),
                )

            rides.append(ride)

        # Create additional random rides
        ride_names = [
            "Thunder Mountain",
            "Space Coaster",
            "Wild Eagle",
            "Dragon Fire",
            "Phoenix Rising",
            "Storm Runner",
            "Lightning Strike",
            "Tornado Alley",
            "Hurricane Force",
            "Cyclone",
            "Viper",
            "Cobra",
            "Rattlesnake",
            "Sidewinder",
            "Diamondback",
            "Copperhead",
            "Banshee",
            "Valkyrie",
            "Griffon",
            "Falcon",
            "Eagle's Flight",
            "Soaring Heights",
        ]

        categories = ["RC", "DR", "FR", "WR", "TR", "OT"]

        for _i in range(len(famous_coasters), count):
            park = random.choice(parks)
            park_areas = list(park.areas.all())
            park_area = random.choice(park_areas) if park_areas else None

            ride_name = random.choice(ride_names)
            category = random.choice(categories)

            manufacturer = random.choice(manufacturers) if manufacturers and random.random() < 0.7 else None
            designer = random.choice(designers) if designers and random.random() < 0.2 else None
            ride_model = random.choice(ride_models) if ride_models and random.random() < 0.4 else None

            ride = Ride.objects.create(
                name=ride_name,
                description=f"Exciting {category} ride with thrilling elements and smooth operation",
                park=park,
                park_area=park_area,
                category=category,
                manufacturer=manufacturer,
                designer=designer,
                ride_model=ride_model,
                status=random.choice(["OPERATING"] * 9 + ["CLOSED_TEMP"]),
                opening_date=date(random.randint(1980, 2023), random.randint(1, 12), random.randint(1, 28)),
                min_height_in=random.choice([36, 42, 48, 52, 54]) if category != "DR" else None,
                capacity_per_hour=random.randint(400, 2000),
                ride_duration_seconds=random.randint(60, 300),
                average_rating=Decimal(str(random.uniform(6.0, 9.0))),
            )

            # Create roller coaster stats for RC category
            if category == "RC":
                RollerCoasterStats.objects.create(
                    ride=ride,
                    height_ft=Decimal(str(random.randint(50, 300))),
                    length_ft=Decimal(str(random.randint(1500, 6000))),
                    speed_mph=Decimal(str(random.randint(25, 100))),
                    inversions=random.randint(0, 6),
                    ride_time_seconds=random.randint(90, 180),
                    track_type=random.choice(["Steel", "Wood"]),
                    track_material=random.choice(["STEEL", "WOOD", "HYBRID"]),
                    roller_coaster_type=random.choice(["SITDOWN", "INVERTED", "FAMILY", "WILD_MOUSE"]),
                    max_drop_height_ft=Decimal(str(random.randint(40, 250))),
                    propulsion_system=random.choice(["CHAIN", "LSM", "GRAVITY"]),
                    train_style=random.choice(["Traditional", "Family", "Compact"]),
                    trains_count=random.randint(1, 3),
                    cars_per_train=random.randint(4, 8),
                    seats_per_car=random.randint(2, 4),
                )

            rides.append(ride)

        self.stdout.write(f"  ✅ Created {len(rides)} rides")
        return rides

    def create_reviews(self, count: int, users: list[User], parks: list[Park], rides: list[Ride]) -> None:
        """Create park and ride reviews"""
        self.stdout.write(f"📝 Creating {count} reviews...")

        if not users or (not parks and not rides):
            self.stdout.write("  ⚠️  No users or content found, skipping reviews")
            return

        review_texts = [
            "Amazing experience! The rides were thrilling and the staff was very friendly.",
            "Great park with excellent theming. The roller coasters are world-class.",
            "Had a fantastic time with the family. Something for everyone to enjoy.",
            "The wait times were reasonable and the food was surprisingly good.",
            "Incredible engineering and smooth operation. Highly recommended!",
            "Beautiful park with great attention to detail in every area.",
            "Thrilling rides and excellent maintenance. Will definitely return!",
            "Perfect for thrill seekers. The intensity is just right.",
            "Family-friendly atmosphere with rides for all ages.",
            "Outstanding park operations and friendly staff throughout.",
        ]

        # Create park reviews
        park_review_count = count // 2
        created_park_reviews = 0
        attempts = 0
        max_attempts = park_review_count * 3  # Allow multiple attempts to avoid infinite loops

        while created_park_reviews < park_review_count and attempts < max_attempts:
            if not parks:
                break

            user = random.choice(users)
            park = random.choice(parks)
            attempts += 1

            # Use get_or_create to avoid duplicates
            review, created = ParkReview.objects.get_or_create(
                user=user,
                park=park,
                defaults={
                    "rating": random.randint(6, 10),
                    "title": f"Great visit to {park.name}",
                    "content": random.choice(review_texts),
                    "is_published": random.choice([True] * 9 + [False]),
                    "visit_date": date(random.randint(2020, 2024), random.randint(1, 12), random.randint(1, 28)),
                },
            )

            if created:
                created_park_reviews += 1

        # Create ride reviews
        ride_review_count = count - created_park_reviews
        created_ride_reviews = 0
        attempts = 0
        max_attempts = ride_review_count * 3  # Allow multiple attempts to avoid infinite loops

        while created_ride_reviews < ride_review_count and attempts < max_attempts:
            if not rides:
                break

            user = random.choice(users)
            ride = random.choice(rides)
            attempts += 1

            # Use get_or_create to avoid duplicates
            review, created = RideReview.objects.get_or_create(
                user=user,
                ride=ride,
                defaults={
                    "rating": random.randint(6, 10),
                    "title": f"Awesome ride - {ride.name}",
                    "content": random.choice(review_texts),
                    "is_published": random.choice([True] * 9 + [False]),
                    "visit_date": date(random.randint(2020, 2024), random.randint(1, 12), random.randint(1, 28)),
                },
            )

            if created:
                created_ride_reviews += 1

        self.stdout.write(f"  ✅ Created {count} reviews")

    def create_notifications(self, users: list[User]) -> None:
        """Create sample notifications for users"""
        self.stdout.write("🔔 Creating notifications...")

        if not users:
            self.stdout.write("  ⚠️  No users found, skipping notifications")
            return

        notification_count = 0

        notification_types = [
            (
                "submission_approved",
                "Your park submission has been approved!",
                "Great news! Your submission for Adventure Park has been approved and is now live.",
            ),
            (
                "review_helpful",
                "Someone found your review helpful",
                "Your review of Steel Vengeance was marked as helpful by another user.",
            ),
            (
                "system_announcement",
                "New features available",
                "Check out our new ride comparison tool and enhanced search filters.",
            ),
            (
                "achievement_unlocked",
                "Achievement unlocked!",
                "Congratulations! You've unlocked the 'Coaster Enthusiast' achievement.",
            ),
        ]

        # Create notifications for random users
        for user in random.sample(users, min(len(users), 15)):
            for _ in range(random.randint(1, 3)):
                notification_type, title, message = random.choice(notification_types)

                UserNotification.objects.create(
                    user=user,
                    notification_type=notification_type,
                    title=title,
                    message=message,
                    priority=random.choice(["normal"] * 3 + ["high"]),
                    is_read=random.choice([True, False]),
                    email_sent=random.choice([True, False]),
                    push_sent=random.choice([True, False]),
                )
                notification_count += 1

        self.stdout.write(f"  ✅ Created {notification_count} notifications")

    def create_moderation_data(self, users: list[User], parks: list[Park], rides: list[Ride]) -> None:
        """Create moderation queue and actions"""
        self.stdout.write("🛡️  Creating moderation data...")

        if not ModerationQueue or not ModerationAction:
            self.stdout.write("  ⚠️  Moderation models not available, skipping")
            return

        if not users or (not parks and not rides):
            self.stdout.write("  ⚠️  No users or content found, skipping moderation data")
            return

        # This would create sample moderation queue items and actions
        # Implementation depends on the actual moderation models structure
        self.stdout.write("  ✅ Moderation data creation skipped (models not fully defined)")

    def create_photos(self, parks: list[Park], rides: list[Ride], ride_models: list[RideModel]) -> None:
        """Create sample photo records"""
        self.stdout.write("📸 Creating photo records...")

        if not CloudflareImage:
            self.stdout.write("  ⚠️  CloudflareImage model not available, skipping photo creation")
            return

        # Since we don't have actual Cloudflare images, we'll skip photo creation
        # In a real scenario, you would need actual CloudflareImage instances
        self.stdout.write("  ⚠️  Photo creation skipped (requires actual CloudflareImage instances)")
        self.stdout.write("  ℹ️  To create photos, you need to upload actual images to Cloudflare first")

    def create_rankings(self, rides: list[Ride]) -> None:
        """Create ride rankings if model exists"""
        self.stdout.write("🏆 Creating ride rankings...")

        if not RideRanking:
            self.stdout.write("  ⚠️  RideRanking model not available, skipping")
            return

        if not rides:
            self.stdout.write("  ⚠️  No rides found, skipping rankings")
            return

        # This would create sample ride rankings
        # Implementation depends on the actual RideRanking model structure
        self.stdout.write("  ✅ Ride rankings creation skipped (model structure not fully defined)")

    def print_summary(self) -> None:
        """Print a summary of created data"""
        self.stdout.write("\n📊 Data Seeding Summary:")
        self.stdout.write("=" * 50)

        # Count all created objects
        counts = {
            "Users": User.objects.count(),
            "Park Companies": ParkCompany.objects.count(),
            "Ride Companies": RideCompany.objects.count(),
            "Parks": Park.objects.count(),
            "Rides": Ride.objects.count(),
            "Ride Models": RideModel.objects.count(),
            "Park Reviews": ParkReview.objects.count(),
            "Ride Reviews": RideReview.objects.count(),
            "Notifications": UserNotification.objects.count(),
            "Park Photos": ParkPhoto.objects.count(),
            "Ride Photos": RidePhoto.objects.count(),
        }

        for model_name, count in counts.items():
            self.stdout.write(f"  {model_name}: {count}")

        self.stdout.write("=" * 50)
        self.stdout.write("🎉 Seeding completed! Your ThrillWiki database is ready for testing.")
