"""
Realtime Module - Interface Layer Views

This module provides API endpoints for the realtime price monitoring system.
Following AgomSaaS architecture rules:
- Interface layer handles input validation and output formatting
- No business logic, delegates to Application layer
"""

import logging
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import TimeoutError as FutureTimeoutError

from django.http import JsonResponse
from django.views import View

from apps.realtime.application.price_polling_service import PricePollingUseCase

logger = logging.getLogger(__name__)


class MarketSummaryView(View):
    """兼容 SDK/MCP 的市场概况接口。"""

    INDEX_CODES = {
        "sh_index": "000001.SH",
        "sz_index": "399001.SZ",
        "cyb_index": "399006.SZ",
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.use_case = PricePollingUseCase()

    def get(self, request, *args, **kwargs):
        """GET /api/realtime/market-summary/"""
        prices = self.use_case.get_latest_prices(list(self.INDEX_CODES.values()))
        prices_by_code = {item["asset_code"]: item for item in prices}
        index_payload = {}
        latest_timestamp = None
        total_volume = 0
        available_count = 0

        for field_name, asset_code in self.INDEX_CODES.items():
            price = prices_by_code.get(asset_code)
            if price is None:
                index_payload[field_name] = None
                continue

            index_payload[field_name] = float(price["price"])
            index_payload[f"{field_name}_change"] = price.get("change")
            index_payload[f"{field_name}_change_pct"] = price.get("change_pct")
            timestamp = price.get("timestamp")
            if timestamp:
                latest_timestamp = timestamp if latest_timestamp is None else max(
                    latest_timestamp,
                    timestamp,
                )
            total_volume += price.get("volume") or 0
            available_count += 1

        payload = {
            "success": available_count > 0,
            "stats_available": False,
            "message": (
                "Major index snapshot is available; breadth statistics are unavailable in the current realtime data providers."
                if available_count
                else "No realtime index snapshot is available from cache or configured providers."
            ),
            "timestamp": latest_timestamp,
            "up_count": 0,
            "down_count": 0,
            "flat_count": 0,
            "limit_up_count": 0,
            "limit_down_count": 0,
            "total_volume": total_volume,
            "total_value": 0,
        }
        payload.update(index_payload)
        return JsonResponse(payload, status=200 if available_count else 503)


class RealtimePriceView(View):
    """实时价格 API 视图"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.use_case = PricePollingUseCase()

    def get(self, request, *args, **kwargs):
        """GET /api/realtime/prices/

        查询参数:
            - assets: 资产代码列表，逗号分隔（可选）
                    如果不提供，则返回所有监控资产的价格

        Returns:
            {
                "timestamp": "2024-01-13T10:30:00",
                "prices": [
                    {
                        "asset_code": "ASSET_CODE",
                        "price": 10.50,
                        "change": 0.10,
                        "change_pct": 0.96,
                        ...
                    }
                ],
                "total": 10,
                "success": 10,
                "failed": 0
            }
        """
        asset_codes_str = request.GET.get("assets")

        # Note: Realtime prices have very short cache TTL (30s) to reduce load
        # while still providing near-realtime data
        if asset_codes_str:
            # 获取指定资产的价格
            asset_codes = [code.strip() for code in asset_codes_str.split(",") if code.strip()]
            prices = self.use_case.get_latest_prices(asset_codes)

            return JsonResponse({
                "success_flag": True,
                "timestamp": prices[0].get("timestamp") if prices else None,
                "prices": prices,
                "total": len(asset_codes),
                "success": len(prices),
                "failed": len(asset_codes) - len(prices)
            })
        else:
            # 触发价格轮询
            snapshot = self.use_case.execute_price_polling()
            snapshot.setdefault("success_flag", True)
            return JsonResponse(snapshot)

    def post(self, request, *args, **kwargs):
        """POST /api/realtime/prices/

        手动触发价格轮询

        Returns:
            价格快照
        """
        snapshot = self.use_case.execute_price_polling()
        snapshot.setdefault("success_flag", True)
        return JsonResponse(snapshot)


class SingleAssetPriceView(View):
    """单个资产价格 API 视图"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.use_case = PricePollingUseCase()

    def get(self, request, asset_code, *args, **kwargs):
        """GET /api/realtime/prices/{asset_code}/

        获取单个资产的最新价格

        Args:
            asset_code: 资产代码

        Returns:
            {
                "asset_code": "ASSET_CODE",
                "price": 10.50,
                "change": 0.10,
                "change_pct": 0.96,
                ...
            }
        """
        prices = self.use_case.get_latest_prices([asset_code])

        if not prices:
            return JsonResponse({
                "success": False,
                "error": f"Price not found for asset: {asset_code}"
            }, status=404)

        payload = {"success": True}
        payload.update(prices[0])
        return JsonResponse(payload)


class PricePollingTriggerView(View):
    """价格轮询触发视图

    用于手动触发价格更新或定时任务调用
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.use_case = PricePollingUseCase()

    def post(self, request, *args, **kwargs):
        """POST /api/realtime/poll/

        触发价格轮询

        Returns:
            价格快照
        """
        logger.info("Manual price polling triggered")
        snapshot = self.use_case.execute_price_polling()
        snapshot.setdefault("success_flag", True)
        return JsonResponse(snapshot)


class HealthCheckView(View):
    """健康检查视图

    检查实时价格服务是否正常
    """

    def get(self, request, *args, **kwargs):
        """GET /api/realtime/health/

        Returns:
            {
                "status": "healthy",
                "data_provider_available": true,
                "last_poll_time": "2024-01-13T10:30:00"
            }
        """
        use_case = PricePollingUseCase()
        check_provider_availability = getattr(type(use_case), "check_provider_availability", None)
        if callable(check_provider_availability):
            is_available, health_error = use_case.check_provider_availability(timeout_seconds=2.0)
        else:
            is_available = False
            health_error = None
            executor = ThreadPoolExecutor(max_workers=1)
            try:
                future = executor.submit(use_case.price_provider.is_available)
                is_available = future.result(timeout=2.0)
            except FutureTimeoutError:
                health_error = "provider_check_timeout"
                logger.warning("Realtime health provider check timed out")
            except Exception as exc:
                health_error = str(exc)
                logger.warning("Realtime health provider check failed: %s", exc)
            finally:
                executor.shutdown(wait=False, cancel_futures=True)

        return JsonResponse({
            "success": True,
            "status": "healthy" if is_available else "unhealthy",
            "data_provider_available": is_available,
            "timestamp": use_case.service.config.to_dict(),
            "error": health_error,
        })
