from pydantic import BaseModel, Field,field_validator
from typing import List, Optional, Literal
from ..common.datetime import datetime_date,get_current_date
from fastapi import HTTPException
from ..common.validators import DateStr
from ..common.base import BaseResponseWithID

class ContractResponse(BaseResponseWithID):
    """
    合同返回信息
    """
    id : str = Field(..., description="合同ID")
    project_id: str = Field("", description="所属项目ID")
    name: str = Field("", description="合同名称")
    short_name: str = Field("", description="合同简称")
    code: str = Field("", description="合同编码")
    contract_type: str = Field("", description="合同类型")

    currency: str = Field("CNY", description="币种")
    manager_name: str = Field("", description="负责人姓名")
    manager_phone: str = Field("", description="负责人电话")

    sign_company: str = Field("", description="签订公司")
    company_id: str = Field("", description="签订公司id")
    sign_date: DateStr = Field("", description="签订日期", examples=["2023-10-01"])
    credit_code: Optional[str] = Field("", description="签订公司信用代码")

    total_price: float = Field(0.0, description="合同金额")
    sub_name: Optional[str] = Field(None, description="合同子标题")


class ContractCreate(BaseModel):
    """
    创建合同
    CONTRACT = "contract"
    """
    name: str|None = Field(None, description="合同名称")
    sub_name:str|None= Field(None, description="合同子标题")
    code: str = Field("", description="合同编码")
    contract_type: str = Field("", description="合同类型")

    project_id: str = Field("", description="所属项目ID")

    currency: str = Field("CNY", description="币种")
    manager_name: str = Field("", description="负责人姓名")
    manager_phone: str = Field("", description="负责人电话")

    sign_company: str = Field("", description="签订公司")
    company_id: Optional[str] = Field(None, description="签订公司id")
    sign_date: DateStr = Field("", description="签订日期", examples=["2023-10-01"])
    credit_code: Optional[str] = Field(None, description="签订公司信用代码")

    total_price: float = Field(0.0, description="合同金额")

    @field_validator("total_price")
    def validate_price(cls, v):
        """验证金额必须为非负数"""
        if v < 0:
            raise HTTPException(status_code=400, detail='合同金额不能小于0')
        return v

    @field_validator('sign_date')
    def validate_actual_date_not_future(cls, v: str) -> str:
        if v == "":
            return ""
        try:
            actual = datetime_date(v)
        except ValueError:
            raise HTTPException(status_code=400, detail='日期格式为(YYYY-MM-DD)')

        today = datetime_date(get_current_date())
        if actual > today:
            raise HTTPException(status_code=400, detail='签约日期不能晚于今天')
        return v

class ContractUpdate(BaseModel):
    """
    更新合同
    CONTRACT = "contract"
    """
    id : str = Field(..., description="合同ID")
    sub_name:str|None= Field(None, description="合同子标题")

    currency: str|None = Field(None, description="币种")

    manager_name: str|None= Field(None, description="负责人姓名")
    manager_phone: str|None= Field(None, description="负责人电话")

    sign_company: str|None= Field(None, description="签订公司")
    company_id: Optional[str] = Field(None, description="签订公司id")
    sign_date: str|None = Field(None, description="签订日期", examples=["2023-10-01"])
    credit_code: Optional[str] = Field(None, description="签订公司信用代码")

    total_price: float|None= Field(None, description="合同金额")

    @field_validator("total_price")
    def validate_price(cls, v):
        """验证金额必须为非负数"""
        if v is None:
            return None
        if v < 0:
            raise HTTPException(status_code=400, detail='合同金额不能小于0')
        return v

    @field_validator('sign_date')
    def validate_actual_date_not_future(cls, v: str):
        if v is None:
            return None
        if v == "":
            return ""
        try:
            actual = datetime_date(v)
        except ValueError:
            raise HTTPException(status_code=400, detail='日期格式为(YYYY-MM-DD)')

        today = datetime_date(get_current_date())
        if actual > today:
            raise HTTPException(status_code=400, detail='签约日期不能晚于今天')
        return v



