#!/usr/bin/env python3
"""
公牛充电桩 API 封装

API 文档：
- 获取充电桩列表：POST /mini/base-server/stationApp/pageAppQueryConnectorByStationId
- 状态码映射：0=离线, 1=空闲, 2=占用, 3=充电中
"""

import os
import logging
import requests
from typing import Dict, List, Optional
from datetime import datetime

logger = logging.getLogger('charger.gongniu')


class GongniuAPI:
    """公牛充电桩 API 封装"""

    API_URL = "https://evse.gongniu.cn/mini/base-server/stationApp/pageAppQueryConnectorByStationId"

    # 状态码映射：公牛 -> 统一格式
    WORK_STATUS_MAP = {
        0: "offline",   # 离线
        1: "free",      # 空闲
        2: "occupied",  # 占用（未充电）
        3: "charging",  # 充电中
    }

    # 充电桩类型映射：公牛 -> 统一格式
    CONNECTOR_TYPE_MAP = {
        1: "DC",   # 直流
        2: "AC",   # 交流
    }

    def __init__(self, station_id: str = None):
        """
        初始化公牛 API

        Args:
            station_id: 充电站 ID，默认从环境变量读取
        """
        self.station_id = station_id or os.environ.get("GONGNIU_STATION_ID", "2046592030206775298")

    def parse_work_status(self, work_status: int) -> str:
        """
        解析工作状态码

        Args:
            work_status: 公牛状态码

        Returns:
            统一状态类型: free/charging/occupied/offline/unknown
        """
        return self.WORK_STATUS_MAP.get(work_status, "unknown")

    def parse_connector_type(self, type_code: int) -> str:
        """
        解析充电桩类型

        Args:
            type_code: 公牛类型码 (1=直流, 2=交流)

        Returns:
            统一类型: DC/AC
        """
        return self.CONNECTOR_TYPE_MAP.get(type_code, "AC")

    def normalize_connector(self, raw_data: dict) -> dict:
        """
        标准化充电桩数据

        将公牛 API 返回的数据转换为统一格式

        Args:
            raw_data: 公牛 API 返回的单个充电桩数据

        Returns:
            标准化后的充电桩数据
        """
        work_status = raw_data.get("workStatus", 0)
        state_type = self.parse_work_status(work_status)

        connector = {
            "connector_id": raw_data.get("connectorCode", ""),
            "connector_name": raw_data.get("connectorName", ""),
            "type": self.parse_connector_type(raw_data.get("type", 2)),
            "power": float(raw_data.get("power", 0)),
            "state": {
                "type": state_type,
                "desc": raw_data.get("workStatusName", ""),
            },
            "vendor": "gongniu",
            "raw_id": raw_data.get("id", ""),  # 保留原始 ID
            "station_id": raw_data.get("stationId", ""),
            "station_name": raw_data.get("stationName", ""),
            # 公牛 API 不返回时长，初始化为 0，前端从缓存计算
            "idle_seconds": 0,
            "charging_seconds": 0,
            "occupied_seconds": 0,
        }

        # DC 充电桩特殊字段
        if connector["type"] == "DC":
            # 充电进度 (soc)
            soc = raw_data.get("soc", 0)
            if state_type == "charging" and soc > 0:
                connector["charging_progress"] = soc

        return connector

    def parse_connectors(self, response: dict, dc_only: bool = False) -> List[dict]:
        """
        解析 API 响应，返回充电桩列表

        Args:
            response: API 响应数据
            dc_only: 是否只返回 DC 桩

        Returns:
            标准化后的充电桩列表
        """
        if not response or response.get("resultCode") != "100":
            logger.error(f"公牛 API 返回异常: {response.get('msg', '未知错误')}")
            return []

        data = response.get("data", {})
        raw_list = data.get("dataList", [])

        connectors = []
        for raw in raw_list:
            connector = self.normalize_connector(raw)

            # 过滤：只取 DC 桩
            if dc_only and connector["type"] != "DC":
                continue

            connectors.append(connector)

        dc_count = sum(1 for c in connectors if c["type"] == "DC")
        ac_count = len(connectors) - dc_count
        logger.info(f"公牛 API 解析完成: {dc_count} 个 DC 充电桩, {ac_count} 个 AC 充电桩")
        return connectors

    def fetch_connectors(self, dc_only: bool = True, timeout: int = 10) -> dict:
        """
        获取充电桩数据

        Args:
            dc_only: 是否只获取 DC 桩
            timeout: 请求超时时间（秒）

        Returns:
            {
                "success": bool,
                "connectors": List[dict],  # 标准化后的充电桩列表
                "vendor": "gongniu",
                "error": str,  # 仅失败时
            }
        """
        try:
            payload = {
                "data": {"stationId": self.station_id},
                "businessTypes": [0],
                "pageNo": 1,
                "pageSize": 100  # 足够大
            }

            headers = {
                "Content-Type": "application/json",
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
                "Accept": "application/json",
            }

            response = requests.post(
                self.API_URL,
                json=payload,
                headers=headers,
                timeout=timeout
            )

            if response.status_code != 200:
                return {
                    "success": False,
                    "error": f"HTTP {response.status_code}",
                    "vendor": "gongniu"
                }

            data = response.json()
            connectors = self.parse_connectors(data, dc_only=dc_only)

            return {
                "success": True,
                "connectors": connectors,
                "vendor": "gongniu",
                "station_id": self.station_id,
                "fetch_time": datetime.now().isoformat(),
            }

        except requests.exceptions.Timeout:
            logger.error("公牛 API 请求超时")
            return {
                "success": False,
                "error": "请求超时",
                "vendor": "gongniu"
            }
        except Exception as e:
            logger.error(f"公牛 API 请求失败: {e}")
            return {
                "success": False,
                "error": str(e),
                "vendor": "gongniu"
            }


# ==================== 命令行测试 ====================

if __name__ == "__main__":
    import sys

    print("=" * 50)
    print("公牛充电桩 API 测试")
    print("=" * 50)

    api = GongniuAPI()
    print(f"\n充电站 ID: {api.station_id}")
    print("正在获取数据...\n")

    result = api.fetch_connectors(dc_only=True)

    if result["success"]:
        print(f"获取成功: {len(result['connectors'])} 个 DC 充电桩\n")
        for c in result["connectors"]:
            status = c["state"]["type"]
            progress = c.get("charging_progress", "-")
            print(f"  {c['connector_name']}: {status} (功率: {c['power']}kW, 进度: {progress}%)")
    else:
        print(f"获取失败: {result.get('error', '未知错误')}")
