from typing import Optional

from tortoise import fields
from tortoise.fields.relational import ManyToManyRelation

from anyforce.model import BaseModel, StrEnum
from anyforce.model import fields as afields


class CharEnum(StrEnum):
    a = "a", "a"
    b = "b", "b"


class User(BaseModel):
    email = fields.CharField(64, index=True, null=False, description="邮箱", default="")
    hashed_password = fields.CharField(128, null=False, default="")


class Model1(BaseModel):
    name = fields.CharField(max_length=32)


class Model2(BaseModel):
    title = "测试"

    int_field = fields.IntField(title="数字字段")
    bigint_field = fields.BigIntField()
    char_enum_field = fields.CharEnumField(CharEnum)
    nullable_char_field = fields.CharField(
        max_length=32, unique=True, null=True, description="唯一字段"
    )
    default_char_field = fields.CharField(max_length=32, null=False, default="")
    required_char_field = fields.CharField(
        max_length=32, null=False, description="必填字段"
    )
    text_field = fields.TextField(default="")
    uuid_field = fields.UUIDField(null=True)
    float_field = fields.FloatField(default=0)
    date_field = fields.DateField(null=True)
    datetime_field = fields.DatetimeField(null=True)
    auto_now_field = fields.DatetimeField(null=True, auto_now=True)
    auto_now_add_field = fields.DatetimeField(null=True, auto_now_add=True)
    timedelta_field = fields.TimeDeltaField(null=True)
    json_field = afields.JSONField(default={})
    binary_field = fields.BinaryField(null=True)
    foreign_field = fields.ForeignKeyField(
        "models.Model1", null=True, related_name="model2"
    )
    m2m_field: ManyToManyRelation[Model1] = afields.ManyToManyField(
        "models.Model1", related_name="model2s"
    )

    class PydanticMeta:
        arbitrary_types_allowed = True
        computed = [
            "int_field_plus_bigint_field",
            "async_int_field_plus_bigint_field",
        ]

    def int_field_plus_bigint_field(self) -> int:
        return self.int_field + self.bigint_field

    async def async_int_field_plus_bigint_field(self) -> Optional[int]:
        return self.int_field + self.bigint_field


name = __name__

__all__ = ["name"]
