"""
User seeder for creating initial user accounts.
"""

from sqlalchemy.orm import Session
from sqlalchemy import func, select, and_
from src.apps.users.models.user import User
from src.core.utils.password import encrypt_password
from src.apps.base.seeders.base_seeder import BaseSeeder
import logging
import secrets
import string

logger = logging.getLogger(__name__)


class UserSeeder(BaseSeeder):
    """
    Seeder for creating initial user accounts.
    
    Creates an admin user with predefined credentials if it doesn't already exist.
    """
    
    def __init__(self):
        super().__init__()
        self.admin_email = "admin@example.com"
        self.admin_username = "admin"
    
    def generate_admin_password(self) -> str:
        """Generate a secure random password for admin user."""
        # Use a mix of letters, digits, and safe symbols
        characters = string.ascii_letters + string.digits + "!@#$%^&*"
        password = ''.join(secrets.choice(characters) for _ in range(16))
        return password
    
    def seed(self, db: Session) -> None:
        """
        Seed the users table with initial admin user.
        
        Args:
            db: Database session
        """
        logger.info("Creating admin user...")
        
        # Generate secure random password
        admin_password = self.generate_admin_password()
        
        # Hash the password
        try:
            encrypted_password = encrypt_password(admin_password)
            if not encrypted_password:
                raise ValueError("Password encryption failed")
            
            hashed_password = encrypted_password.decode('utf-8')
            logger.info("Password hashed successfully")
        except Exception as e:
            logger.error(f"Failed to hash password: {e}")
            raise

        # Create admin user
        admin_user = User(
            email=self.admin_email,
            username=self.admin_username,
            hashed_password=hashed_password,
            first_name="Admin",
            last_name="User",
            full_name="Admin User",
            user_id="admin_001",
            is_active=True,
            is_verified=True,
            is_superuser=True,
            phone=None,
            middle_name=None,
            bio="System Administrator"
        )

        try:
            db.add(admin_user)
            db.flush()  # Flush to get the ID without committing
            
            logger.info(f"Created admin user: {admin_user.email} (ID: {admin_user.id})")
            logger.info(f"Admin password: {admin_password}")
            logger.warning("IMPORTANT: Save the admin password securely!")
            
        except Exception as e:
            logger.error(f"Failed to create admin user: {e}")
            raise
    
    def should_run(self, db: Session) -> bool:
        """
        Check if the user seeder should run.
        
        Args:
            db: Database session
            
        Returns:
            True if no admin user exists, False otherwise
        """
        # Check if admin user already exists
        stmt = select(User).where(
            and_(
                User.email == self.admin_email,
                User.is_superuser == True
            )
        )
        existing_admin = db.execute(stmt).scalar_one_or_none()
        
        if existing_admin:
            logger.info(f"Admin user already exists: {existing_admin.email} (ID: {existing_admin.id})")
            return False
        
        return True