"""Export current database data and generate a seeder script."""
from sqlmodel import Session, select
from typing import Dict, Any
import json

from app.core.database import engine
from app.models.route import Route
from app.models.bus_stop import BusStop
from app.models.route_stop import RouteStop
from app.models.bus_schedule import BusSchedule


def export_all_data() -> Dict[str, Any]:
    """Export all data from the database."""
    with Session(engine) as session:
        # Export routes
        routes = session.exec(select(Route)).all()
        routes_data = []
        for route in routes:
            routes_data.append({
                "id": str(route.id),
                "name": route.name,
                "description": route.description,
                "origin_city": route.origin_city,
                "destination_city": route.destination_city,
                "distance_km": route.distance_km,
                "estimated_duration_minutes": route.estimated_duration_minutes,
                "status": route.status.value if route.status else "active",
            })
        
        # Export bus stops
        bus_stops = session.exec(select(BusStop)).all()
        bus_stops_data = []
        for stop in bus_stops:
            bus_stops_data.append({
                "id": str(stop.id),
                "name": stop.name,
                "latitude": stop.latitude,
                "longitude": stop.longitude,
                "city": stop.city,
                "address": stop.address,
                "stop_type": stop.stop_type.value if stop.stop_type else "regular",
                "has_shelter": stop.has_shelter,
                "has_seating": stop.has_seating,
                "is_accessible": stop.is_accessible,
            })
        
        # Export route stops
        route_stops = session.exec(select(RouteStop)).all()
        route_stops_data = []
        for route_stop in route_stops:
            route_stops_data.append({
                "id": str(route_stop.id),
                "route_id": str(route_stop.route_id),
                "stop_id": str(route_stop.stop_id),
                "stop_order": route_stop.stop_order,
                "travel_time_minutes": route_stop.travel_time_minutes,
                "is_pickup_point": route_stop.is_pickup_point,
                "is_dropoff_point": route_stop.is_dropoff_point,
            })
        
        # Export bus schedules
        bus_schedules = session.exec(select(BusSchedule)).all()
        bus_schedules_data = []
        for schedule in bus_schedules:
            bus_schedules_data.append({
                "id": str(schedule.id),
                "route_id": str(schedule.route_id),
                "departure_time": schedule.departure_time.strftime("%H:%M:%S") if schedule.departure_time else None,
                "frequency_minutes": schedule.frequency_minutes,
                "schedule_type": schedule.schedule_type.value if schedule.schedule_type else "weekday",
                "is_active": schedule.is_active,
                "notes": schedule.notes,
            })
        
        return {
            "routes": routes_data,
            "bus_stops": bus_stops_data,
            "route_stops": route_stops_data,
            "bus_schedules": bus_schedules_data,
        }


def generate_seeder_code(data: Dict[str, Any]) -> str:
    """Generate Python seeder code from exported data."""
    
    code = '''"""Database seeding script generated from current database."""
from sqlmodel import Session, select, create_engine
from uuid import UUID
from datetime import time

from app.core.config import settings
from app.models.route import Route, RouteStatus
from app.models.bus_stop import BusStop, StopType
from app.models.route_stop import RouteStop
from app.models.bus_schedule import BusSchedule, BusScheduleType


def seed_database():
    """Seed the database with exported data."""
    # Use synchronous engine for seeding (replace asyncpg with psycopg2)
    sync_database_url = settings.database_url.replace("+asyncpg", "+psycopg2")
    sync_engine = create_engine(sync_database_url, echo=False)
    
    with Session(sync_engine) as session:
        # Check if data already exists
        try:
            existing_routes = session.exec(select(Route)).first()
            if existing_routes:
                print("Database already has data. Skipping seed.")
                print("To reseed, drop the tables first or use: make db-reset")
                return
        except Exception as e:
            # If tables don't exist yet, that's fine - we'll create the data
            print(f"Note: {e}")
            print("Proceeding with seed...")

'''
    
    # Generate routes
    code += "        # Insert Routes\n"
    code += "        routes = [\n"
    for route in data["routes"]:
        status_enum = route["status"].upper().replace("-", "_")
        code += f'''            Route(
                id=UUID("{route["id"]}"),
                name={repr(route["name"])},
                description={repr(route["description"])},
                origin_city={repr(route["origin_city"])},
                destination_city={repr(route["destination_city"])},
                distance_km={route["distance_km"] if route["distance_km"] is not None else "None"},
                estimated_duration_minutes={route["estimated_duration_minutes"] if route["estimated_duration_minutes"] is not None else "None"},
                status=RouteStatus.{status_enum},
            ),
'''
    code += "        ]\n"
    code += "        for route in routes:\n"
    code += "            session.add(route)\n"
    code += "        session.flush()  # Flush routes so we can reference them in foreign keys\n\n"
    
    # Generate bus stops
    code += "        # Insert Bus Stops\n"
    code += "        bus_stops = [\n"
    for stop in data["bus_stops"]:
        stop_type_enum = stop["stop_type"].upper().replace("-", "_")
        code += f'''            BusStop(
                id=UUID("{stop["id"]}"),
                name={repr(stop["name"])},
                latitude={stop["latitude"]},
                longitude={stop["longitude"]},
                city={repr(stop["city"])},
                address={repr(stop["address"]) if stop["address"] else "None"},
                stop_type=StopType.{stop_type_enum},
                has_shelter={stop["has_shelter"]},
                has_seating={stop["has_seating"]},
                is_accessible={stop["is_accessible"]},
            ),
'''
    code += "        ]\n"
    code += "        for stop in bus_stops:\n"
    code += "            session.add(stop)\n"
    code += "        session.flush()  # Flush stops so we can reference them in route_stops\n\n"
    
    # Generate route stops
    code += "        # Insert Route Stops\n"
    code += "        route_stops = [\n"
    for route_stop in data["route_stops"]:
        code += f'''            RouteStop(
                route_id=UUID("{route_stop["route_id"]}"),
                stop_id=UUID("{route_stop["stop_id"]}"),
                stop_order={route_stop["stop_order"]},
                travel_time_minutes={route_stop["travel_time_minutes"] if route_stop["travel_time_minutes"] is not None else "None"},
                is_pickup_point={route_stop["is_pickup_point"]},
                is_dropoff_point={route_stop["is_dropoff_point"]},
            ),
'''
    code += "        ]\n"
    code += "        for route_stop in route_stops:\n"
    code += "            session.add(route_stop)\n"
    code += "        session.flush()  # Flush route_stops before adding schedules\n\n"
    
    # Generate bus schedules
    code += "        # Insert Bus Schedules\n"
    code += "        bus_schedules = [\n"
    for schedule in data["bus_schedules"]:
        if schedule["departure_time"]:
            hour, minute, second = schedule["departure_time"].split(":")
            # Convert to int to remove leading zeros
            hour_int = int(hour)
            minute_int = int(minute)
            time_str = f"time({hour_int}, {minute_int})"
        else:
            time_str = "None"
        
        schedule_type_enum = schedule["schedule_type"].upper().replace("-", "_")
        code += f'''            BusSchedule(
                route_id=UUID("{schedule["route_id"]}"),
                departure_time={time_str},
                frequency_minutes={schedule["frequency_minutes"] if schedule["frequency_minutes"] is not None else "None"},
                schedule_type=BusScheduleType.{schedule_type_enum},
                is_active={schedule["is_active"]},
                notes={repr(schedule["notes"]) if schedule["notes"] else "None"},
            ),
'''
    code += "        ]\n"
    code += "        for schedule in bus_schedules:\n"
    code += "            session.add(schedule)\n\n"
    
    code += "        session.commit()\n"
    code += '        print("Database seeded successfully!")\n\n'
    
    code += '''
if __name__ == "__main__":
    seed_database()
'''
    
    return code


def main():
    """Main function to export database and generate seeder."""
    print("Exporting database data...")
    
    try:
        data = export_all_data()
        
        # Save JSON export
        json_file = "database_export.json"
        with open(json_file, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2, default=str, ensure_ascii=False)
        print(f"✅ Exported data to {json_file}")
        print(f"   - {len(data['routes'])} routes")
        print(f"   - {len(data['bus_stops'])} bus stops")
        print(f"   - {len(data['route_stops'])} route stops")
        print(f"   - {len(data['bus_schedules'])} bus schedules")
        
        # Generate seeder code
        seeder_code = generate_seeder_code(data)
        seeder_file = "app/core/seed.py"
        with open(seeder_file, "w", encoding="utf-8") as f:
            f.write(seeder_code)
        print(f"✅ Generated seeder script: {seeder_file}")
        
    except Exception as e:
        print(f"❌ Error exporting database: {e}")
        raise


if __name__ == "__main__":
    main()

