"""
智联招聘 Service — 基于新算法文件的封装
保持对外公开接口不变（cleaning.py / company_cleaner.py 依赖）
"""

from __future__ import annotations

from typing import Any, Dict, List, Optional

from loguru import logger

from app.services.crawler._zhilian_api import (
    GetCompanyDetail,
    GetPositionDetail,
    SearchCompanyPositions,
    SearchPositions,
)
from app.services.crawler._zhilian_client import (
    ZhilianClient,
    create_capi_client,
    create_cgate_client,
)
from app.services.crawler._zhilian_sign import ZhilianSign


class ZhilianService:
    def __init__(self, proxy_url: Optional[str] = None):
        self._signer = ZhilianSign()
        self._cgate = create_cgate_client(signer=self._signer, proxy=proxy_url or None)
        self._capi = create_capi_client(signer=self._signer, proxy=proxy_url or None)

    def set_proxy(self, proxy_url: Optional[str]) -> None:
        proxy = proxy_url.strip().strip("`") if proxy_url else None
        self._cgate = create_cgate_client(signer=self._signer, proxy=proxy)
        self._capi = create_capi_client(signer=self._signer, proxy=proxy)
        logger.info(f"ZhilianService proxy set to: {proxy or 'direct'}")

    def get_job_detail(self, job_number: str) -> Optional[Dict[str, Any]]:
        """获取职位详情"""
        logger.info(f"Zhilian get_job_detail: {job_number}")
        try:
            fetcher = GetPositionDetail(number=job_number, client=self._cgate)
            result = fetcher.fetch()
            if result.success:
                return result.data
            logger.warning(f"Zhilian get_job_detail failed: {result.error}")
            return None
        except Exception as e:
            logger.error(f"Zhilian get_job_detail exception: {e}")
            return None

    def get_company_detail(self, company_number: str) -> Optional[Dict[str, Any]]:
        """获取公司详情"""
        logger.info(f"Zhilian get_company_detail: {company_number}")
        try:
            fetcher = GetCompanyDetail(number=company_number, client=self._cgate)
            result = fetcher.fetch()
            if result.success:
                return result.data
            logger.warning(f"Zhilian get_company_detail failed: {result.error}")
            return None
        except Exception as e:
            logger.error(f"Zhilian get_company_detail exception: {e}")
            return None

    def get_company_jobs_by_id(
        self,
        company_number: str,
        page_index: int = 1,
        page_size: int = 30,
        work_city: Optional[int] = None,
    ) -> Optional[Dict[str, Any]]:
        """获取公司职位列表"""
        logger.info(f"Zhilian get_company_jobs: company={company_number}, page={page_index}")
        try:
            searcher = SearchCompanyPositions(
                company_id=company_number,
                city_code=str(work_city) if work_city is not None else "",
                page_size=page_size,
                client=self._capi,
            )
            result = searcher.search(page_index=page_index)
            if result.success:
                return result.data
            logger.warning(f"Zhilian get_company_jobs failed: {result.error}")
            return None
        except Exception as e:
            logger.error(f"Zhilian get_company_jobs exception: {e}")
            return None

    def search_company_jobs_by_name(
        self,
        company_name: str,
        city_id: Optional[int] = None,
        page_size: int = 15,
        page_index: int = 1,
    ) -> Optional[Dict[str, Any]]:
        """按公司名搜索职位"""
        logger.info(f"Zhilian search_company_jobs_by_name: {company_name}")
        try:
            searcher = SearchPositions(
                keyword=company_name,
                city_code=city_id if city_id is not None else "",
                page_size=page_size,
                client=self._cgate,
            )
            result = searcher.search(page_index=page_index)
            if result.success:
                return result.data
            logger.warning(f"Zhilian search_company_jobs failed: {result.error}")
            return None
        except Exception as e:
            logger.error(f"Zhilian search_company_jobs exception: {e}")
            return None

    def search_jobs(
        self,
        city_id: int = 801,
        page_size: int = 15,
        page_index: int = 1,
        job_level3_code: Optional[str] = None,
    ) -> List[Dict[str, Any]]:
        """搜索职位（返回列表）"""
        logger.info(f"Zhilian search_jobs: city={city_id}, page={page_index}")
        try:
            filters = {}
            if job_level3_code:
                filters["S_SOU_POSITION_TYPE"] = job_level3_code
            searcher = SearchPositions(
                city_code=city_id,
                filters=filters,
                page_size=page_size,
                client=self._cgate,
            )
            result = searcher.search(page_index=page_index)
            if result.success:
                return result.list or []
            logger.warning(f"Zhilian search_jobs failed: {result.error}")
            return []
        except Exception as e:
            logger.error(f"Zhilian search_jobs exception: {e}")
            return []

    # ── asyncio.to_thread 桥接（ARCH-06）────────────────────────

    async def async_get_job_detail(self, job_number: str) -> Optional[Dict]:
        import asyncio
        return await asyncio.to_thread(self.get_job_detail, job_number)

    async def async_get_company_detail(self, company_number: str) -> Optional[Dict]:
        import asyncio
        return await asyncio.to_thread(self.get_company_detail, company_number)

    async def async_get_company_jobs(
        self, company_number: str, page_index: int = 1, page_size: int = 30,
        work_city: Optional[int] = None,
    ) -> Optional[Dict]:
        import asyncio
        return await asyncio.to_thread(
            self.get_company_jobs_by_id, company_number, page_index, page_size, work_city
        )

    async def async_search_jobs(
        self, city_id: int = 801, page_size: int = 15, page_index: int = 1,
        job_level3_code: Optional[str] = None,
    ) -> List:
        import asyncio
        return await asyncio.to_thread(
            self.search_jobs, city_id, page_size, page_index, job_level3_code
        )

