"""Initialize test data for Preloop."""

import asyncio
import logging
import uuid

from passlib.context import CryptContext
from sqlalchemy.exc import SQLAlchemyError

from preloop.models.crud.account import CRUDAccount
from preloop.models.crud.organization import CRUDOrganization
from preloop.models.crud.project import CRUDProject
from preloop.models.crud.tracker import CRUDTracker
from preloop.models.db.session import get_db_session
from preloop.models.models.account import Account
from preloop.models.models.organization import Organization
from preloop.models.models.project import Project
from preloop.models.models.tracker import Tracker, TrackerType

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

# Password hashing
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


async def create_test_data():
    """Create test data for the Preloop server."""
    session_generator = get_db_session()
    db = next(session_generator)
    crud_account = CRUDAccount(Account)
    crud_tracker = CRUDTracker(Tracker)
    crud_organization = CRUDOrganization(Organization)
    crud_project = CRUDProject(Project)

    try:
        # Create a test account if it doesn't exist
        account = crud_account.get_by_email(db, email="admin@preloop.ai")
        if account:
            logger.info(
                f"Account already exists: {account.username} (ID: {account.id})"
            )
        else:
            # Hash the password
            hashed_password = pwd_context.hash("admin")

            logger.info("Creating admin account...")
            account = crud_account.create(
                db,
                obj_in={
                    "id": str(uuid.uuid4()),
                    "username": "admin",
                    "email": "admin@preloop.ai",
                    "full_name": "Admin User",
                    "hashed_password": hashed_password,
                    "is_active": True,
                    "is_superuser": True,
                    "meta_data": {"admin_account": True},
                },
            )
            logger.info(f"Created account: {account.username} (ID: {account.id})")

        # Create a tracker if it doesn't exist
        tracker = crud_tracker.get_for_account(db, account_id=account.id)
        if tracker and len(tracker) > 0:
            logger.info(
                f"Tracker already exists: {tracker[0].name} (ID: {tracker[0].id})"
            )
            tracker = tracker[0]
        else:
            logger.info("Creating GitHub tracker...")
            tracker = crud_tracker.create(
                db,
                obj_in={
                    "id": str(uuid.uuid4()),
                    "name": "GitHub Issues",
                    "tracker_type": TrackerType.GITHUB.value,
                    "account_id": account.id,
                    "is_active": True,
                    "url": "https://api.github.com",
                    "api_key": "github_pat_mock_token",
                    "connection_details": {"repository": "spacecode/astrobot"},
                    "meta_data": {"integration_type": "personal_access_token"},
                },
            )
            logger.info(f"Created tracker: {tracker.name} (ID: {tracker.id})")

        # Create an organization if it doesn't exist
        org = crud_organization.get_by_identifier(db, identifier="spacecode")
        if org:
            logger.info(f"Organization already exists: {org.name} (ID: {org.id})")
        else:
            # Create organization
            logger.info("Creating test organization...")
            org = crud_organization.create(
                db,
                obj_in={
                    "id": str(uuid.uuid4()),
                    "name": "Spacecode AI",
                    "identifier": "spacecode",
                    "description": "Spacecode AI organization for testing",
                    "tracker_id": tracker.id,
                    "is_active": True,
                    "settings": {"default_tracker": tracker.id},
                    "meta_data": {"industry": "Technology", "size": "Startup"},
                },
            )
            logger.info(f"Created organization: {org.name} (ID: {org.id})")

        # Create a project if it doesn't exist
        project = crud_project.get_by_identifier(
            db, organization_id=org.id, identifier="astrobot"
        )
        if project:
            logger.info(f"Project already exists: {project.name} (ID: {project.id})")
        else:
            # Create project
            logger.info("Creating test project...")
            project = crud_project.create(
                db,
                obj_in={
                    "id": str(uuid.uuid4()),
                    "name": "Astrobot",
                    "identifier": "astrobot",
                    "description": "Astrobot project for testing",
                    "organization_id": org.id,
                    "is_active": True,
                    "settings": {"visibility": "public"},
                    "tracker_settings": {
                        "github": {
                            "repository": "spacecode/astrobot",
                            "credentials": "github_pat_mock_token",
                        }
                    },
                    "meta_data": {"team": "Engineering"},
                },
            )
            logger.info(f"Created project: {project.name} (ID: {project.id})")

        logger.info("Test data setup complete")

    except SQLAlchemyError as e:
        db.rollback()
        logger.error(f"Error creating test data: {e}")
        raise
    finally:
        db.close()
        try:
            # Clean up the generator
            next(session_generator, None)
        except StopIteration:
            pass


def main():
    """Main function to create test data."""
    try:
        # First ensure the database tables exist using Alembic
        import os
        import subprocess
        from pathlib import Path

        # Get the models directory path (where alembic.ini lives)
        repo_root = Path(__file__).resolve().parents[1]
        models_dir = os.getenv(
            "PRELOOP_MODELS_PATH",
            str(repo_root / "backend" / "preloop" / "models"),
        )

        logger.info(
            "Running Alembic migrations to ensure database schema is up to date..."
        )

        # Run alembic upgrade head
        result = subprocess.run(
            ["alembic", "upgrade", "head"],
            cwd=models_dir,
            capture_output=True,
            text=True,
        )

        if result.returncode != 0:
            logger.error(f"Alembic migration failed: {result.stderr}")
            raise RuntimeError(f"Failed to run database migrations: {result.stderr}")

        logger.info("Database schema initialized successfully via Alembic")

        # Now create the test data
        asyncio.run(create_test_data())
        logger.info("Test data creation completed successfully")
    except Exception as e:
        logger.error(f"Failed to create test data: {e}")
        raise


if __name__ == "__main__":
    main()
