from enum import Enum
from datetime import datetime

from sqlalchemy import Column, Integer, String, Boolean, Date, ForeignKey, Text, Double,Float, DateTime, Enum as SqlAlchemyEnum
from sqlalchemy.orm import relationship

from models.base import Base, TimestampMixin


class UserTypesEnum(Enum):
    ADMIN = 'admin'
    PARENT = 'parent'
    PARTICIPANT = 'participant'
    GUEST = 'guest'
    STAFF = 'staff'

    @property
    def model(self):
        from .parent import Parent
        from .participant import Participant
        from .staff import Staff
        match(self.value):
            case self.ADMIN.value: return User
            case self.PARENT.value: return Parent
            case self.PARTICIPANT.value: return Participant
            case self.GUEST.value: return User
            case self.STAFF.value: return Staff


## user table only for admin & guest
class User(Base, TimestampMixin):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    first_name = Column(String(255), nullable=False)
    sur_name = Column(String(255), nullable=False)
    email = Column(String(255), unique=True, nullable=False)
    address = Column(String(255), nullable=True)
    post_code = Column(String(255), nullable=True)
    hashed_password = Column(String(255), nullable=False)
    user_type = Column(String(50), nullable=False)
    country_code = Column(String(5), nullable=True)
    mobile_number = Column(String(20), nullable=True)
    alternative_contact_email=Column(String(50), nullable=True)
    alternative_phone_number=Column(String(50), nullable=True)
    wallet_amount=Column(Float,nullable=True)
    term_and_condition_accepted=Column(Boolean,nullable=True,default=False)
    profile_image = Column(Text, nullable=True)

    @property
    def profile_image_url(self):
        return f"/images/{self.profile_image}"


# not used
class UserProfile(Base, TimestampMixin):
    __tablename__ = 'user_profile'

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    first_name = Column(String(255), nullable=False)
    sur_name = Column(String(255), nullable=True)
    middle_name = Column(String(255), nullable=True)
    dob = Column(Date, nullable=True)
    age = Column(Integer, nullable=True)
    address = Column(String(255), nullable=True)
    post_code = Column(String(255), nullable=True)
    local_authority = Column(String(255), nullable=True)
    gender = Column(String(50), nullable=False)
    email = Column(String(255), nullable=False)
    emergency_contact_name = Column(String(255), nullable=True)
    second_emergency_contact = Column(String(255), nullable=True)
    medical_needs = Column(String(255), nullable=True)
    ethnicity = Column(String(255), nullable=True)
    care_experience = Column(String(30), nullable=True)
    age_above_three = Column(String(30), nullable=True)
    wac_receipt = Column(String(255), nullable=True)
    profile_image = Column(Text, nullable=True)
    how_did_you_know = Column(String(255), nullable=True)
    email_consent = Column(Boolean, nullable=False,default=False)
    terms_and_conditions_consent = Column(Boolean, nullable=False,default=False)
    code_of_consent_availability = Column(Boolean, nullable=True,default=False)


    @property
    def profile_image_url(self):
        return f"/images/{self.profile_image}"

    @property
    def wallet(self):
        return self.user.user_wallet.balance


# not used
class UserWallet(Base, TimestampMixin):
    __tablename__ = 'user_wallet'

    id = Column(Integer, primary_key=True, autoincrement=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, unique=True)
    balance = Column(Double, default=0, nullable=False)


class PasswordResetToken(Base):
    __tablename__ = 'password_reset_tokens'

    id = Column(Integer, primary_key=True, index=True)
    user_id = Column(Integer,  nullable=False)
    token = Column(String, unique=True, nullable=False)
    expiry = Column(DateTime, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    user_type = Column(SqlAlchemyEnum(UserTypesEnum), nullable=False)

    def is_expired(self):
        return self.expiry < datetime.utcnow()
