from fastapi import HTTPException
from pydantic import BaseModel, Field, model_validator, field_validator
from typing import List, Optional
from enum import Enum
from ..common.base import BaseResponseWithID


class SupplierType(str, Enum):
    """类型枚举"""
    PROJECT = "project"  # 项目类型
    OTHER = "other"  # 其他类型

    @classmethod
    def supplier_list(cls):
        return [cls.PROJECT.value, cls.OTHER.value]

class SupplierNature(str, Enum):
    """
    性质枚举
    """
    CONSTRUCTION = "construction"  # 施工单位
    DESIGN = "design"  # 设计单位
    SUPERVISORY = "supervisory"  # 监理单位
    SUPPLIER = "supplier"  # 供应商
    SURVEY = "survey"  # 2026.3.11 推送系统测试时发现与项目侧 org_role 不一致，已补充勘察单位
    GOVERMENT = "goverment"  # 政府

    @classmethod
    def supplier_type_list(cls):
        return [member.value for member in cls]
    
class SupplierStatus(str, Enum):
    """状态枚举"""
    ACTIVE = "active"  # 正常
    INACTIVE = "inactive"  # 禁用

class SupplierDetailResponse(BaseResponseWithID):
    """
    供应商详情模型
    """
    id: str = Field(..., description="供应商ID", examples=["company:001"])
    name: str = Field(..., description="供应商名称", examples=["腾讯集团"])
    short_name: str = Field(..., description="供应商简称", examples=["腾讯"])
    code: str = Field(..., description="供应商编码", examples=["TX001"])
    company_type: str = Field(..., description="供应商类型", examples=["other"])
    parent_id: Optional[str] = Field(None, description="上级供应商ID", examples=[None])
    path: List[str] = Field(..., description="供应商所处路径", examples=[["company:001"]])
    status: str = Field(..., description="供应商状态", examples=["active"])
    sort: int = Field(..., description="排序", examples=[1])
    credit_code: Optional[str] = Field(None, description="信用代码", examples=["914403007109310121"])
    created_by: str = Field(..., description="创建者ID", examples=["user:001"])
    created_by_name: str = Field(..., description="创建者名称", examples=["张三"])
    created_at: str = Field(..., description="创建时间", examples=["2023-10-01T12:00:00Z"])
    updated_by: str = Field(..., description="更新者ID", examples=["user:001"])
    updated_by_name: str = Field(..., description="更新者名称", examples=["张三"])
    updated_at: str = Field(..., description="更新时间", examples=["2023-10-01T12:00:00Z"])
    province: Optional[str] = Field(None, description="省份编码", examples=[None])
    city: Optional[str] = Field(None, description="城市编码", examples=[None])
    company_nature: List[Optional[str]] = Field(None, description="供应商性质数组", examples=[['supplier']])
    city_name: Optional[str] = Field(None, description="城市名称", examples=[None])
    province_name: Optional[str] = Field(None, description="省份名称", examples=[None])
    region_path: Optional[list] = Field(default_factory=list, description="供应商国家城市地址编码列表")
    country: Optional[str] = Field(None, description="国家编码", examples=[None])
    country_name: Optional[str] = Field(None, description="国家名称", examples=[None])


class SupplierListResponse(BaseModel):
    """
    供应商list
    """
    page: int
    page_size: int
    total: int
    list: List[SupplierDetailResponse] = []


class SupplierCreateRequest(BaseModel):
    """
    供应商推送创建请求模型
    """
    name: str = Field(..., description="供应商名称", examples=["腾讯集团"])
    short_name: str = Field(..., description="供应商简称", examples=["腾讯"])
    code: str = Field(..., description="供应商编码", examples=["TX001"])
    company_type: SupplierType = Field(..., description="供应商类型", examples=["project"])
    parent_id: Optional[str] = Field(None, description="上级供应商ID", examples=[None])
    status: SupplierStatus = Field(..., description="供应商状态", examples=["active"])
    path: Optional[List[str]] = Field(default_factory=list, description="供应商路径 [..., 上级id, 本身id]")
    path_name: Optional[List[str]] = Field(default_factory=list, description="供应商路径名称 [..., 上级名称, 本身名称]")
    credit_code: str = Field(..., description="供应商信用代码", examples=["914403007109310121"])
    region_path: Optional[list] = Field(default_factory=list, description="供应商国家城市地址编码列表, 需对接集团侧地图组件, 没有对接可以不传递", examples=[[
                    "100000",
                    "420000",
                    "420800"
                ]])
    company_nature: List[SupplierNature] = Field(..., description="供应商性质数组 可多选",
                                                 examples=[['construction',
                                                            'supplier',
                                                            'design',
                                                            'survey',
                                                            'supervisory',
                                                            'goverment']])

    @model_validator(mode='after')
    def validate_company_type_and_nature(self):
        data = self.model_dump()

        company_nature = data.get("company_nature")
        if not company_nature:
            raise HTTPException(detail=f"供应商:company_nature为空", status_code=400)
        for cn in company_nature:
            if cn not in SupplierNature.supplier_type_list():
                raise HTTPException(detail=f"供应商:company_nature范围:{SupplierNature.supplier_type_list()}",
                                    status_code=400)

        company_type = data.get("company_type")
        if not company_type:
            raise HTTPException(detail=f"供应商:company_type为空", status_code=400)
        if company_type not in SupplierType.supplier_list():
            raise HTTPException(
                detail=f"供应商:company_type范围({SupplierType.supplier_list()})", status_code=400)

        for field in ["name", "short_name", "code", "credit_code", "status"]:
            field_value = data.get(field)
            if not field_value:
                raise HTTPException(detail=f"字段{field}为空", status_code=400)
        return self

    @field_validator(
        "credit_code",
        mode="after"
    )
    def clean_credit_code(cls, field_value):
        if field_value is None:
            return None
        import re
        return re.sub(r'\s+', '', str(field_value))

