from __future__ import annotations

from datetime import datetime

from sqlalchemy import or_
from sqlalchemy.orm import Session

from ..database.orm import OperationLogORM


class OperationLogRepository:
    """操作日志仓库：只负责 operation_logs 表的写入和查询。"""

    def __init__(self, session: Session):
        self.session = session

    def create_log(
        self,
        *,
        user_id: int | None,
        username: str,
        role: str,
        module: str,
        action: str,
        target_type: str,
        target_id: str,
        status: str,
        detail: str,
        ip_address: str,
        user_agent: str,
    ) -> OperationLogORM:
        log = OperationLogORM(
            user_id=user_id,
            username=username,
            role=role,
            module=module,
            action=action,
            target_type=target_type,
            target_id=target_id,
            status=status,
            detail=detail,
            ip_address=ip_address,
            user_agent=user_agent,
        )
        self.session.add(log)
        self.session.commit()
        self.session.refresh(log)
        return log

    def list_logs(
        self,
        *,
        page: int,
        page_size: int,
        username: str | None = None,
        module: str | None = None,
        action: str | None = None,
        status: str | None = None,
        keyword: str | None = None,
        start_time: datetime | None = None,
        end_time: datetime | None = None,
    ) -> tuple[list[OperationLogORM], int]:
        query = self.session.query(OperationLogORM)

        if username:
            query = query.filter(OperationLogORM.username.like(f"%{username}%"))
        if module:
            query = query.filter(OperationLogORM.module == module)
        if action:
            query = query.filter(OperationLogORM.action == action)
        if status:
            query = query.filter(OperationLogORM.status == status)
        if start_time:
            query = query.filter(OperationLogORM.created_at >= start_time)
        if end_time:
            query = query.filter(OperationLogORM.created_at <= end_time)
        if keyword:
            like_keyword = f"%{keyword}%"
            query = query.filter(
                or_(
                    OperationLogORM.username.like(like_keyword),
                    OperationLogORM.module.like(like_keyword),
                    OperationLogORM.action.like(like_keyword),
                    OperationLogORM.target_type.like(like_keyword),
                    OperationLogORM.target_id.like(like_keyword),
                    OperationLogORM.detail.like(like_keyword),
                )
            )

        total = query.count()
        items = (
            query.order_by(OperationLogORM.created_at.desc(), OperationLogORM.id.desc())
            .offset((page - 1) * page_size)
            .limit(page_size)
            .all()
        )
        return items, total

    def rollback(self) -> None:
        self.session.rollback()
