#!/usr/bin/env python3
"""
Combat Data Migration Script.

This script migrates existing inline combat encounter data from game_sessions
to the dedicated combat_encounters table.

The migration is idempotent - it's safe to run multiple times. Sessions that
have already been migrated (have active_combat_encounter_id) are skipped.

Usage:
    python scripts/migrate_combat_data.py

Note:
    - Run this after deploying the new combat database schema
    - The application handles automatic migration on-demand, so this is optional
    - This script is useful for proactively migrating all data at once
"""

import sys
import os
import json
from pathlib import Path

# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from dotenv import load_dotenv

# Load environment variables before importing app modules
load_dotenv()

from app.services.database_service import get_database_service
from app.services.combat_repository import get_combat_repository
from app.models.session import GameSession
from app.models.combat import CombatEncounter
from app.utils.logging import get_logger

logger = get_logger(__file__)


def migrate_inline_combat_encounters() -> dict:
    """
    Migrate all inline combat encounters to the dedicated table.

    Scans all game sessions for inline combat_encounter data and migrates
    them to the combat_encounters table. Updates sessions to use the new
    active_combat_encounter_id reference.

    Returns:
        Dict with migration statistics:
        - total_sessions: Number of sessions scanned
        - migrated: Number of sessions with combat data migrated
        - skipped: Number of sessions already migrated or without combat
        - errors: Number of sessions that failed to migrate
    """
    db = get_database_service()
    repo = get_combat_repository()

    stats = {
        'total_sessions': 0,
        'migrated': 0,
        'skipped': 0,
        'errors': 0,
        'error_details': []
    }

    print("Scanning game_sessions for inline combat data...")

    # Query all sessions (paginated)
    offset = 0
    limit = 100

    while True:
        try:
            rows = db.list_rows(
                table_id='game_sessions',
                limit=limit,
                offset=offset
            )
        except Exception as e:
            logger.error("Failed to query sessions", error=str(e))
            print(f"Error querying sessions: {e}")
            break

        if not rows:
            break

        for row in rows:
            stats['total_sessions'] += 1
            session_id = row.id

            try:
                # Parse session data
                session_json = row.data.get('sessionData', '{}')
                session_data = json.loads(session_json)

                # Check if already migrated (has reference, no inline data)
                if (session_data.get('active_combat_encounter_id') and
                    not session_data.get('combat_encounter')):
                    stats['skipped'] += 1
                    continue

                # Check if has inline combat data to migrate
                combat_data = session_data.get('combat_encounter')
                if not combat_data:
                    stats['skipped'] += 1
                    continue

                # Parse combat encounter
                encounter = CombatEncounter.from_dict(combat_data)
                user_id = session_data.get('user_id', row.data.get('userId', ''))

                logger.info("Migrating inline combat encounter",
                           session_id=session_id,
                           encounter_id=encounter.encounter_id)

                # Check if encounter already exists in repository
                existing = repo.get_encounter(encounter.encounter_id)
                if existing:
                    # Already migrated, just update session reference
                    session_data['active_combat_encounter_id'] = encounter.encounter_id
                    session_data['combat_encounter'] = None
                else:
                    # Save to repository
                    repo.create_encounter(
                        encounter=encounter,
                        session_id=session_id,
                        user_id=user_id
                    )
                    session_data['active_combat_encounter_id'] = encounter.encounter_id
                    session_data['combat_encounter'] = None

                # Update session
                db.update_row(
                    table_id='game_sessions',
                    row_id=session_id,
                    data={'sessionData': json.dumps(session_data)}
                )

                stats['migrated'] += 1
                print(f"  Migrated: {session_id} -> {encounter.encounter_id}")

            except Exception as e:
                stats['errors'] += 1
                error_msg = f"Session {session_id}: {str(e)}"
                stats['error_details'].append(error_msg)
                logger.error("Failed to migrate session",
                            session_id=session_id,
                            error=str(e))
                print(f"  Error: {session_id} - {e}")

        offset += limit

        # Safety check to prevent infinite loop
        if offset > 10000:
            print("Warning: Stopped after 10000 sessions (safety limit)")
            break

    return stats


def main():
    """Run the migration."""
    print("=" * 60)
    print("Code of Conquest - Combat Data Migration")
    print("=" * 60)
    print()

    # Verify environment variables
    required_vars = [
        'APPWRITE_ENDPOINT',
        'APPWRITE_PROJECT_ID',
        'APPWRITE_API_KEY',
        'APPWRITE_DATABASE_ID'
    ]

    missing_vars = [var for var in required_vars if not os.getenv(var)]
    if missing_vars:
        print("ERROR: Missing required environment variables:")
        for var in missing_vars:
            print(f"   - {var}")
        print()
        print("Please ensure your .env file is configured correctly.")
        sys.exit(1)

    print("Environment configuration:")
    print(f"  Endpoint: {os.getenv('APPWRITE_ENDPOINT')}")
    print(f"  Project: {os.getenv('APPWRITE_PROJECT_ID')}")
    print(f"  Database: {os.getenv('APPWRITE_DATABASE_ID')}")
    print()

    # Confirm before proceeding
    print("This script will migrate inline combat data to the dedicated")
    print("combat_encounters table. This operation is safe and idempotent.")
    print()
    response = input("Proceed with migration? (y/N): ").strip().lower()
    if response != 'y':
        print("Migration cancelled.")
        sys.exit(0)

    print()
    print("Starting migration...")
    print()

    try:
        stats = migrate_inline_combat_encounters()

        print()
        print("=" * 60)
        print("Migration Results")
        print("=" * 60)
        print()
        print(f"Total sessions scanned: {stats['total_sessions']}")
        print(f"Successfully migrated:  {stats['migrated']}")
        print(f"Skipped (no combat):    {stats['skipped']}")
        print(f"Errors:                 {stats['errors']}")
        print()

        if stats['error_details']:
            print("Error details:")
            for error in stats['error_details'][:10]:  # Show first 10
                print(f"  - {error}")
            if len(stats['error_details']) > 10:
                print(f"  ... and {len(stats['error_details']) - 10} more")
            print()

        if stats['errors'] > 0:
            print("Some sessions failed to migrate. Check logs for details.")
            sys.exit(1)
        else:
            print("Migration completed successfully!")

    except Exception as e:
        logger.error("Migration failed", error=str(e))
        print()
        print(f"MIGRATION FAILED: {str(e)}")
        print()
        print("Check logs for details.")
        sys.exit(1)


if __name__ == '__main__':
    main()
