import pytest
from sqlalchemy.orm import Session
from ...models.user_model import User

# import model enums instead
from ...models.enum_for_models import UserTypeEnum, ProgramTypeEnum
from ...entities.user_entity import UserEntity
from datetime import datetime


programs = ProgramTypeEnum
roles = UserTypeEnum

volunteer = User(
    id=1,
    uuid="test1",
    username="volunteer",
    email="volunteer@compass.com",
    experience=1,
    group="volunteers",
    program=[programs.COMMUNITY, programs.ECONOMIC],
    created_at=datetime.now(),
    role=UserTypeEnum.VOLUNTEER,
)

employee = User(
    id=2,
    uuid="test2",
    username="employee",
    email="employee@compass.com",
    experience=5,
    group="employees",
    program=[programs.DOMESTIC, programs.ECONOMIC],
    created_at=datetime.now(),
    role=roles.EMPLOYEE,
)

admin = User(
    id=3,
    uuid="test3",
    username="admin",
    email="admin@compass.com",
    experience=10,
    group="admin",
    program=[
        programs.ECONOMIC,
        programs.DOMESTIC,
        programs.COMMUNITY,
    ],
    created_at=datetime.now(),
    role=roles.ADMIN,
)

newUser = User(
    id=4,
    username="new",
    uuid="test4",
    email="new@compass.com",
    experience=1,
    group="volunteer",
    program=[programs.ECONOMIC],
    created_at=datetime.now(),
    role=roles.VOLUNTEER,
)

toDelete = User(
    id=5,
    username="delete",
    email="delete@compass.com",
    experience=0,
    group="none",
    program=[programs.COMMUNITY],
    created_at=datetime.now(),
    role=roles.VOLUNTEER,
)

users = [volunteer, employee, admin, toDelete]

admin1 = User(
    username="Prajwal Moharana",
    uuid="acc6e112-d296-4739-a80c-b89b2933e50b",
    email="root@compass.com",
    experience=10,
    group="admin",
    program=[programs.ECONOMIC, programs.DOMESTIC, programs.COMMUNITY],
    created_at=datetime.now(),
    role=roles.ADMIN,
)

employee1 = User(
    username="Mel Ho",
    uuid="c5fcff86-3deb-4d09-9f60-9b529e40161a",
    email="employee@compass.com",
    experience=5,
    group="employee",
    program=[programs.ECONOMIC, programs.DOMESTIC, programs.COMMUNITY],
    created_at=datetime.now(),
    role=roles.EMPLOYEE,
)

volunteer1 = User(
    username="Pranav Wagh",
    uuid="1d2e114f-b286-4464-8528-d177dc226b09",
    email="volunteer1@compass.com",
    experience=2,
    group="volunteer",
    program=[programs.DOMESTIC],
    created_at=datetime.now(),
    role=roles.VOLUNTEER,
)

volunteer2 = User(
    username="Yashu Singhai",
    uuid="13888204-1bae-4be4-8192-1ca46be4fc7d",
    email="volunteer2@compass.com",
    experience=1,
    group="volunteer",
    program=[programs.COMMUNITY, programs.ECONOMIC],
    created_at=datetime.now(),
    role=roles.VOLUNTEER,
)

users1 = [admin1, employee1, volunteer1, volunteer2]


from sqlalchemy import text
from sqlalchemy.orm import Session, DeclarativeBase, InstrumentedAttribute


def reset_table_id_seq(
    session: Session,
    entity: type[DeclarativeBase],
    entity_id_column: InstrumentedAttribute[int],
    next_id: int,
) -> None:
    """Reset the ID sequence of an entity table.

    Args:
        session (Session) - A SQLAlchemy Session
        entity (DeclarativeBase) - The SQLAlchemy Entity table to target
        entity_id_column (MappedColumn) - The ID column (should be an int column)
        next_id (int) - Where the next inserted, autogenerated ID should begin

    Returns:
        None"""
    table = entity.__table__
    id_column_name = entity_id_column.name
    sql = text(f"ALTER SEQUENCe {table}_{id_column_name}_seq RESTART WITH {next_id}")
    session.execute(sql)


def insert_fake_data(session: Session):
    """Inserts fake organization data into the test session."""

    global users

    # Create entities for test organization data
    entities = []
    for user in users:
        entity = UserEntity.from_model(user)
        session.add(entity)
        entities.append(entity)

    # Reset table IDs to prevent ID conflicts
    reset_table_id_seq(session, UserEntity, UserEntity.id, len(users) + 1)

    # Commit all changes
    session.commit()


def insert_test_data(session: Session):
    """Inserts fake organization data into the test session."""

    global users1

    # Create entities for test organization data
    for user in users1:
        entity = UserEntity.from_model(user)
        session.add(entity)

    # Reset table IDs to prevent ID conflicts
    reset_table_id_seq(session, UserEntity, UserEntity.id, len(users1) + 1)

    # Commit all changes
    session.commit()


@pytest.fixture(autouse=True)
def fake_data_fixture(session: Session):
    """Insert fake data the session automatically when test is run.
    Note:
        This function runs automatically due to the fixture property `autouse=True`.
    """
    insert_fake_data(session)
    session.commit()
    yield