"""
Migration script to merge deep_research.db and research_history.db into ldr.db
"""

# Standard library imports
# import json  # Remove unused imports
import logging
import os
import sqlite3
import sys
import traceback

# from pathlib import Path  # Remove unused imports

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Add the parent directory to sys.path to allow relative imports
sys.path.append(
    os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
)

# Import the database module after adding to sys path
# pylint: disable=wrong-import-position
from src.local_deep_research.web.models.database import (  # noqa: E402
    DB_PATH,
    LEGACY_DEEP_RESEARCH_DB,
    LEGACY_RESEARCH_HISTORY_DB,
)


def migrate_to_ldr_db():
    """
    Migrates data from deep_research.db and research_history.db to ldr.db
    """
    # Ensure data directory exists
    try:
        from src.local_deep_research.setup_data_dir import setup_data_dir

        setup_data_dir()
    except ImportError:
        # If we can't import directly, check the path manually
        logger.info("Creating data directory manually")
        data_dir = os.path.dirname(DB_PATH)
        os.makedirs(data_dir, exist_ok=True)

    logger.info(f"Using database path: {DB_PATH}")

    # Check if ldr.db already exists
    if os.path.exists(DB_PATH):
        logger.info(f"Target database {DB_PATH} already exists")

        # Ask for confirmation
        if (
            input(
                f"Target database {DB_PATH} already exists. Do you want to continue migration? (y/n): "
            ).lower()
            != "y"
        ):
            logger.info("Migration aborted by user")
            return False

    # Connect to the target database
    try:
        ldr_conn = sqlite3.connect(DB_PATH)
        ldr_cursor = ldr_conn.cursor()
        logger.info(f"Connected to target database: {DB_PATH}")
    except Exception as e:
        logger.error(f"Failed to connect to target database: {e}")
        return False

    # Enable foreign keys
    ldr_cursor.execute("PRAGMA foreign_keys = OFF")

    # Initialize the database schema
    try:
        from src.local_deep_research.web.models.database import init_db

        init_db()
        logger.info("Initialized database schema")
    except Exception as e:
        logger.error(f"Failed to initialize database schema: {e}")
        ldr_conn.close()
        return False

    # Migrate from research_history.db
    migrated_research = migrate_research_history_db(
        ldr_conn, LEGACY_RESEARCH_HISTORY_DB
    )

    # Migrate from deep_research.db
    migrated_deep_research = migrate_deep_research_db(ldr_conn, LEGACY_DEEP_RESEARCH_DB)

    # Re-enable foreign keys and commit
    ldr_cursor.execute("PRAGMA foreign_keys = ON")
    ldr_conn.commit()
    ldr_conn.close()

    logger.info(
        f"Migration completed - Research History: {migrated_research}, Deep Research: {migrated_deep_research}"
    )
    return True


def migrate_research_history_db(ldr_conn, legacy_path):
    """
    Migrates data from research_history.db to ldr.db

    Args:
        ldr_conn: Connection to the target ldr.db
        legacy_path: Path to legacy research_history.db

    Returns:
        bool: True if migration was successful, False otherwise
    """
    if not os.path.exists(legacy_path):
        logger.warning(f"Legacy database not found: {legacy_path}")
        return False

    try:
        # Connect to legacy database
        legacy_conn = sqlite3.connect(legacy_path)
        legacy_cursor = legacy_conn.cursor()
        ldr_cursor = ldr_conn.cursor()

        logger.info(f"Connected to legacy database: {legacy_path}")

        # Get tables from legacy database
        legacy_cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
        tables = [row[0] for row in legacy_cursor.fetchall()]

        for table in tables:
            # Skip sqlite internal tables
            if table.startswith("sqlite_"):
                continue

            logger.info(f"Migrating table: {table}")

            # Check if table exists in target database
            ldr_cursor.execute(
                f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'"
            )
            if not ldr_cursor.fetchone():
                # Create the table in the target database
                legacy_cursor.execute(
                    f"SELECT sql FROM sqlite_master WHERE type='table' AND name='{table}'"
                )
                create_sql = legacy_cursor.fetchone()[0]
                logger.info(f"Creating table {table} with SQL: {create_sql}")
                ldr_cursor.execute(create_sql)
                logger.info(f"Created table {table} in target database")

            # Get column names
            legacy_cursor.execute(f"PRAGMA table_info({table})")
            columns = [row[1] for row in legacy_cursor.fetchall()]

            # Get all data from legacy table
            legacy_cursor.execute(f"SELECT * FROM {table}")
            rows = legacy_cursor.fetchall()

            logger.info(f"Found {len(rows)} rows in {table}")

            if rows:
                # Create placeholders for the SQL query
                placeholders = ", ".join(["?" for _ in columns])
                columns_str = ", ".join(columns)

                # Insert data into target database
                for row in rows:
                    try:
                        ldr_cursor.execute(
                            f"INSERT OR IGNORE INTO {table} ({columns_str}) VALUES ({placeholders})",
                            row,
                        )
                    except sqlite3.Error as e:
                        logger.error(f"Error inserting into {table}: {e}")
                        logger.error(f"Row data: {row}")
                        continue

                # Verify data was inserted
                ldr_cursor.execute(f"SELECT COUNT(*) FROM {table}")
                count = ldr_cursor.fetchone()[0]
                logger.info(f"Migrated {count} rows to {table} (expected {len(rows)})")
            else:
                logger.info(f"No data to migrate from {table}")

        legacy_conn.close()
        return True

    except Exception as e:
        logger.error(f"Failed to migrate from {legacy_path}: {e}")
        logger.error(f"Exception details: {traceback.format_exc()}")
        return False


def migrate_deep_research_db(ldr_conn, legacy_path):
    """
    Migrates data from deep_research.db to ldr.db

    Args:
        ldr_conn: Connection to the target ldr.db
        legacy_path: Path to legacy deep_research.db

    Returns:
        bool: True if migration was successful, False otherwise
    """
    if not os.path.exists(legacy_path):
        logger.warning(f"Legacy database not found: {legacy_path}")
        return False

    try:
        # Connect to legacy database
        legacy_conn = sqlite3.connect(legacy_path)
        legacy_cursor = legacy_conn.cursor()
        ldr_cursor = ldr_conn.cursor()

        logger.info(f"Connected to legacy database: {legacy_path}")

        # Get tables from legacy database
        legacy_cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
        tables = [row[0] for row in legacy_cursor.fetchall()]

        # Migrate each table
        for table in tables:
            # Skip sqlite internal tables
            if table.startswith("sqlite_"):
                continue

            # Skip the research_log table as it's redundant with research_logs
            if table == "research_log":
                logger.info(
                    "Skipping redundant table 'research_log', using 'research_logs' instead"
                )
                continue

            logger.info(f"Migrating table: {table}")

            # Check if table exists in target database
            ldr_cursor.execute(
                f"SELECT name FROM sqlite_master WHERE type='table' AND name='{table}'"
            )
            if not ldr_cursor.fetchone():
                # Create the table in the target database
                legacy_cursor.execute(
                    f"SELECT sql FROM sqlite_master WHERE type='table' AND name='{table}'"
                )
                create_sql = legacy_cursor.fetchone()[0]
                ldr_cursor.execute(create_sql)
                logger.info(f"Created table {table} in target database")

            # Get column names
            legacy_cursor.execute(f"PRAGMA table_info({table})")
            columns = [row[1] for row in legacy_cursor.fetchall()]

            # Get all data from legacy table
            legacy_cursor.execute(f"SELECT * FROM {table}")
            rows = legacy_cursor.fetchall()

            if rows:
                # Create placeholders for the SQL query
                placeholders = ", ".join(["?" for _ in columns])
                columns_str = ", ".join(columns)

                # Insert data into target database
                for row in rows:
                    try:
                        ldr_cursor.execute(
                            f"INSERT OR IGNORE INTO {table} ({columns_str}) VALUES ({placeholders})",
                            row,
                        )
                    except sqlite3.Error as e:
                        logger.error(f"Error inserting into {table}: {e}")
                        continue

                logger.info(f"Migrated {len(rows)} rows from {table}")
            else:
                logger.info(f"No data to migrate from {table}")

        legacy_conn.close()
        return True

    except Exception as e:
        logger.error(f"Failed to migrate from {legacy_path}: {e}")
        return False


if __name__ == "__main__":
    migrate_to_ldr_db()
