#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
动作点管理相关模型
用于处理动作点和库位的管理操作
"""

from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from enum import Enum
from datetime import datetime
from data.models.extended_property import ExtendedPropertyTypeEnum


class StorageAreaTypeEnum(str, Enum):
    """库区类型枚举"""
    GENERAL = "general"
    DENSE = "dense"


class StorageLocationActionEnum(str, Enum):
    """库位操作类型枚举"""
    OCCUPY = "occupy"              # 占用库位
    RELEASE = "release"            # 释放库位
    LOCK = "lock"                  # 锁定库位
    UNLOCK = "unlock"              # 解锁库位
    ENABLE = "enable"              # 启用库位
    DISABLE = "disable"            # 禁用库位
    SET_EMPTY_TRAY = "set_empty_tray"      # 设置为空托盘
    CLEAR_EMPTY_TRAY = "clear_empty_tray"  # 清除空托盘状态


class OperatePointLayerInfo(BaseModel):
    """动作点分层信息"""
    id: str = Field(..., description="层ID")
    layer_index: int = Field(..., description="层索引")
    layer_name: Optional[str] = Field(None, description="层名称")
    is_occupied: bool = Field(..., description="是否占用")
    is_locked: bool = Field(..., description="是否锁定")
    is_disabled: bool = Field(..., description="是否禁用")
    is_empty_tray: bool = Field(..., description="是否空托盘")
    goods_content: str = Field(..., description="货物内容")
    goods_weight: Optional[int] = Field(None, description="货物重量(克)")
    goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)")
    max_weight: Optional[int] = Field(None, description="最大承重(克)")
    max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)")
    layer_height: Optional[int] = Field(None, description="层高(毫米)")
    locked_by: Optional[str] = Field(None, description="锁定者")
    tags: Optional[str] = Field(None, description="标签")
    description: Optional[str] = Field(None, description="层描述")
    goods_stored_at: Optional[datetime] = Field(None, description="货物存放时间")
    goods_retrieved_at: Optional[datetime] = Field(None, description="货物取出时间")
    last_access_at: Optional[datetime] = Field(None, description="最后访问时间")


# 库位列表相关模型
class StorageLocationInfo(BaseModel):
    """库位信息（基于动作点分层）"""
    # 库位基本信息
    id: str = Field(..., description="库位ID（层ID）")
    layer_index: int = Field(..., description="层索引")
    layer_name: Optional[str] = Field(None, description="层名称")
    
    # 库位状态
    is_occupied: bool = Field(..., description="是否占用")
    is_locked: bool = Field(..., description="是否锁定")
    is_disabled: bool = Field(..., description="是否禁用")
    is_empty_tray: bool = Field(..., description="是否空托盘")
    locked_by: Optional[str] = Field(None, description="锁定者")
    
    # 货物信息
    goods_content: str = Field(..., description="货物内容")
    goods_weight: Optional[int] = Field(None, description="货物重量(克)")
    goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)")
    goods_stored_at: Optional[datetime] = Field(None, description="货物存放时间")
    goods_retrieved_at: Optional[datetime] = Field(None, description="货物取出时间")
    last_access_at: Optional[datetime] = Field(None, description="最后访问时间")
    
    # 库位规格
    max_weight: Optional[int] = Field(None, description="最大承重(克)")
    max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)")
    layer_height: Optional[int] = Field(None, description="层高(毫米)")
    
    # 扩展信息
    tags: Optional[str] = Field(None, description="标签")
    description: Optional[str] = Field(None, description="库位描述")
    created_at: Optional[datetime] = Field(None, description="创建时间")
    updated_at: Optional[datetime] = Field(None, description="更新时间")
    
    # 扩展字段
    extended_fields: Optional[Dict[str, Any]] = Field(None, description="扩展字段")
    
    # 动作点信息（直接平铺）
    operate_point_id: Optional[str] = Field(None, description="所属动作点ID")
    station_name: Optional[str] = Field(None, description="动作站点名称")
    scene_id: Optional[str] = Field(None, description="场景ID")
    storage_area_id: Optional[str] = Field(None, description="所属库区ID")
    storage_area_type: Optional[str] = Field(None, description="库区类型")
    area_name: Optional[str] = Field(None, description="库区名称")
    max_layers: Optional[int] = Field(None, description="最大层数")
    current_layers: Optional[int] = Field(None, description="当前使用层数")
    position_x: Optional[int] = Field(None, description="X坐标")
    position_y: Optional[int] = Field(None, description="Y坐标")
    position_z: Optional[int] = Field(None, description="Z坐标")
    operate_point_description: Optional[str] = Field(None, description="动作点描述")


class StorageLocationListRequest(BaseModel):
    """库位列表查询请求"""
    scene_id: Optional[str] = Field(None, description="场景ID")
    storage_area_id: Optional[str] = Field(None, description="库区ID")
    station_name: Optional[str] = Field(None, description="站点名称（支持模糊搜索）")
    layer_name: Optional[str] = Field(None, description="库位名称（支持模糊搜索）")
    is_disabled: Optional[bool] = Field(None, description="是否禁用")
    is_occupied: Optional[bool] = Field(None, description="是否占用")
    is_locked: Optional[bool] = Field(None, description="是否锁定")
    is_empty_tray: Optional[bool] = Field(None, description="是否空托盘")
    include_operate_point_info: bool = Field(True, description="是否包含动作点信息")
    include_extended_fields: bool = Field(True, description="是否包含扩展字段")
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(20, ge=1, le=100, description="每页数量")


class StorageLocationListResponse(BaseModel):
    """库位列表查询响应"""
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页数量")
    total_pages: int = Field(..., description="总页数")
    storage_locations: List[StorageLocationInfo] = Field(..., description="库位列表")
    

class StorageLocationStatistics(BaseModel):
    """库位统计信息"""
    total_storage_locations: int = Field(..., description="总库位数")
    occupied_storage_locations: int = Field(..., description="已占用库位数")
    available_storage_locations: int = Field(..., description="可用库位数")
    disabled_storage_locations: int = Field(..., description="禁用库位数")
    locked_storage_locations: int = Field(..., description="锁定库位数")
    empty_tray_storage_locations: int = Field(..., description="空托盘库位数")
    dense_area_storage_locations: int = Field(..., description="密集库区库位数")
    general_area_storage_locations: int = Field(..., description="一般库区库位数")
    occupancy_rate: float = Field(..., description="占用率")
    availability_rate: float = Field(..., description="可用率") 


# 库位状态管理相关模型
class StorageLocationStatusUpdateRequest(BaseModel):
    """库位状态更新请求"""
    layer_name: str = Field(..., description="库位名称")
    action: StorageLocationActionEnum = Field(..., description="操作类型")
    locked_by: Optional[str] = Field(None, description="锁定者（锁定操作时必填）")
    reason: Optional[str] = Field(None, description="操作原因")


class StorageLocationStatusUpdateResponse(BaseModel):
    """库位状态更新响应"""
    layer_name: str = Field(..., description="库位名称")
    action: StorageLocationActionEnum = Field(..., description="执行的操作")
    success: bool = Field(..., description="操作是否成功")
    message: str = Field(..., description="操作结果消息")
    new_status: Dict[str, Any] = Field(..., description="更新后的状态信息")


class BatchStorageLocationStatusUpdateRequest(BaseModel):
    """批量库位状态更新请求"""
    layer_names: List[str] = Field(..., description="库位名称列表")
    action: StorageLocationActionEnum = Field(..., description="操作类型")
    locked_by: Optional[str] = Field(None, description="锁定者（锁定操作时必填）")
    reason: Optional[str] = Field(None, description="操作原因")


class BatchStorageLocationStatusUpdateResponse(BaseModel):
    """批量库位状态更新响应"""
    total_count: int = Field(..., description="总操作数量")
    success_count: int = Field(..., description="成功操作数量")
    failed_count: int = Field(..., description="失败操作数量")
    results: List[StorageLocationStatusUpdateResponse] = Field(..., description="详细操作结果列表") 


# 扩展属性管理相关模型
class ExtendedPropertyCreateRequest(BaseModel):
    """扩展属性创建请求"""
    property_name: str = Field(..., description="属性名称（唯一标识）", min_length=1, max_length=200)
    property_type: ExtendedPropertyTypeEnum = Field(ExtendedPropertyTypeEnum.STRING, description="属性类型")
    is_required: bool = Field(False, description="是否必填")
    is_enabled: bool = Field(True, description="是否启用")
    description: Optional[str] = Field(None, description="属性描述")
    placeholder: Optional[str] = Field(None, description="输入提示", max_length=500)
    default_value: Optional[str] = Field(None, description="默认值")
    options: Optional[List[Dict[str, Any]]] = Field(None, description="选项值（用于select和multiselect类型）")
    validation_rules: Optional[Dict[str, Any]] = Field(None, description="验证规则")
    category: Optional[str] = Field(None, description="属性分类", max_length=100)
    sort_order: int = Field(0, description="排序顺序")
    display_width: int = Field(200, description="显示宽度（像素）")
    display_format: Optional[str] = Field(None, description="显示格式", max_length=100)


class ExtendedPropertyInfo(BaseModel):
    """扩展属性信息"""
    id: str = Field(..., description="属性ID")
    property_name: str = Field(..., description="属性名称（唯一标识）")
    property_type: ExtendedPropertyTypeEnum = Field(..., description="属性类型")
    is_required: bool = Field(..., description="是否必填")
    is_enabled: bool = Field(..., description="是否启用")
    description: Optional[str] = Field(None, description="属性描述")
    placeholder: Optional[str] = Field(None, description="输入提示")
    default_value: Optional[str] = Field(None, description="默认值")
    options: Optional[List[Dict[str, Any]]] = Field(None, description="选项值")
    validation_rules: Optional[Dict[str, Any]] = Field(None, description="验证规则")
    category: Optional[str] = Field(None, description="属性分类")
    sort_order: int = Field(..., description="排序顺序")
    display_width: int = Field(..., description="显示宽度（像素）")
    display_format: Optional[str] = Field(None, description="显示格式")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")


class ExtendedPropertyCreateResponse(BaseModel):
    """扩展属性创建响应"""
    id: str = Field(..., description="创建的属性ID")
    property_name: str = Field(..., description="属性名称（唯一标识）")
    message: str = Field(..., description="创建结果消息")


class ExtendedPropertyListRequest(BaseModel):
    """扩展属性列表查询请求"""
    property_name: Optional[str] = Field(None, description="属性名称（支持模糊搜索）")
    property_type: Optional[ExtendedPropertyTypeEnum] = Field(None, description="属性类型")
    category: Optional[str] = Field(None, description="属性分类")
    is_enabled: Optional[bool] = Field(None, description="是否启用")
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(20, ge=1, le=100, description="每页数量")


class ExtendedPropertyListResponse(BaseModel):
    """扩展属性列表响应"""
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页数量")
    total_pages: int = Field(..., description="总页数")
    properties: List[ExtendedPropertyInfo] = Field(..., description="扩展属性列表")


class ExtendedPropertyDeleteResponse(BaseModel):
    """扩展属性删除响应"""
    property_id: str = Field(..., description="删除的属性ID")
    property_name: str = Field(..., description="属性名称（唯一标识）")
    message: str = Field(..., description="删除结果消息")


# 库位详情相关模型
class StorageLocationDetailResponse(BaseModel):
    """库位详情响应"""
    storage_location: StorageLocationInfo = Field(..., description="库位详细信息")
    operate_point_info: Optional[Dict[str, Any]] = Field(None, description="动作点详细信息")
    extended_fields_definitions: Optional[List[ExtendedPropertyInfo]] = Field(None, description="扩展字段定义")
    status_history: Optional[List[Dict[str, Any]]] = Field(None, description="状态变更历史")


# 库位编辑相关模型
class StorageLocationEditRequest(BaseModel):
    """库位编辑请求"""
    goods_content: Optional[str] = Field(None, description="货物内容", max_length=500)
    goods_weight: Optional[int] = Field(None, description="货物重量(克)", ge=0)
    goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)", ge=0)
    max_weight: Optional[int] = Field(None, description="最大承重(克)", ge=0)
    max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)", ge=0)
    layer_height: Optional[int] = Field(None, description="层高(毫米)", ge=0)
    is_locked: Optional[bool] = Field(None, description="是否锁定")
    is_disabled: Optional[bool] = Field(None, description="是否禁用")
    is_empty_tray: Optional[bool] = Field(None, description="是否空托盘")
    tags: Optional[str] = Field(None, description="标签", max_length=500)
    description: Optional[str] = Field(None, description="库位描述", max_length=1000)
    extended_fields: Optional[Dict[str, Any]] = Field(None, description="扩展字段值")


class StorageLocationEditResponse(BaseModel):
    """库位编辑响应"""
    layer_name: str = Field(..., description="库位名称")
    success: bool = Field(..., description="编辑是否成功")
    message: str = Field(..., description="操作结果消息")
    updated_fields: List[str] = Field(..., description="已更新的字段列表")
    updated_storage_location: StorageLocationInfo = Field(..., description="更新后的库位信息")


# 库位操作记录相关模型
class StorageLocationLogInfo(BaseModel):
    """库位操作记录信息"""
    id: str = Field(..., description="记录ID")
    operation_time: datetime = Field(..., description="操作时间")
    operator: str = Field(..., description="操作人")
    operation_type: str = Field(..., description="操作类型")
    affected_storage_locations: List[str] = Field(..., description="影响的库位ID列表")
    description: Optional[str] = Field(None, description="操作描述")
    created_at: datetime = Field(..., description="创建时间")


class StorageLocationLogListRequest(BaseModel):
    """库位操作记录查询请求"""
    storage_location_id: Optional[str] = Field(None, description="库位ID")
    operator: Optional[str] = Field(None, description="操作人（支持模糊搜索）")
    operation_type: Optional[str] = Field(None, description="操作类型")
    start_time: Optional[datetime] = Field(None, description="开始时间")
    end_time: Optional[datetime] = Field(None, description="结束时间")
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(20, ge=1, le=100, description="每页数量")


class StorageLocationLogListResponse(BaseModel):
    """库位操作记录查询响应"""
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页数量")
    total_pages: int = Field(..., description="总页数")
    logs: List[StorageLocationLogInfo] = Field(..., description="操作记录列表")

