#!/usr/bin/env python
"""
Script to seed the database with a test user and API key.
"""

import os
import click
from dotenv import load_dotenv

from preloop.models.crud import crud_account, crud_api_key, crud_user
from preloop.models.db.session import get_db_session
from preloop.models.db.setup import setup_database
from preloop.api.auth.jwt import get_password_hash
from preloop.schemas.auth import ApiKeyCreate


def assign_owner_role_if_available(db_session, user):
    """Assign owner role to user if RBAC system is available.

    This is a no-op in open-source builds without RBAC.
    In Enterprise builds, assigns the 'owner' role to give full access.
    """
    try:
        from preloop.models.crud.permission import crud_user_role
        from preloop.models.models.permission import Role

        # Check if user already has owner role
        user_roles = crud_user_role.get_user_roles(db_session, user_id=user.id)
        if any(r.name == "owner" for r in user_roles):
            click.echo("User already has owner role.")
            return True

        # Find the owner role
        owner_role = (
            db_session.query(Role)
            .filter(Role.name == "owner", Role.is_system_role.is_(True))
            .first()
        )

        if owner_role:
            crud_user_role.assign_role(
                db_session,
                user_id=user.id,
                role_id=owner_role.id,
                granted_by=None,  # System-assigned
            )
            db_session.commit()
            click.echo("Assigned 'owner' role to user.")
            return True
        else:
            click.echo("Owner role not found - RBAC may not be initialized.")
            return False

    except ImportError:
        # RBAC not available (open-source build)
        click.echo("RBAC not available - skipping role assignment.")
        return False
    except Exception as e:
        click.echo(f"Warning: Could not assign owner role: {e}")
        return False


@click.command()
@click.option(
    "--email", envvar="TEST_USER_EMAIL", required=True, help="Email for the test user."
)
@click.option(
    "--password",
    envvar="TEST_USER_PASSWORD",
    required=True,
    help="Password for the test user.",
)
@click.option(
    "--api-key",
    envvar="TEST_USER_API_KEY",
    required=True,
    help="API key for the test user.",
)
def seed_test_user(email: str, password: str, api_key: str):
    """
    Creates a test user and an API key if they don't already exist.
    """
    load_dotenv()
    setup_database(os.getenv("DATABASE_URL"))
    db_session = next(get_db_session())

    click.echo(f"Checking for test user with email: {email}")
    user = crud_user.get_by_email(db_session, email=email)

    if user:
        click.echo("Test user already exists.")
    else:
        click.echo("Creating new test user...")
        # First create an account (organization)
        account_in = {
            "organization_name": "Test Organization",
            "is_active": True,
            "email_verified": True,
        }
        account = crud_account.create(db_session, obj_in=account_in)
        db_session.flush()  # Ensure account.id is available

        # Then create a user with authentication credentials
        user_in = {
            "account_id": str(account.id),
            "email": email,
            "username": os.getenv("TEST_USER_USERNAME", "test_user"),
            "full_name": "Test User",
            "hashed_password": get_password_hash(password),
            "email_verified": True,
            "is_active": True,
            "user_source": "local",
        }
        user = crud_user.create(db_session, obj_in=user_in)
        db_session.flush()  # Ensure user.id is available

        # Update account to set primary_user_id
        account.primary_user_id = user.id
        db_session.commit()

        click.echo("Test user and account created successfully.")

    # Assign owner role if RBAC is available (Enterprise Edition)
    click.echo("Checking for RBAC role assignment...")
    assign_owner_role_if_available(db_session, user)

    click.echo("Checking for test user API key...")
    # A simple check to see if any key exists for the user.
    # A more robust implementation might check for the specific key.
    existing_keys = crud_api_key.get_active_by_user(db_session, username=user.username)
    if any(k.key == api_key for k in existing_keys):
        click.echo("API key already exists for the test user.")
    else:
        click.echo("Creating API key for the test user...")
        api_key_in = ApiKeyCreate(name="Test API Key")
        crud_api_key.create_with_owner(
            db_session,
            obj_in=api_key_in,
            owner_username=user.username,
            key_value=api_key,
        )
        click.echo("API key created successfully.")

    click.echo("\nDatabase seeding complete.")


if __name__ == "__main__":
    seed_test_user()
