#!/usr/bin/env python
"""
BaoLife Asset URL Updater

Automatically updates education_manager.py and shop_manager.py with new
generated image URLs from the database.

Usage:
    python update_asset_urls.py --preview    # Show what will be changed
    python update_asset_urls.py --update     # Actually update the files
    python update_asset_urls.py --backup     # Create backup before updating
"""

import argparse
import logging
import re
import shutil
from pathlib import Path
from datetime import datetime
from database.db_operations import get_database_connection

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# File paths
EDUCATION_MANAGER = Path(__file__).parent / "education" / "education_manager.py"
SHOP_MANAGER = Path(__file__).parent / "shop" / "shop_manager.py"


# ============================================================
# Database Queries
# ============================================================

def get_elementary_school_urls():
    """Get elementary school URLs in correct order"""
    db = get_database_connection()
    cursor = db.cursor(dictionary=True)

    cursor.execute("""
        SELECT event_type, image_url
        FROM generated_images
        WHERE event_category = 'education_elementary'
        ORDER BY id
    """)

    results = cursor.fetchall()
    logger.info(f"Found {len(results)} elementary school images")
    return [r['image_url'] for r in results]


def get_high_school_urls():
    """Get high school URLs in correct order"""
    db = get_database_connection()
    cursor = db.cursor(dictionary=True)

    cursor.execute("""
        SELECT event_type, image_url
        FROM generated_images
        WHERE event_category = 'education_high_school'
        ORDER BY id
    """)

    results = cursor.fetchall()
    logger.info(f"Found {len(results)} high school images")
    return [r['image_url'] for r in results]


def get_college_urls():
    """Get college URLs in correct order"""
    db = get_database_connection()
    cursor = db.cursor(dictionary=True)

    cursor.execute("""
        SELECT event_type, image_url
        FROM generated_images
        WHERE event_category = 'education_college'
        ORDER BY id
    """)

    results = cursor.fetchall()
    logger.info(f"Found {len(results)} college images")
    return [r['image_url'] for r in results]


def get_shop_item_urls():
    """Get shop item URLs mapped by event_type"""
    db = get_database_connection()
    cursor = db.cursor(dictionary=True)

    cursor.execute("""
        SELECT event_type, image_url
        FROM generated_images
        WHERE event_category = 'shop_item'
        ORDER BY id
    """)

    results = cursor.fetchall()
    logger.info(f"Found {len(results)} shop item images")

    # Map by event_type for easier lookup
    return {r['event_type']: r['image_url'] for r in results}


def get_extracurricular_urls():
    """Get extracurricular activity URLs mapped by event_type"""
    db = get_database_connection()
    cursor = db.cursor(dictionary=True)

    cursor.execute("""
        SELECT event_type, image_url
        FROM generated_images
        WHERE event_category = 'education_extracurricular'
        ORDER BY id
    """)

    results = cursor.fetchall()
    logger.info(f"Found {len(results)} extracurricular images")

    # Map by event_type for easier lookup
    return {r['event_type']: r['image_url'] for r in results}


# ============================================================
# File Update Functions
# ============================================================

def update_education_manager(elementary_urls, high_school_urls, college_urls, extracurricular_urls, preview=True):
    """Update education_manager.py with new URLs"""
    logger.info(f"Updating {EDUCATION_MANAGER}")

    with open(EDUCATION_MANAGER, 'r') as f:
        content = f.read()

    original_content = content
    updates = []

    # Update elementary schools (6 schools)
    # Pattern matches both Discord and Midjourney URLs
    elementary_pattern = r"elementary_schools\.append\(ElementarySchoolClass\([^)]+,\s*'(https://[^']+)'\)\)"
    elementary_matches = list(re.finditer(elementary_pattern, content))

    if len(elementary_matches) != len(elementary_urls):
        logger.warning(f"Mismatch: Found {len(elementary_matches)} elementary schools in code, but {len(elementary_urls)} URLs")

    for i, match in enumerate(elementary_matches):
        if i < len(elementary_urls):
            old_url = match.group(1)
            new_url = elementary_urls[i]
            content = content.replace(old_url, new_url)
            updates.append(f"Elementary school {i+1}: {old_url[:50]}... → {new_url[:50]}...")

    # Update high schools (6 schools)
    # Pattern matches both Discord and Midjourney URLs
    high_school_pattern = r"high_schools\.append\(HighSchoolClass\([^)]+,\s*'(https://[^']+)'\)\)"
    high_school_matches = list(re.finditer(high_school_pattern, content))

    if len(high_school_matches) != len(high_school_urls):
        logger.warning(f"Mismatch: Found {len(high_school_matches)} high schools in code, but {len(high_school_urls)} URLs")

    for i, match in enumerate(high_school_matches):
        if i < len(high_school_urls):
            old_url = match.group(1)
            new_url = high_school_urls[i]
            content = content.replace(old_url, new_url)
            updates.append(f"High school {i+1}: {old_url[:50]}... → {new_url[:50]}...")

    # Update colleges (10 colleges)
    # Pattern matches both Discord and Midjourney URLs
    college_pattern = r"colleges\.append\(CollegeClass\([^)]+,\s*'(https://[^']+)'\)\)"
    college_matches = list(re.finditer(college_pattern, content))

    if len(college_matches) != len(college_urls):
        logger.warning(f"Mismatch: Found {len(college_matches)} colleges in code, but {len(college_urls)} URLs")

    for i, match in enumerate(college_matches):
        if i < len(college_urls):
            old_url = match.group(1)
            new_url = college_urls[i]
            content = content.replace(old_url, new_url)
            updates.append(f"College {i+1}: {old_url[:50]}... → {new_url[:50]}...")

    # Update extracurricular activities (6 activities)
    # Pattern: ExtraCurricular('Name', 'type', 'desc', priority, 'URL')
    # Map activity names to event_types
    extracurricular_mappings = {
        "Debate Team": "debate_team",
        "Robotics Team": "robotics_team",
        "Baseball": "baseball_team",
        "Basketball": "basketball_team",
        "Soccer": "soccer_team",
        "Football": "football_team",
    }

    extracurricular_pattern = r"extraCurriculars\.append\(ExtraCurricular\('([^']+)',\s*'[^']+',\s*'[^']+',\s*\d+,\s*'(https://[^']+)'\)\)"

    for match in re.finditer(extracurricular_pattern, content):
        activity_name = match.group(1)
        old_url = match.group(2)

        # Find corresponding event_type
        event_type = extracurricular_mappings.get(activity_name)

        if event_type and event_type in extracurricular_urls:
            new_url = extracurricular_urls[event_type]
            content = content.replace(old_url, new_url)
            updates.append(f"Extracurricular '{activity_name}': {old_url[:50]}... → {new_url[:50]}...")
        elif "discord" in old_url.lower() or "midjourney" in old_url.lower():
            logger.warning(f"No mapping found for extracurricular: {activity_name}")

    # Show preview or write
    if preview:
        logger.info("\nPREVIEW - education_manager.py changes:")
        for update in updates:
            logger.info(f"  {update}")
        logger.info(f"\nTotal changes: {len(updates)}")
    else:
        with open(EDUCATION_MANAGER, 'w') as f:
            f.write(content)
        logger.info(f"✓ Updated {EDUCATION_MANAGER} with {len(updates)} changes")

    return len(updates)


def update_shop_manager(shop_urls, preview=True):
    """Update shop_manager.py with new URLs"""
    logger.info(f"Updating {SHOP_MANAGER}")

    with open(SHOP_MANAGER, 'r') as f:
        content = f.read()

    original_content = content
    updates = []

    # Mapping of item names to event_types
    item_mappings = {
        "Case of Energy Drinks": "energy_drinks",
        "Sports Car": "sports_car",
        "Designer Suit": "designer_suit",
        "Artisan Coffee Machine": "coffee_machine",
        "Designer Handbag": "handbag",
        "Diamond Ring": "diamond_ring",
        "Rare Wine": "rare_wine",
        "Limited Edition Sneakers": "sneakers",
        "Designer Sunglasses": "sunglasses",
        "Luxury Fragrance": "perfume",
    }

    # Update StoreItem entries that have image URLs
    # Pattern: StoreItem("Name", price, "desc", prestige, "URL")
    store_item_pattern = r'StoreItem\("([^"]+)",\s*\d+,\s*"[^"]+",\s*\d+,\s*"([^"]+)"\)'

    for match in re.finditer(store_item_pattern, content):
        item_name = match.group(1)
        old_url = match.group(2)

        # Find corresponding event_type
        event_type = item_mappings.get(item_name)

        if event_type and event_type in shop_urls:
            new_url = shop_urls[event_type]
            content = content.replace(old_url, new_url)
            updates.append(f"{item_name}: {old_url[:50]}... → {new_url[:50]}...")
        elif "discord" in old_url.lower():
            logger.warning(f"No mapping found for item: {item_name}")

    # Update InAppPurchaseItem (Diamond packs)
    if "diamonds" in shop_urls:
        diamond_url = shop_urls["diamonds"]
        # Replace the default diamond image in InAppPurchaseItem.__init__
        diamond_pattern = r'self\.image = "https://cdn\.discordapp\.com/[^"]+"'
        if re.search(diamond_pattern, content):
            content = re.sub(diamond_pattern, f'self.image = "{diamond_url}"', content)
            updates.append(f"Diamond pack default image: → {diamond_url[:50]}...")

        # Also update specific diamond pack URLs
        diamond_pack_pattern = r'InAppPurchaseItem\([^)]+,\s*"([^"]+)"\)'
        for match in re.finditer(diamond_pack_pattern, content):
            old_url = match.group(1)
            if "discord" in old_url.lower():
                content = content.replace(old_url, diamond_url)
                updates.append(f"Diamond pack: {old_url[:50]}... → {diamond_url[:50]}...")

    # Show preview or write
    if preview:
        logger.info("\nPREVIEW - shop_manager.py changes:")
        for update in updates:
            logger.info(f"  {update}")
        logger.info(f"\nTotal changes: {len(updates)}")
    else:
        with open(SHOP_MANAGER, 'w') as f:
            f.write(content)
        logger.info(f"✓ Updated {SHOP_MANAGER} with {len(updates)} changes")

    return len(updates)


# ============================================================
# Backup Function
# ============================================================

def create_backups():
    """Create backup copies of files before updating"""
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

    backups = []

    if EDUCATION_MANAGER.exists():
        backup_path = EDUCATION_MANAGER.parent / f"education_manager.py.backup_{timestamp}"
        shutil.copy2(EDUCATION_MANAGER, backup_path)
        logger.info(f"✓ Created backup: {backup_path}")
        backups.append(backup_path)

    if SHOP_MANAGER.exists():
        backup_path = SHOP_MANAGER.parent / f"shop_manager.py.backup_{timestamp}"
        shutil.copy2(SHOP_MANAGER, backup_path)
        logger.info(f"✓ Created backup: {backup_path}")
        backups.append(backup_path)

    return backups


# ============================================================
# Main
# ============================================================

def main():
    parser = argparse.ArgumentParser(
        description="Update Python files with new generated image URLs"
    )

    parser.add_argument(
        '--preview',
        action='store_true',
        help='Preview changes without updating files'
    )

    parser.add_argument(
        '--update',
        action='store_true',
        help='Update files with new URLs'
    )

    parser.add_argument(
        '--backup',
        action='store_true',
        help='Create backup before updating'
    )

    args = parser.parse_args()

    # Default to preview if no action specified
    if not args.preview and not args.update:
        args.preview = True

    try:
        logger.info("Fetching generated image URLs from database...")

        # Get URLs from database
        elementary_urls = get_elementary_school_urls()
        high_school_urls = get_high_school_urls()
        college_urls = get_college_urls()
        extracurricular_urls = get_extracurricular_urls()
        shop_urls = get_shop_item_urls()

        logger.info(f"\nFound:")
        logger.info(f"  Elementary schools: {len(elementary_urls)}")
        logger.info(f"  High schools: {len(high_school_urls)}")
        logger.info(f"  Colleges: {len(college_urls)}")
        logger.info(f"  Extracurricular activities: {len(extracurricular_urls)}")
        logger.info(f"  Shop items: {len(shop_urls)}")
        logger.info("")

        # Validate we have the expected number
        if len(elementary_urls) != 6:
            logger.warning(f"Expected 6 elementary schools, found {len(elementary_urls)}")
        if len(high_school_urls) != 6:
            logger.warning(f"Expected 6 high schools, found {len(high_school_urls)}")
        if len(college_urls) != 10:
            logger.warning(f"Expected 10 colleges, found {len(college_urls)}")

        # Create backups if requested
        if args.backup and args.update:
            create_backups()

        # Update files
        preview_mode = args.preview or not args.update

        edu_changes = update_education_manager(
            elementary_urls,
            high_school_urls,
            college_urls,
            extracurricular_urls,
            preview=preview_mode
        )

        shop_changes = update_shop_manager(
            shop_urls,
            preview=preview_mode
        )

        # Summary
        logger.info("\n" + "="*70)
        if preview_mode:
            logger.info("PREVIEW MODE - No files were changed")
            logger.info(f"Total changes that would be made: {edu_changes + shop_changes}")
            logger.info("\nTo apply changes, run:")
            logger.info("  python update_asset_urls.py --update --backup")
        else:
            logger.info("UPDATE COMPLETE")
            logger.info(f"Total changes made: {edu_changes + shop_changes}")
            logger.info(f"  education_manager.py: {edu_changes} URLs updated")
            logger.info(f"  shop_manager.py: {shop_changes} URLs updated")
        logger.info("="*70)

    except Exception as e:
        logger.error(f"Error: {e}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    main()
