"""
设备类型CRUD操作
"""
from typing import List, Optional, Tuple
from sqlalchemy import select, and_, or_, func
from sqlalchemy.orm import Session
from app.models.device_type import DeviceType, DeviceTypeField
from app.schemas.device_type import DeviceTypeCreate, DeviceTypeUpdate, DeviceTypeFieldCreate, DeviceTypeFieldUpdate


class DeviceTypeCRUD:
    """设备类型CRUD操作类"""

    def get(self, db: Session, id: int) -> Optional[DeviceType]:
        """
        根据ID获取设备类型

        Args:
            db: 数据库会话
            id: 设备类型ID

        Returns:
            DeviceType对象或None
        """
        return db.query(DeviceType).filter(
            and_(
                DeviceType.id == id,
                DeviceType.deleted_at.is_(None)
            )
        ).first()

    def get_by_code(self, db: Session, code: str) -> Optional[DeviceType]:
        """
        根据代码获取设备类型

        Args:
            db: 数据库会话
            code: 设备类型代码

        Returns:
            DeviceType对象或None
        """
        return db.query(DeviceType).filter(
            and_(
                DeviceType.type_code == code,
                DeviceType.deleted_at.is_(None)
            )
        ).first()

    def get_multi(
        self,
        db: Session,
        skip: int = 0,
        limit: int = 20,
        category: Optional[str] = None,
        status: Optional[str] = None,
        keyword: Optional[str] = None
    ) -> Tuple[List[DeviceType], int]:
        """
        获取设备类型列表

        Args:
            db: 数据库会话
            skip: 跳过条数
            limit: 返回条数
            category: 设备分类筛选
            status: 状态筛选
            keyword: 搜索关键词

        Returns:
            (设备类型列表, 总数)
        """
        query = db.query(DeviceType).filter(DeviceType.deleted_at.is_(None))

        # 筛选条件
        if category:
            query = query.filter(DeviceType.category == category)
        if status:
            query = query.filter(DeviceType.status == status)
        if keyword:
            query = query.filter(
                or_(
                    DeviceType.type_code.ilike(f"%{keyword}%"),
                    DeviceType.type_name.ilike(f"%{keyword}%")
                )
            )

        # 排序
        query = query.order_by(DeviceType.sort_order.asc(), DeviceType.id.desc())

        # 总数
        total = query.count()

        # 分页
        items = query.offset(skip).limit(limit).all()

        return items, total

    def create(self, db: Session, obj_in: DeviceTypeCreate, creator_id: Optional[int] = None) -> DeviceType:
        """
        创建设备类型

        Args:
            db: 数据库会话
            obj_in: 创建数据
            creator_id: 创建人ID

        Returns:
            创建的DeviceType对象
        """
        # 检查代码是否已存在
        if self.get_by_code(db, obj_in.type_code):
            raise ValueError(f"设备类型代码 '{obj_in.type_code}' 已存在")

        db_obj = DeviceType(**obj_in.model_dump(), created_by=creator_id)
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def update(
        self,
        db: Session,
        db_obj: DeviceType,
        obj_in: DeviceTypeUpdate,
        updater_id: Optional[int] = None
    ) -> DeviceType:
        """
        更新设备类型

        Args:
            db: 数据库会话
            db_obj: 数据库对象
            obj_in: 更新数据
            updater_id: 更新人ID

        Returns:
            更新后的DeviceType对象
        """
        obj_data = obj_in.model_dump(exclude_unset=True)
        for field, value in obj_data.items():
            setattr(db_obj, field, value)

        db_obj.updated_by = updater_id
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def delete(self, db: Session, id: int, deleter_id: Optional[int] = None) -> bool:
        """
        删除设备类型（软删除）

        Args:
            db: 数据库会话
            id: 设备类型ID
            deleter_id: 删除人ID

        Returns:
            是否删除成功
        """
        obj = self.get(db, id)
        if not obj:
            return False

        obj.deleted_at = func.now()
        obj.deleted_by = deleter_id
        db.add(obj)
        db.commit()
        return True

    def get_all_categories(self, db: Session) -> List[str]:
        """
        获取所有设备分类

        Args:
            db: 数据库会话

        Returns:
            设备分类列表
        """
        result = db.query(DeviceType.category).filter(
            and_(
                DeviceType.deleted_at.is_(None),
                DeviceType.category.isnot(None)
            )
        ).distinct().all()
        return [r[0] for r in result if r[0]]


class DeviceTypeFieldCRUD:
    """设备类型字段CRUD操作类"""

    def get(self, db: Session, id: int) -> Optional[DeviceTypeField]:
        """
        根据ID获取字段

        Args:
            db: 数据库会话
            id: 字段ID

        Returns:
            DeviceTypeField对象或None
        """
        return db.query(DeviceTypeField).filter(
            and_(
                DeviceTypeField.id == id,
                DeviceTypeField.deleted_at.is_(None)
            )
        ).first()

    def get_by_device_type(
        self,
        db: Session,
        device_type_id: int,
        status: Optional[str] = None
    ) -> List[DeviceTypeField]:
        """
        获取设备类型的所有字段

        Args:
            db: 数据库会话
            device_type_id: 设备类型ID
            status: 状态筛选

        Returns:
            字段列表
        """
        query = db.query(DeviceTypeField).filter(
            and_(
                DeviceTypeField.device_type_id == device_type_id,
                DeviceTypeField.deleted_at.is_(None)
            )
        )

        if status:
            query = query.filter(DeviceTypeField.status == status)

        return query.order_by(DeviceTypeField.sort_order.asc(), DeviceTypeField.id.asc()).all()

    def create(
        self,
        db: Session,
        obj_in: DeviceTypeFieldCreate,
        device_type_id: int,
        creator_id: Optional[int] = None
    ) -> DeviceTypeField:
        """
        创建字段

        Args:
            db: 数据库会话
            obj_in: 创建数据
            device_type_id: 设备类型ID
            creator_id: 创建人ID

        Returns:
            创建的DeviceTypeField对象
        """
        # 检查字段代码是否已存在
        existing = db.query(DeviceTypeField).filter(
            and_(
                DeviceTypeField.device_type_id == device_type_id,
                DeviceTypeField.field_code == obj_in.field_code,
                DeviceTypeField.deleted_at.is_(None)
            )
        ).first()

        if existing:
            raise ValueError(f"字段代码 '{obj_in.field_code}' 已存在")

        db_obj = DeviceTypeField(
            **obj_in.model_dump(),
            device_type_id=device_type_id,
            created_by=creator_id
        )
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def update(
        self,
        db: Session,
        db_obj: DeviceTypeField,
        obj_in: DeviceTypeFieldUpdate,
        updater_id: Optional[int] = None
    ) -> DeviceTypeField:
        """
        更新字段

        Args:
            db: 数据库会话
            db_obj: 数据库对象
            obj_in: 更新数据
            updater_id: 更新人ID

        Returns:
            更新后的DeviceTypeField对象
        """
        obj_data = obj_in.model_dump(exclude_unset=True)
        for field, value in obj_data.items():
            setattr(db_obj, field, value)

        db_obj.updated_by = updater_id
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def delete(self, db: Session, id: int, deleter_id: Optional[int] = None) -> bool:
        """
        删除字段（软删除）

        Args:
            db: 数据库会话
            id: 字段ID
            deleter_id: 删除人ID

        Returns:
            是否删除成功
        """
        obj = self.get(db, id)
        if not obj:
            return False

        obj.deleted_at = func.now()
        obj.deleted_by = deleter_id
        db.add(obj)
        db.commit()
        return True

    def batch_create(
        self,
        db: Session,
        fields_in: List[DeviceTypeFieldCreate],
        device_type_id: int,
        creator_id: Optional[int] = None
    ) -> List[DeviceTypeField]:
        """
        批量创建字段

        Args:
            db: 数据库会话
            fields_in: 字段创建列表
            device_type_id: 设备类型ID
            creator_id: 创建人ID

        Returns:
            创建的字段列表
        """
        db_objs = [
            DeviceTypeField(
                **field.model_dump(),
                device_type_id=device_type_id,
                created_by=creator_id
            )
            for field in fields_in
        ]
        db.add_all(db_objs)
        db.commit()
        for obj in db_objs:
            db.refresh(obj)
        return db_objs


# 创建全局实例
device_type = DeviceTypeCRUD()
device_type_field = DeviceTypeFieldCRUD()
