"""
Admin-related models
"""

from enum import Enum
from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional, Union
from datetime import datetime

from sqlalchemy import Column, Integer, String, Boolean, DateTime, Enum as SqlEnum, JSON
from core.database import Base
from typing import List


class AdminRole(str, Enum):
    ADMINISTRATOR = "Administrator"
    SUB_ADMIN = "Sub admin"


class Admin(Base):
    __tablename__ = "admins"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, index=True, nullable=False)
    email = Column(String(100), unique=True, index=True, nullable=False)
    password_hash = Column(String(255), nullable=False)
    role = Column(SqlEnum(AdminRole), nullable=False)
    permissions = Column(JSON, nullable=True)  # New permissions column to store list of permissions
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)


class AdminPydantic(BaseModel):
    """Admin user model"""
    id: Optional[int] = None
    username: str = Field(..., description="Admin username")
    email: EmailStr = Field(..., description="Admin email address")
    password_hash: str = Field(..., description="Hashed password")
    role: AdminRole = Field(..., description="Admin role")
    permissions: Optional[List[str]] = Field(default=None, description="List of permissions assigned to the admin")
    is_active: bool = Field(default=True, description="Whether the admin is active")
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


class AdminLogin(BaseModel):
    """Admin login request model"""
    username: str = Field(..., description="Admin username")
    password: str = Field(..., description="Admin password")


class AdminCreate(BaseModel):
    """Admin creation model"""
    username: str = Field(..., description="Admin username")
    email: EmailStr = Field(..., description="Admin email address")
    password: str = Field(..., description="Admin password")
    role: AdminRole = Field(..., description="Admin role")
    permissions: Optional[Union[str, List[str]]] = Field(default=None, description="List of permissions assigned to the admin")

    @validator('permissions', pre=True, always=True)
    def validate_permissions(cls, v):
        if isinstance(v, str):
            return [perm.strip() for perm in v.split(',') if perm.strip()]
        return v


class AdminUpdate(BaseModel):
    """Admin update model"""
    username: Optional[str] = Field(None, description="Admin username")
    email: Optional[EmailStr] = Field(None, description="Admin email address")
    role: Optional[AdminRole] = Field(None, description="Admin role")
    permissions: Optional[Union[str, List[str]]] = Field(default=None, description="List of permissions assigned to the admin")
    is_active: Optional[bool] = Field(None, description="Whether the admin is active")

    @validator('permissions', pre=True, always=True)
    def validate_permissions(cls, v):
        if isinstance(v, str):
            return [perm.strip() for perm in v.split(',') if perm.strip()]
        return v


class PasswordReset(BaseModel):
    """Password reset request model"""
    email: EmailStr = Field(..., description="Admin email address")


class PasswordResetConfirm(BaseModel):
    """Password reset confirmation model"""
    token: str = Field(..., description="Reset token")
    new_password: str = Field(..., description="New password")


class TokenResponse(BaseModel):
    """Token response model"""
    access_token: str
    token_type: str = "bearer"
    admin: dict  # Simplified admin info


class AdminResponse(BaseModel):
    """Admin response model"""
    id: int
    username: str
    email: str
    role: AdminRole
    permissions: Optional[List[str]] = Field(default=None, description="List of permissions assigned to the admin")
    is_active: bool
    created_at: datetime
    updated_at: datetime
