"""
Config 模型

对应 configs 表，用于存储动态配置（系统配置和任务配置）
"""
from sqlalchemy import Column, String, Text, Integer, TIMESTAMP, func, Index
from sqlalchemy.dialects.postgresql import JSONB
from typing import Optional, Dict, Any

from ..base import Base


class Config(Base):
    """
    动态配置表

    统一存储系统配置和任务配置：
    - system 类型：全局系统配置（如 DDSketch 精度、日志级别）
    - task 类型：任务级配置（如 rate_limit、max_retries）
    """
    __tablename__ = 'configs'

    id = Column(Integer, primary_key=True, autoincrement=True, comment='自增主键')

    config_type = Column(
        String(20),
        nullable=False,
        comment='配置类型：system（系统配置）| task（任务配置）'
    )

    scope = Column(
        String(500),
        nullable=True,
        comment='作用域，task 类型格式为 namespace:queue:task_name'
    )

    key = Column(
        String(100),
        nullable=False,
        comment='配置键名'
    )

    value = Column(
        JSONB,
        nullable=False,
        comment='配置值（JSONB 格式）'
    )

    description = Column(
        Text,
        nullable=True,
        comment='配置描述'
    )

    created_at = Column(
        TIMESTAMP(timezone=True),
        nullable=False,
        server_default=func.current_timestamp(),
        comment='创建时间'
    )
    updated_at = Column(
        TIMESTAMP(timezone=True),
        nullable=False,
        server_default=func.current_timestamp(),
        onupdate=func.current_timestamp(),
        comment='更新时间'
    )

    __table_args__ = (
        Index(
            'uq_configs_type_scope_key',
            'config_type', 'scope', 'key',
            unique=True
        ),
        Index('idx_configs_type', 'config_type'),
        Index('idx_configs_scope', 'scope'),
        Index('idx_configs_updated_at', 'updated_at'),
    )

    def to_dict(self) -> Dict[str, Any]:
        return {
            'id': self.id,
            'config_type': self.config_type,
            'scope': self.scope,
            'key': self.key,
            'value': self.value,
            'description': self.description,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
        }

    @classmethod
    def make_task_scope(cls, namespace: str, queue: str, task_name: str) -> str:
        return f"{namespace}:{queue}:{task_name}"

    @classmethod
    def parse_task_scope(cls, scope: str) -> Optional[Dict[str, str]]:
        if not scope:
            return None
        parts = scope.split(':', 2)
        if len(parts) != 3:
            return None
        return {
            'namespace': parts[0],
            'queue': parts[1],
            'task_name': parts[2],
        }

    def __repr__(self) -> str:
        return (
            f"<Config(id={self.id}, type='{self.config_type}', "
            f"scope='{self.scope}', key='{self.key}')>"
        )
