from dataclasses import dataclass
from math import ceil
from typing import Any, Callable

from nonebot_plugin_alconna import UniMessage


@dataclass
class PagerQuery:
    page_index: int
    page_size: int

    def apply[T](self, ls: list[T]) -> "PagerResult[T]":
        if self.page_size <= 0:
            return PagerResult(
                success=False,
                message="每页元素数量应该大于 0",
                data=[],
                page_count=-1,
                query=self,
            )
        page_count = ceil(len(ls) / self.page_size)
        if self.page_index <= 0 or self.page_size <= 0:
            return PagerResult(
                success=False,
                message="页数必须大于 0",
                data=[],
                page_count=page_count,
                query=self,
            )
        data = ls[(self.page_index - 1) * self.page_size: self.page_index * self.page_size]
        if len(data) > 0:
            return PagerResult(
                success=True,
                message="",
                data=data,
                page_count=page_count,
                query=self,
            )
        return PagerResult(
            success=False,
            message="指定的页数超过最大页数",
            data=data,
            page_count=page_count,
            query=self,
        )


@dataclass
class PagerResult[T]:
    data: list[T]
    success: bool
    message: str
    page_count: int
    query: PagerQuery

    def to_unimessage(
        self,
        formatter: Callable[[T], str | UniMessage[Any]] = str,
        title: str = '查询结果',
        list_indicator: str = '- ',
    ) -> UniMessage[Any]:
        msg = UniMessage.text(f'===== {title} =====\n\n')

        if not self.success:
            msg = msg.text(f'⚠️ {self.message}\n')
        else:
            for obj in self.data:
                msg = msg.text(list_indicator)
                msg += formatter(obj)
                msg += '\n'

        msg = msg.text(f'\n===== 第 {self.query.page_index} 页，共 {self.page_count} 页 =====')
        return msg


