"""Fracciones Service"""

import asyncio
from typing import Optional, List, Tuple
from ..common import SitarAPIBaseService
from .schemas import FraccionesResponse


class FraccionesService(SitarAPIBaseService):
    """Service for Fracciones operations"""

    _instance: Optional["FraccionesService"] = None

    @classmethod
    def get_instance(cls) -> "FraccionesService":
        """Get singleton instance"""
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    async def search_with_total(
        self,
        fraccion: Optional[str] = None,
        nico: Optional[str] = None,
        description: Optional[str] = None,
        nivel: Optional[int] = None,
        skip: int = 0,
        limit: int = 100,
    ) -> Tuple[List[FraccionesResponse], int]:
        """Search Mexican tariff fractions; total matches SITAR PaginatedFraccionesResponse.total."""
        params = {"skip": skip, "limit": min(limit, 1000)}
        if fraccion:
            params["fraccion"] = fraccion
        if nico:
            params["nico"] = nico
        if description:
            params["descripcion"] = description
        if nivel is not None:
            params["nivel"] = nivel

        raw = await self._make_request("GET", "/api/v1/fracciones/", params=params)
        rows, total = self._parse_paginated_list_and_total(raw)
        return [FraccionesResponse(**item) for item in rows], total

    async def search(
        self,
        fraccion: Optional[str] = None,
        nico: Optional[str] = None,
        description: Optional[str] = None,
        nivel: Optional[int] = None,
        skip: int = 0,
        limit: int = 100,
    ) -> List[FraccionesResponse]:
        """Search Mexican tariff fractions"""
        items, _ = await self.search_with_total(
            fraccion=fraccion,
            nico=nico,
            description=description,
            nivel=nivel,
            skip=skip,
            limit=limit,
        )
        return items

    async def get_by_id(self, sysid: int) -> FraccionesResponse:
        """Get single Fraccion record by SYSID"""
        data = await self._make_request("GET", f"/api/v1/fracciones/{sysid}")
        return FraccionesResponse(**data)

    @classmethod
    def search_sync(
        cls,
        fraccion: Optional[str] = None,
        nico: Optional[str] = None,
        description: Optional[str] = None,
        nivel: Optional[int] = None,
        skip: int = 0,
        limit: int = 100,
    ) -> List[FraccionesResponse]:
        """Search Mexican tariff fractions (sync wrapper for use in Celery/sync context)."""
        service = cls.get_instance()
        return asyncio.run(
            service.search(
                fraccion=fraccion,
                nico=nico,
                description=description,
                nivel=nivel,
                skip=skip,
                limit=limit,
            )
        )
