"""Chart generation and access tools."""

from typing import Optional
from mcp.server.fastmcp import Context
from mcp.server.session import ServerSession
from point_topic_mcp.core.utils import check_env_vars


def register_chart_tools(mcp):
    """Register chart-related tools (public and authenticated)."""
    
    # Public chart tools (no credentials needed)
    @mcp.tool()
    def get_point_topic_public_chart_catalog(ctx: Optional[Context[ServerSession, None]] = None) -> str:
        """Get all available public charts from the Point Topic Charts API.
        
        Fetches the public chart catalog from https://charts.point-topic.com/public
        which includes chart metadata, available parameters, and example URLs for
        embedding visualizations.
        
        Returns:
            JSON string containing chart catalog with structure including project names,
            chart titles, tags, required parameters, and example URLs for HTML/PNG/CSV formats.
        """
        import requests
        import json
        response = requests.get("https://charts.point-topic.com/public")
        return json.dumps(response.json())
    
    @mcp.tool()
    def get_point_topic_public_chart_csv(url: str, ctx: Optional[Context[ServerSession, None]] = None) -> str:
        """Get a specific chart from Point Topic Charts API for context.
        
        When displaying charts to the user in an iframe, use this tool to see
        the chart contents and provide context. The user can only see charts if
        you embed them as iframes without the format parameter.
        
        Strategy: Embed the iframe first, then give some context about the chart
        with the info returned by this tool.
        
        Args:
            url: Chart URL WITHOUT the format parameter (e.g., no &format=png/csv).
        
        Returns: csv string
        """
        import urllib.parse
        import requests

        # strip any existing format param and add format=csv
        parsed = urllib.parse.urlparse(url)
        query = urllib.parse.parse_qs(parsed.query)
        query.pop('format', None)
        query['format'] = 'csv'
        csv_url = urllib.parse.urlunparse(parsed._replace(query=urllib.parse.urlencode(query, doseq=True)))

        resp = requests.get(csv_url)
        if resp.status_code != 200:
            return f"Error: {resp.status_code} {resp.text}"
        
        return resp.text
        
    # Authenticated chart tools (require API key)
    if check_env_vars('chart_tools', ['CHART_API_KEY']):
        @mcp.tool()
        def generate_authenticated_chart_url(
            project: str,
            chart_name: str,
            period: Optional[str] = None,
            la_code: Optional[str] = None,
            additional_params: Optional[dict] = None,
            ctx: Optional[Context[ServerSession, None]] = None
        ) -> str:
            """Generate signed URL for embedding private charts with iframe.
            
            Creates temporary token that expires after specified hours (default 24).
            Use this for charts that require authentication (non-public charts).
            
            For public charts, continue using get_point_topic_public_chart_catalog().
            
            Args:
                project: Chart project name (e.g., 'inca', 'ukplus')
                chart_name: Chart name (e.g., 'footprint_subs_openreach_altnet')
                period: Chart period parameter (e.g., '2024Q4') [optional]
                la_code: Local Authority code (e.g., 'E09000033') [optional]
                additional_params: Any other chart parameters as dict [optional]
            
            Returns:
                Iframe-ready URL with embedded token that expires in 24 hours.
                Embed like: <iframe src="RETURNED_URL" width="800" height="600"></iframe>
            
            Example:
                url = generate_authenticated_chart_url(
                    "inca",
                    "footprint_subs_openreach_altnet",
                    period="2024Q4",
                    la_code="E09000033"
                )
                # Returns: https://charts.point-topic.com/chart/inca/footprint_subs_openreach_altnet?period=2024Q4&la_code=E09000033&token=eyJhbGc...
            """
            import requests
            import json
            import os
            
            # Build params dict from individual parameters
            params = {}
            if period is not None:
                params['period'] = period
            if la_code is not None:
                params['la_code'] = la_code
            if additional_params:
                params.update(additional_params)
            
            # Get Chart API key from environment (we know it exists due to conditional registration)
            api_key = os.getenv("CHART_API_KEY")
            
            try:
                response = requests.post(
                    "https://charts.point-topic.com/token/generate",
                    headers={
                        "X-API-Key": api_key,
                        "Content-Type": "application/json"
                    },
                    json={
                        "charts": [{
                            "project": project,
                            "chart_name": chart_name,
                            "params": params
                        }],
                        "expires_in_hours": 24
                    },
                    timeout=10
                )
                
                if response.status_code == 401:
                    return "Error: Invalid Chart API key. Check CHART_API_KEY in environment."
                
                if response.status_code != 200:
                    return f"Error generating token: HTTP {response.status_code} - {response.text[:200]}"
                
                result = response.json()
                return result["tokens"][0]["iframe_url"]
                
            except requests.exceptions.Timeout:
                return "Error: Request timed out while generating token"
            except requests.exceptions.RequestException as e:
                return f"Error: Network request failed - {str(e)}"
            except Exception as e:
                return f"Error: {str(e)}"

