"""
Migrate data from SQLite to MariaDB using SQLAlchemy ORM only — no raw SQL
except for the AUTO_INCREMENT reset which requires a DDL statement.

Usage:
    MARIADB_URL='mysql+pymysql://user:pass@host/dbname?charset=utf8mb4' \\
        python migrate_to_mariadb.py

Or pass the URL as a CLI argument:
    python migrate_to_mariadb.py 'mysql+pymysql://user:pass@host/dbname?charset=utf8mb4'
"""

import sys

from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker

import config
from models import Base, Battery, Device


def migrate(mariadb_url: str):
    print("=== Battery Tracker: SQLite → MariaDB Migration ===\n")

    # -- Engines --
    sqlite_engine = create_engine(config.SQLALCHEMY_DATABASE_URI)
    mariadb_engine = create_engine(mariadb_url, pool_pre_ping=True)

    SrcSession = sessionmaker(bind=sqlite_engine)
    DstSession = sessionmaker(bind=mariadb_engine)

    src = SrcSession()
    dst = DstSession()

    try:
        # -- Create tables on MariaDB --
        print("Creating tables on MariaDB (if not exist)…")
        Base.metadata.create_all(mariadb_engine)

        # -- Read source data --
        src_devices   = src.query(Device).all()
        src_batteries = src.query(Battery).all()
        print(f"Source: {len(src_devices)} devices, {len(src_batteries)} batteries\n")

        # -- Migrate Devices first (batteries have FK → device) --
        print("Migrating devices…")
        for d in src_devices:
            new_d = Device(
                id=d.id,
                name=d.name,
                battery_slots=d.battery_slots,
                notes=d.notes,
            )
            dst.add(new_d)
        dst.flush()

        # -- Migrate Batteries --
        print("Migrating batteries…")
        for b in src_batteries:
            new_b = Battery(
                id=b.id,
                label=b.label,
                brand=b.brand,
                status=b.status,
                device_id=b.device_id,
                notes=b.notes,
            )
            dst.add(new_b)
        dst.flush()

        dst.commit()
        print("Commit successful.\n")

        # -- Reset AUTO_INCREMENT so new rows don't collide --
        # This DDL is required; there is no ORM-level equivalent.
        with mariadb_engine.connect() as conn:
            max_device_id   = max((d.id for d in src_devices),   default=0)
            max_battery_id  = max((b.id for b in src_batteries),  default=0)
            conn.execute(text("ALTER TABLE device SET AUTO_INCREMENT = :v"),
                         {"v": max_device_id + 1})
            conn.execute(text("ALTER TABLE battery SET AUTO_INCREMENT = :v"),
                         {"v": max_battery_id + 1})
            conn.commit()
        print("AUTO_INCREMENT counters reset.\n")

        # -- Verify counts --
        dst_device_count   = dst.query(Device).count()
        dst_battery_count  = dst.query(Battery).count()
        src_device_count   = len(src_devices)
        src_battery_count  = len(src_batteries)

        print("=== Verification ===")
        print(f"{'Table':<12} {'SQLite':>8} {'MariaDB':>9} {'OK?':>5}")
        print("-" * 38)

        device_ok  = src_device_count  == dst_device_count
        battery_ok = src_battery_count == dst_battery_count

        print(f"{'device':<12} {src_device_count:>8} {dst_device_count:>9} {'OK' if device_ok else 'MISMATCH':>5}")
        print(f"{'battery':<12} {src_battery_count:>8} {dst_battery_count:>9} {'OK' if battery_ok else 'MISMATCH':>5}")

        if not (device_ok and battery_ok):
            print("\nERROR: Row count mismatch. Do not decommission SQLite.")
            sys.exit(1)

        print("\nMigration complete. All row counts match.")

    except Exception as exc:
        dst.rollback()
        print(f"\nERROR: {exc}")
        raise
    finally:
        src.close()
        dst.close()


if __name__ == "__main__":
    if len(sys.argv) > 1:
        url = sys.argv[1]
    else:
        import os
        url = os.environ.get("MARIADB_URL")

    if not url:
        print("ERROR: Provide MariaDB URL via MARIADB_URL env var or as a CLI argument.")
        print("  Example: python migrate_to_mariadb.py 'mysql+pymysql://user:pass@host/db?charset=utf8mb4'")
        sys.exit(1)

    migrate(url)
