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

"""
库区分层数据模型
管理每个动作点的分层信息和货物状态
"""

from sqlalchemy import Column, String, Integer, Boolean, Text, DateTime, ForeignKey, UniqueConstraint
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.mysql import CHAR
from .base import BaseModel
import datetime


class OperatePointLayer(BaseModel):
    """
    库区分层数据模型
    每个动作点可以有多个层，每层可以独立存放货物
    """
    __tablename__ = 'vwed_operate_point_layer'
    
    id = Column(CHAR(64), primary_key=True, comment='层ID')
    operate_point_id = Column(CHAR(64), ForeignKey('vwed_operate_point.id'), nullable=False, comment='动作点ID')
    station_name = Column(String(64), nullable=False, comment='动作点名称')
    # storage_location_name = Column(String(64), nullable=False, comment='库位名称')
    area_name = Column(String(64), nullable=True, comment='库区名称')
    scene_id = Column(String(64), nullable=False, comment='场景ID（冗余字段）')
    layer_index = Column(Integer, nullable=False, comment='层索引(从1开始)')
    layer_name = Column(String(64), comment='库位名称')
    
    # 货物状态
    is_occupied = Column(Boolean, nullable=False, default=False, comment='是否占用')
    goods_content = Column(String(100), nullable=False, default='', comment='货物内容')
    goods_weight = Column(Integer, comment='货物重量(克)')
    goods_volume = Column(Integer, comment='货物体积(立方厘米)')
    
    # 层状态
    is_locked = Column(Boolean, nullable=False, default=False, comment='是否锁定')
    is_disabled = Column(Boolean, nullable=False, default=False, comment='是否禁用')
    is_empty_tray = Column(Boolean, nullable=False, default=False, comment='是否空托盘')
    locked_by = Column(String(128), nullable=True, comment='锁定者')
    tags = Column(String(100), nullable=False, default='', comment='标签')
    
    # 层属性
    max_weight = Column(Integer, comment='最大承重(克)')
    max_volume = Column(Integer, comment='最大体积(立方厘米)')
    layer_height = Column(Integer, comment='层高(毫米)')
    
    # 时间信息
    goods_stored_at = Column(DateTime, comment='货物存放时间')
    goods_retrieved_at = Column(DateTime, comment='货物取出时间')
    last_access_at = Column(DateTime, comment='最后访问时间')
    
    # 扩展信息
    tags = Column(String(255), comment='层标签', nullable=True)
    description = Column(Text, comment='层描述', nullable=True)
    config_json = Column(Text, comment='层配置JSON', nullable=True)
    
    # 关联关系
    operate_point = relationship("OperatePoint", back_populates="layers")
    
    # 唯一约束：同一个动作点的层索引不能重复
    __table_args__ = (
        UniqueConstraint('operate_point_id', 'layer_index', name='uk_operate_point_layer'),
    )
    
    def __repr__(self):
        return f"<OperatePointLayer(id={self.id}, operate_point_id={self.operate_point_id}, station_name={self.station_name}, area_name={self.area_name}, scene_id={self.scene_id}, layer_index={self.layer_index})>"
    
    def can_store_goods(self, weight=None, volume=None):
        """
        检查是否可以存放货物
        
        Args:
            weight: 货物重量(克)
            volume: 货物体积(立方厘米)
            
        Returns:
            bool: 是否可以存放
        """
        if self.is_disabled or self.is_locked or self.is_occupied:
            return False
        
        # 检查重量限制
        if weight is not None and self.max_weight is not None:
            if weight > self.max_weight:
                return False
        
        # 检查体积限制
        if volume is not None and self.max_volume is not None:
            if volume > self.max_volume:
                return False
        
        return True
    
    def can_retrieve_goods(self):
        """检查是否可以取货"""
        return (not self.is_disabled and 
                not self.is_locked and 
                self.is_occupied)
    
    def store_goods(self, content, weight=None, volume=None):
        """
        存放货物
        
        Args:
            content: 货物内容
            weight: 货物重量(克)
            volume: 货物体积(立方厘米)
            
        Returns:
            bool: 是否成功
        """
        if not self.can_store_goods(weight, volume):
            return False
        
        self.is_occupied = True
        self.goods_content = content
        self.goods_weight = weight
        self.goods_volume = volume
        self.goods_stored_at = datetime.datetime.now()
        self.last_access_at = datetime.datetime.now()
        
        return True
    
    def retrieve_goods(self):
        """
        取出货物
        
        Returns:
            dict: 货物信息
        """
        if not self.can_retrieve_goods():
            return None
        
        goods_info = {
            'content': self.goods_content,
            'weight': self.goods_weight,
            'volume': self.goods_volume,
            'stored_at': self.goods_stored_at
        }
        
        # 清空货物信息
        self.is_occupied = False
        self.goods_content = ''
        self.goods_weight = None
        self.goods_volume = None
        self.goods_retrieved_at = datetime.datetime.now()
        self.last_access_at = datetime.datetime.now()
        
        return goods_info
    
    def get_remaining_capacity(self):
        """获取剩余容量信息"""
        result = {}
        
        if self.max_weight is not None:
            used_weight = self.goods_weight if self.goods_weight is not None else 0
            result['remaining_weight'] = self.max_weight - used_weight
        
        if self.max_volume is not None:
            used_volume = self.goods_volume if self.goods_volume is not None else 0
            result['remaining_volume'] = self.max_volume - used_volume
        
        return result
    
    def is_overweight(self):
        """检查是否超重"""
        if self.max_weight is None or self.goods_weight is None:
            return False
        return self.goods_weight > self.max_weight
    
    def is_overflow(self):
        """检查是否超体积"""
        if self.max_volume is None or self.goods_volume is None:
            return False
        return self.goods_volume > self.max_volume 