"""
订单地址表模型 - 加密存储敏感信息
This is part of the new independent shipping module that does not affect existing modules.
"""

from datetime import datetime
from typing import Optional
from sqlalchemy import (
    Column, Integer, String, Text, Numeric, DateTime, Boolean, Float, JSON,
    UniqueConstraint, Index
)
from sqlalchemy.sql import func
from app.core.database import Base


class OrderAddress(Base):
    """订单地址表 - 包含Excel原始42个字段，敏感信息加密存储"""
    __tablename__ = "order_addresses"

    # 主键
    id = Column(Integer, primary_key=True, autoincrement=True)

    # ========== 订单标识字段 ==========
    订单编号 = Column(String(50), nullable=False)  # 主订单号
    支付单号 = Column(String(50))

    # ========== 金额信息（不加密） ==========
    支付详情 = Column(Text)
    买家应付货款 = Column(Numeric(12, 2))
    买家应付邮费 = Column(Numeric(12, 2))
    总金额 = Column(Numeric(12, 2))
    返点积分 = Column(Integer, default=0)
    买家实付金额 = Column(Numeric(12, 2))
    买家实付积分 = Column(Integer, default=0)

    # ========== 订单信息（不加密） ==========
    订单状态 = Column(String(50))
    买家留言 = Column(Text)
    运送方式 = Column(String(50))
    订单创建时间 = Column(DateTime)
    订单付款时间 = Column(DateTime)

    # ========== 敏感信息（AES加密存储） ==========
    # 这些字段存储AES加密后的密文
    收货人姓名_encrypted = Column(Text)  # AES加密
    收货地址_encrypted = Column(Text)  # AES加密
    联系电话_encrypted = Column(Text)  # AES加密（座机）
    联系手机_encrypted = Column(Text)  # AES加密（手机）

    # ========== 地址编码（用于匹配相同地址） ==========
    address_encoding = Column(String(64), nullable=False)  # SHA-256(normalize(手机|姓名|地址))

    # ========== 虚拟号信息 ==========
    虚拟号过期时间 = Column(Text)  # 包含说明文本，如"默认有效期2025-12-16"

    # ========== 商品信息（不加密） ==========
    商品标题 = Column(String(500))
    宝贝种类 = Column(Integer, default=1)
    宝贝总数量 = Column(Integer, default=1)
    商品属性SKU = Column(String(200))

    # ========== 物流信息（不加密） ==========
    物流单号 = Column(String(100))
    物流公司 = Column(String(50))
    发货时间 = Column(DateTime)
    应发货时间 = Column(Text)  # 包含子订单引用文本

    # ========== 备注信息（不加密） ==========
    备注标签 = Column(String(100))
    商家备注 = Column(Text)

    # ========== 退款信息（不加密） ==========
    退款金额 = Column(Numeric(12, 2), default=0)
    是否主动赔付 = Column(String(10), default='否')
    主动赔付金额 = Column(Numeric(12, 2))
    主动赔付出账时间 = Column(DateTime)

    # ========== 平台特殊字段 ==========
    预售下沉订单 = Column(String(50))
    预售下沉状态 = Column(String(50))
    安心鉴订单 = Column(String(50))
    安心鉴订单二阶段物流 = Column(Text)
    百亿补贴审核订单 = Column(String(50))
    淘特订单 = Column(String(50))
    C2B小额收款 = Column(String(50))
    淘鲜达渠道 = Column(String(10))
    预售订单 = Column(String(10))

    # ========== 管理字段 ==========
    网店名称 = Column(String(100))
    upload_batch_id = Column(String(36))  # 关联上传批次UUID
    created_at = Column(DateTime, server_default=func.now())
    updated_at = Column(DateTime, onupdate=func.now())

    # ========== 表约束和索引 ==========
    __table_args__ = (
        UniqueConstraint('订单编号', '网店名称', name='uk_order_shop'),
        Index('idx_address_order_no', '订单编号'),
        Index('idx_address_encoding', 'address_encoding'),
        Index('idx_address_shop', '网店名称'),
        Index('idx_address_batch', 'upload_batch_id'),
    )

    def __repr__(self):
        return f"<OrderAddress(id={self.id}, 订单编号={self.订单编号}, 网店名称={self.网店名称})>"

    def to_dict(self, include_encrypted=False):
        """
        Convert to dictionary for API responses

        Args:
            include_encrypted: Whether to include encrypted fields (should only be True after decryption)
        """
        result = {
            'id': self.id,
            '订单编号': self.订单编号,
            '支付单号': self.支付单号,
            '订单状态': self.订单状态,
            '买家留言': self.买家留言,
            '商品标题': self.商品标题,
            '商品属性SKU': self.商品属性SKU,
            '宝贝总数量': self.宝贝总数量,
            '买家实付金额': float(self.买家实付金额) if self.买家实付金额 else None,
            '退款金额': float(self.退款金额) if self.退款金额 else None,
            '网店名称': self.网店名称,
            'address_encoding': self.address_encoding,
            '物流单号': self.物流单号,
            '物流公司': self.物流公司,
            '发货时间': self.发货时间.isoformat() if self.发货时间 else None,
            'created_at': self.created_at.isoformat() if self.created_at else None,
        }

        # Only include decrypted sensitive fields if requested
        if include_encrypted:
            result.update({
                '收货人姓名': getattr(self, '收货人姓名', None),  # These would be set after decryption
                '收货地址': getattr(self, '收货地址', None),
                '联系电话': getattr(self, '联系电话', None),
                '联系手机': getattr(self, '联系手机', None),
            })

        return result

    @property
    def has_virtual_number(self):
        """判断是否使用虚拟号"""
        return bool(self.虚拟号过期时间 and '默认有效期' in self.虚拟号过期时间)

    @property
    def is_presale(self):
        """判断是否为预售订单"""
        return self.预售订单 == '是'

    def set_decrypted_fields(self, name: str, address: str, phone: str, landline: Optional[str] = None):
        """
        Set decrypted fields as temporary attributes (not saved to DB)
        Used for displaying decrypted data without modifying encrypted storage
        """
        self.收货人姓名 = name
        self.收货地址 = address
        self.联系手机 = phone
        self.联系电话 = landline