from sqlalchemy import text
from sqlalchemy.exc import IntegrityError
from datetime import datetime as dt, timezone as tz
from flask_security import hash_password
from uuid import uuid4

from eveai_ops import create_app
from common.models.user import User, Tenant, Role, RolesUsers
from common.extensions import db, minio_client
from common.utils.database import Database
from flask_security.utils import hash_password



def initialize_data():
    """
    Initialize baseline data for a new EveAI environment.

    This function creates:
    - System roles (IDs 1-999)
    - Default tenant (ID 1)
    - Admin user (ID 1)
    """
    print("💜 Starting data initialization...")

    app = create_app()

    with app.app_context():

        # Step 1: Initialize roles
        roles = initialize_roles()

        # Step 2: Initialize default tenant
        default_tenant = initialize_default_tenant()

        # Step 3: Initialize admin user
        admin_user = initialize_admin_user(default_tenant)

        print("💜 Data initialization completed successfully")


def initialize_roles():
    """Initialize system roles with IDs below 1000"""
    print("🧡 Initializing system roles...")

    # Define system roles - matching the exact IDs and names you specified
    roles_data = [
        {'id': 1, 'name': 'Super User', 'description': 'System administrator with full access'},
        {'id': 2, 'name': 'Tenant Admin', 'description': 'Administrator for a specific tenant'},
        {'id': 3, 'name': 'Partner Admin', 'description': 'Partner Administrator, managing different Tenants'},
    ]

    roles = {}
    for role_data in roles_data:
        role = Role.query.filter_by(name=role_data['name']).first()

        if not role:
            print(f"Creating role: {role_data['name']} (ID: {role_data['id']})")
            role = Role(**role_data)
            db.session.add(role)
        else:
            print(f"Role already exists: {role.name} (ID: {role.id})")

        roles[role_data['name']] = role

    db.session.commit()

    # Verify sequence is set correctly
    db.session.execute(text("ALTER SEQUENCE public.role_id_seq RESTART WITH 1000"))
    db.session.commit()

    print("🧡 Finished initializing system roles.")

    return roles


def initialize_default_tenant():
    """Initialize the default system tenant with ID 1"""
    print("🧡 Initializing default tenant...")

    tenant_data = {
        'id': 1,
        'name': 'Jedi',
        'website': 'https://www.askeveai.com',
        'timezone': 'UTC',
        'type': 'Active',
        'currency': '€',
        'created_at': dt.now(tz.utc),
        'updated_at': dt.now(tz.utc)
    }

    tenant = db.session.get(Tenant, tenant_data['id'])

    if not tenant:
        print(f"💛 Creating default tenant: {tenant_data['name']} (ID: {tenant_data['id']})")
        tenant = Tenant(**tenant_data)
        db.session.add(tenant)
        db.session.commit()

        # Create tenant schema
        print(f"💛 Creating schema for tenant {tenant.id}")
        Database(tenant.id).create_tenant_schema()

        # Create MinIO bucket
        print(f"💛 Creating MinIO bucket for tenant {tenant.id}")
        minio_client.create_tenant_bucket(tenant.id)
    else:
        print(f"🧡 Default tenant already exists: {tenant.name} (ID: {tenant.id})")

    print(f"🧡 Finished initializing default tenant.")

    return tenant


def initialize_admin_user(tenant):
    """Initialize the system admin user with ID 1"""
    print("Initializing admin user...")

    # Check if admin user already exists
    admin_user = User.query.filter_by(email='yoda@flow-it.net').first()

    if not admin_user:
        print("🧡 Creating admin user (yoda)")

        # Create a secure password - you can replace this with your preferred default
        password = hash_password('Dagobah')

        # Create the admin user with ID 1
        admin_user = User(
            id=1,
            tenant_id=tenant.id,
            user_name='yoda',
            email='yoda@flow-it.net',
            password=password,
            first_name='Yoda',
            last_name='Master',
            active=True,
            fs_uniquifier=str(uuid4()),
            confirmed_at=dt.now(tz.utc),
            created_at=dt.now(tz.utc),
            updated_at=dt.now(tz.utc)
        )

        db.session.add(admin_user)
        db.session.commit()

        user_role = RolesUsers(user_id=admin_user.id, role_id=1)
        db.session.add(user_role)
        db.session.commit()
    else:
        print(f"🧡 Admin user already exists: {admin_user.email} (ID: {admin_user.id})")

    print(f"🧡 Admin user initialized successfully.")

    return admin_user


if __name__ == "__main__":
    try:
        initialize_data()
    except IntegrityError:
        print("💔 Error: Integrity constraint violation. Initial data already exists.")
    except Exception as e:
        print(f"💔 An error occurred during initialization: {e}")
