# vorto_utils/dumbpanel.py - DumbPanel env variable client
import requests


class DumbPanelClient:
    """DumbPanel environment variable client.

    Usage:
        dp = DumbPanelClient("S_NKF")
        dp = DumbPanelClient("S_NKF", "http://host:port丨app_key丨app_secret")

        dp.update_env("13800138000", "phone#token#unifyId", "牛卡福:13800138000|到期:2026-12-31")
        dp.delete_env("13800138000")

    IMPORTANT: remark must contain the raw username (NOT masked) for update/delete matching.
    """

    def __init__(self, os_var_name, dp_config_str=None):
        """
        Args:
            os_var_name: DumbPanel env variable name, e.g. "S_NKF"
            dp_config_str: Config string "host丨app_key丨app_secret".
                          Falls back to middleware bucket if not provided.
        """
        if dp_config_str is None:
            try:
                import middleware
                dp_config_str = middleware.bucketGet('s_vorto', 'dpname') or ''
            except ImportError:
                dp_config_str = ''

        self.os_var_name = os_var_name
        self.host = ''
        self.app_key = ''
        self.app_secret = ''

        if dp_config_str:
            configs = dp_config_str.replace('|', '丨').split('丨')
            if len(configs) >= 3:
                self.host = configs[0].strip().rstrip('/')
                self.app_key = configs[1].strip()
                self.app_secret = configs[2].strip()

    def is_configured(self):
        """Check if DumbPanel is properly configured"""
        return bool(self.host and self.app_key and self.app_secret)

    def get_token(self):
        """Get DumbPanel access token.

        Returns:
            str: Access token, None on failure.
        """
        if not self.is_configured():
            return None
        try:
            url = f'{self.host}/api/open-api/token'
            resp = requests.post(
                url,
                json={'app_key': self.app_key, 'app_secret': self.app_secret},
                timeout=10
            ).json()
            # Handle various response formats:
            #   {"data": {"access_token": "xxx"}}  (actual DumbPanel format)
            #   {"data": {"token": "xxx"}}
            #   {"data": "token_string"}
            #   {"token": "xxx"}
            data = resp.get('data')
            if isinstance(data, dict):
                return data.get('access_token') or data.get('token')
            if isinstance(data, str) and data:
                return data
            return resp.get('access_token') or resp.get('token')
        except Exception:
            return None

    def _parse_env_list(self, resp_json):
        """Parse env list from various response structures.

        Handles:
            {"data": [...]},
            {"data": {"list": [...], "total": N}},
            {"data": {"data": [...], "total": N}}
        """
        data = resp_json.get('data')
        if isinstance(data, list):
            return data
        if isinstance(data, dict):
            return data.get('list', []) or data.get('data', [])
        return []

    def update_env(self, username, env_value, remark=''):
        """Update or create a DumbPanel environment variable.

        Args:
            username: User identifier (matched in remarks).
            env_value: Environment variable value.
            remark: Environment variable remark (must contain raw username for matching).

        Returns:
            bool: Whether the operation succeeded.
        """
        if not self.is_configured():
            return False

        try:
            token = self.get_token()
            if not token:
                return False

            headers = {'Authorization': f'Bearer {token}'}

            # Search by username to find envs whose remarks contain it
            search_resp = requests.get(
                f'{self.host}/api/envs',
                params={'keyword': username, 'page': 1, 'page_size': 100},
                headers=headers,
                timeout=10
            ).json()

            envs = self._parse_env_list(search_resp)
            env_id = next(
                (e.get('id') for e in envs
                 if e.get('name') == self.os_var_name and username in e.get('remarks', '')),
                None
            )

            env_data = {
                'name': self.os_var_name,
                'value': env_value,
                'remarks': remark
            }

            if env_id:
                # Update existing env
                requests.put(
                    f'{self.host}/api/envs/{env_id}',
                    headers=headers,
                    json=env_data,
                    timeout=10
                )
            else:
                # Create new env (DumbPanel accepts single object, not array)
                requests.post(
                    f'{self.host}/api/envs',
                    headers=headers,
                    json=env_data,
                    timeout=10
                )
            return True
        except Exception:
            return False

    def delete_env(self, username):
        """Delete a DumbPanel environment variable.

        Args:
            username: User identifier (matched in remarks).

        Returns:
            bool: Whether the operation succeeded.
        """
        if not self.is_configured():
            return False

        try:
            token = self.get_token()
            if not token:
                return False

            headers = {'Authorization': f'Bearer {token}'}

            # Search by username keyword
            search_resp = requests.get(
                f'{self.host}/api/envs',
                params={'keyword': username, 'page': 1, 'page_size': 100},
                headers=headers,
                timeout=10
            ).json()

            envs = self._parse_env_list(search_resp)
            for env in envs:
                if env.get('name') == self.os_var_name and username in env.get('remarks', ''):
                    env_id = env.get('id')
                    # DumbPanel deletes by URL path, not request body
                    requests.delete(
                        f'{self.host}/api/envs/{env_id}',
                        headers=headers,
                        timeout=10
                    )
                    return True
            return False
        except Exception:
            return False
