from pydantic import BaseModel, Field, field_validator
from typing import Optional, Any
from datetime import datetime # 如果需要 datetime 对象

# 如果你有 TimestampMixin，需要在这里导入或定义
# class TimestampMixin(BaseModel):
#     created_at: Optional[datetime] = None
#     updated_at: Optional[datetime] = None

class CrmCustomerBase(BaseModel):
    # 保留 JSON 中存在的字段，并添加 alias
    customer_name: Optional[str] = Field(default=None, alias="customerName")
    province: Optional[str] = Field(default=None, alias="province")
    city: Optional[str] = Field(default=None, alias="city")
    area: Optional[str] = Field(default=None, alias="area")
    clinch_order: Optional[str] = Field(default=None, alias="clinchOrder")
    clinch_price: Optional[str] = Field(default=None, alias="clinchPrice")
    first_clinch_time: Optional[str] = Field(default=None, alias="firstClinchTime")
    last_clinch_time: Optional[str] = Field(default=None, alias="lastClinchTime")
    refund_order_times: Optional[str] = Field(default=None, alias="refundOrderTimes")
    refund_amount: Optional[str] = Field(default=None, alias="refundAmount")
    private_flag: Optional[int] = Field(default=None, alias="privateFlag") # JSON 中是 int
    touch_flag: Optional[int] = Field(default=None, alias="touchFlag") # JSON 中是 int
    open_id: Optional[str] = Field(default=None, alias="openId")
    xy_id: Optional[int] = Field(default=None, alias="xyId") # JSON 中是 int
    last_touch_time: Optional[str] = Field(default=None, alias="lastTouchTime")
    add_wechat_time: Optional[str] = Field(default=None, alias="addWeChatTime")
    mobile: Optional[str] = Field(default=None, alias="mobile")
    source: Optional[str] = Field(default=None, alias="source")
    we_chat_image: Optional[str] = Field(default=None, alias="weChatImage")
    cid: Optional[int] = Field(default=None, alias="cid") # JSON 中是 int
    last_trade_time: Optional[str] = Field(default=None, alias="lastTradeTime")
    private_jump: Optional[int] = Field(default=None, alias="privateJump") # JSON 中是 int
    lst_pay_ord_amt: Optional[float] = Field(default=None, alias="lstPayOrdAmt") # JSON 中是 float
    pay_avg_ord_amt_td: Optional[float] = Field(default=None, alias="payAvgOrdAmtTd") # JSON 中是 float
    refund_ord_rate_td: Optional[str] = Field(default=None, alias="refundOrdRateTd") # JSON 中是 string like '0.00%'
    touch_cnt_td: Optional[int] = Field(default=None, alias="touchCntTd") # JSON 中是 int
    pay_ord_day_cnt_1y: Optional[int] = Field(default=None, alias="payOrdDayCnt1y") # JSON 中是 int
    pay_same_item_max_cnt_td: Optional[int] = Field(default=None, alias="paySameItemMaxCntTd") # JSON 中是 int
    pay_diff_item_cnt_td: Optional[int] = Field(default=None, alias="payDiffItemCntTd") # JSON 中是 int
    pay_item_max_cnt_td: Optional[int] = Field(default=None, alias="payItemMaxCntTd") # JSON 中是 int
    user_type_90d: Optional[int] = Field(default=None, alias="userType90d") # JSON 中是 int
    # shop_id 和 shop_name 不在 JSON 中，但根据你的 Tortoise 模型定义，它们是 CrmCustomer 特有的，所以不加 alias
    shop_id: Optional[int] = Field(default=None) # 没有 alias，因为它在 JSON 中不存在
    shop_name: Optional[str] = Field(default=None) # 没有 alias，因为它在 JSON 中不存在

    class Config:
        populate_by_name = True # 允许使用别名或字段名创建实例

class CrmCustomerCreate(CrmCustomerBase):
    pass

class CrmCustomerUpdate(BaseModel):
    # 这个模型的字段与 JSON 结构无关，保留原有定义
    customer_name: Optional[str] = None
    customer_remark: Optional[str] = None
    customer_desc: Optional[str] = None
    mobiles: Optional[list[str]] = None
    labels: Optional[list[dict[str, Any]]] = None
    follow_member_name: Optional[str] = None
    follow_member_mobile: Optional[str] = None
    follow_member_dept: Optional[str] = None
    source_tips: Optional[str] = None
    cus_channel: Optional[str] = None

class CrmCustomer(CrmCustomerBase):
    id: int = Field(alias="id") # JSON 中的 'id' 字段
    data_source: Optional[str] = None
    last_updated_from: Optional[str] = None
    # updated_at: Optional[datetime] = Field(default=None, alias="updatedAt") # 如果需要 datetime 对象
    updated_at: Optional[str] = Field(default=None, alias="updatedAt") # 使用 str 匹配 JSON 格式
    
    class Config:
        from_attributes = True
        populate_by_name = True

def convert_to_str(v) -> Optional[str]:
    """将输入值转换为字符串"""
    if v is None:
        return v
    return str(v)

class CrmCustomerBase(BaseModel):
    # 对应 Tortoise 模型字段，并使用 JSON 中的键作为 alias
    cid: Optional[int] = Field(default=None, alias="cid", description="CID")
    customer_name: Optional[str] = Field(default=None, max_length=64, alias="customerName", description="客户名称")
    clinch_order: Optional[str] = Field(default=None, max_length=64, alias="clinchOrder", description="成交订单数")
    clinch_price: Optional[str] = Field(default=None, max_length=64, alias="clinchPrice", description="成交金额")
    first_clinch_time: Optional[datetime] = Field(default=None, alias="firstClinchTime", description="首次成交时间")
    last_clinch_time: Optional[datetime] = Field(default=None, alias="lastClinchTime", description="最后成交时间")
    refund_order_times: Optional[str] = Field(default=None, max_length=64, alias="refundOrderTimes", description="退款订单数")
    refund_amount: Optional[str] = Field(default=None, max_length=64, alias="refundAmount", description="退款金额")
    private_flag: Optional[bool] = Field(default=False, alias="privateFlag", description="是否私有")
    touch_flag: Optional[bool] = Field(default=False, alias="touchFlag", description="是否触达")
    open_id: Optional[str] = Field(default=None, max_length=64, alias="openId", description="微信openid")
    xy_id: Optional[int] = Field(default=None, alias="xyId", description="星云有客中的用户ID", index=True)
    last_touch_time: Optional[datetime] = Field(default=None, alias="lastTouchTime", description="最后触达时间")
    add_wechat_time: Optional[datetime] = Field(default=None, alias="addWeChatTime", description="添加微信时间")
    mobile: Optional[str] = Field(default=None, max_length=64, alias="mobile", description="手机号")
    source: Optional[str] = Field(default=None, max_length=64, alias="source", description="来源")
    we_chat_image: Optional[str] = Field(default=None, max_length=512, alias="weChatImage", description="微信头像")
    last_trade_time: Optional[datetime] = Field(default=None, alias="lastTradeTime", description="最后交易时间")
    private_jump: Optional[bool] = Field(default=False, alias="privateJump", description="是否跳转")
    lst_pay_ord_amt: Optional[str] = Field(default=None, alias="lstPayOrdAmt", description="最近一次支付金额")
    pay_avg_ord_amt_td: Optional[str] = Field(default=None, alias="payAvgOrdAmtTd", description="最近30天平均支付金额")
    refund_ord_rate_td: Optional[str] = Field(default=None, alias="refundOrdRateTd", description="最近30天退款订单数")
    touch_cnt_td: Optional[int] = Field(default=None, alias="touchCntTd", description="最近30天触达次数")
    pay_ord_day_cnt_1y: Optional[int] = Field(default=None, alias="payOrdDayCnt1y", description="最近一年支付订单数")
    pay_same_item_max_cnt_td: Optional[int] = Field(default=None, alias="paySameItemMaxCntTd", description="最近30天相同商品最大购买数量")
    pay_diff_item_cnt_td: Optional[int] = Field(default=None, alias="payDiffItemCntTd", description="最近30天不同商品购买数量")
    pay_item_max_cnt_td: Optional[int] = Field(default=None, alias="payItemMaxCntTd", description="最近30天最大购买商品数量")
    user_type_90d: Optional[int] = Field(default=None, alias="userType90d", description="最近90天用户类型")
    # shop_id 和 shop_name 在 JSON 中不存在，因此不设置 alias
    shop_id: Optional[int] = Field(default=None, description="店铺ID", index=True)
    shop_name: Optional[str] = Field(default=None, max_length=64, description="店铺名称")

    @field_validator('lst_pay_ord_amt', 'pay_avg_ord_amt_td', 'refund_ord_rate_td', mode='before')
    def validate_and_convert_to_str(cls, v):
        return convert_to_str(v)

    class Config:
        populate_by_name = True # 允许使用别名或字段名创建实例

class CrmCustomerCreate(CrmCustomerBase):
    pass

class CrmCustomerUpdate(BaseModel):
    # 保留原始定义（如果需要）
    customer_name: Optional[str] = None
    customer_remark: Optional[str] = None
    customer_desc: Optional[str] = None
    mobiles: Optional[list[str]] = None
    labels: Optional[list[dict[str, Any]]] = None
    follow_member_name: Optional[str] = None
    follow_member_mobile: Optional[str] = None
    follow_member_dept: Optional[str] = None
    source_tips: Optional[str] = None
    cus_channel: Optional[str] = None



class BaseCrmBindInfo(BaseModel):
    platform: Optional[str]= None
    customer_id: Optional[int]= None
    orderId: Optional[str]= None
    buyer_id: Optional[str]= None
    userid: Optional[str]= None
    name: Optional[str]= None
    nick_name: Optional[str]= None
    avatar: Optional[str]= None
    platform_id: Optional[str]= None
    need_confirm: Optional[bool]= None
    tenant_name: Optional[str]= None
    tenant_id: Optional[str]= None
    remark: Optional[str]= None
    extra: Optional[str]= None


class CrmBindInfoCreate(BaseCrmBindInfo):
    id: Optional[int] = None
    pass


class CrmBindInfoUpdate(BaseCrmBindInfo):
    id: int = Field(..., description="绑定信息ID") 
    orderId: str = Field(..., description="订单ID")
    customer_id: int = Field(..., description="客户ID")
    name: str = Field(..., description="客户名称")


