"""
2025.10.26: change designate column type from Annotated to Optional and raw type.
"""

# import packages from default or pip library
from datetime import date
from sqlmodel import SQLModel, Field
from fastapi.exceptions import RequestValidationError
from pycountry import countries as pycountries

# import packages from this framework


# define Class for Common SQLModel
class AddressMixin(SQLModel):
    address: str = Field(nullable=False)


class BirthdateMixin(SQLModel):
    birthdate: date = Field(nullable=False)


class CPNumMixin(SQLModel):
    cp_num: str = Field(nullable=False)


class EmailMixin(SQLModel):
    email: str = Field(nullable=False, unique=True)


class FirstnameMixin(SQLModel):
    firstname: str = Field(nullable=False, index=True)


class LastnameMixin(SQLModel):
    lastname: str = Field(nullable=False, index=True)


class NationMixin(SQLModel):
    nation: str = Field(nullable=False)


class NicknameMixin(SQLModel):
    nickname: str = Field(unique=True, index=True)


class PostalCodeMixin(SQLModel):
    postal_code: str = Field(nullable=False)


# define function to control SQL event
# please follow the procedure below
# use decorator 'event.listens_for()' for event handling function
# event handler function must have 3 args: mapper, connection and target)
# in your model file, import listens_for from 'sqlalchemy.event'
# event.listens_for(target=TARGET_TABLE_CLASS_NAME, identifier=['before_insert', 'before_update',...])
def _convert_country_to_alpha2(mapper, connection, target):
    if target.nation is not None and len(target.nation) != 2:
        try:
            target.nation = pycountries.get(name=target.nation).alpha_2
        except AttributeError:
            raise RequestValidationError(errors={"input": "nation", "msg": "please input official country name."})
    return None

def _convert_country_to_alpha3(mapper, connection, target):
    if target.nation is not None and len(target.nation) != 3:
        try:
            target.nation = pycountries.get(name=target.nation).alpha_3
        except AttributeError:
            raise RequestValidationError(errors={"input": "nation", "msg": "please input official country name."})
    return None

def _lower_firstname(mapper, connection, target) -> None:
    if target.firstname is not None:
        target.firstname = target.firstname.lower()
    return None

def _lower_lastname(mapper, connection, target) -> None:
    if target.lastname is not None:
        target.lastname = target.lastname.lower()
    return None

