"""
Network Tools for Uni-Wizard
HTTP client and Gitea API integration
"""

import json
import urllib.request
import urllib.error
from typing import Dict, Optional, Any
from base64 import b64encode

from .registry import registry


class HTTPClient:
    """Simple HTTP client for API calls"""
    
    def __init__(self, base_url: str = None, auth: tuple = None):
        self.base_url = base_url
        self.auth = auth
    
    def _make_request(
        self,
        method: str,
        url: str,
        data: Dict = None,
        headers: Dict = None
    ) -> tuple:
        """Make HTTP request and return (body, status_code, error)"""
        try:
            # Build full URL
            full_url = url
            if self.base_url and not url.startswith('http'):
                full_url = f"{self.base_url.rstrip('/')}/{url.lstrip('/')}"
            
            # Prepare data
            body = None
            if data:
                body = json.dumps(data).encode('utf-8')
            
            # Build request
            req = urllib.request.Request(
                full_url,
                data=body,
                method=method
            )
            
            # Add headers
            req.add_header('Content-Type', 'application/json')
            if headers:
                for key, value in headers.items():
                    req.add_header(key, value)
            
            # Add auth
            if self.auth:
                username, password = self.auth
                credentials = b64encode(f"{username}:{password}".encode()).decode()
                req.add_header('Authorization', f'Basic {credentials}')
            
            # Make request
            with urllib.request.urlopen(req, timeout=30) as response:
                return response.read().decode('utf-8'), response.status, None
                
        except urllib.error.HTTPError as e:
            return e.read().decode('utf-8'), e.code, str(e)
        except Exception as e:
            return None, 0, str(e)
    
    def get(self, url: str) -> tuple:
        return self._make_request('GET', url)
    
    def post(self, url: str, data: Dict) -> tuple:
        return self._make_request('POST', url, data)
    
    def put(self, url: str, data: Dict) -> tuple:
        return self._make_request('PUT', url, data)
    
    def delete(self, url: str) -> tuple:
        return self._make_request('DELETE', url)


def http_get(url: str) -> str:
    """
    Perform HTTP GET request.
    
    Args:
        url: URL to fetch
        
    Returns:
        Response body or error message
    """
    client = HTTPClient()
    body, status, error = client.get(url)
    
    if error:
        return f"Error (HTTP {status}): {error}"
    
    return body


def http_post(url: str, body: Dict) -> str:
    """
    Perform HTTP POST request with JSON body.
    
    Args:
        url: URL to post to
        body: JSON body as dictionary
        
    Returns:
        Response body or error message
    """
    client = HTTPClient()
    response_body, status, error = client.post(url, body)
    
    if error:
        return f"Error (HTTP {status}): {error}"
    
    return response_body


# Gitea API Tools
GITEA_URL = "http://143.198.27.163:3000"
GITEA_USER = "timmy"
GITEA_PASS = ""  # Should be configured


def gitea_create_issue(
    repo: str = "Timmy_Foundation/timmy-home",
    title: str = None,
    body: str = None,
    labels: list = None
) -> str:
    """
    Create a Gitea issue.
    
    Args:
        repo: Repository path (owner/repo)
        title: Issue title (required)
        body: Issue body
        labels: List of label names
        
    Returns:
        Created issue URL or error
    """
    if not title:
        return "Error: title is required"
    
    try:
        client = HTTPClient(
            base_url=GITEA_URL,
            auth=(GITEA_USER, GITEA_PASS) if GITEA_PASS else None
        )
        
        data = {
            "title": title,
            "body": body or ""
        }
        if labels:
            data["labels"] = labels
        
        response, status, error = client.post(
            f"/api/v1/repos/{repo}/issues",
            data
        )
        
        if error:
            return f"Error creating issue: {error}"
        
        result = json.loads(response)
        return f"✓ Issue created: #{result['number']} - {result['html_url']}"
        
    except Exception as e:
        return f"Error: {str(e)}"


def gitea_comment(
    repo: str = "Timmy_Foundation/timmy-home",
    issue_number: int = None,
    body: str = None
) -> str:
    """
    Comment on a Gitea issue.
    
    Args:
        repo: Repository path
        issue_number: Issue number (required)
        body: Comment body (required)
        
    Returns:
        Comment result
    """
    if not issue_number or not body:
        return "Error: issue_number and body are required"
    
    try:
        client = HTTPClient(
            base_url=GITEA_URL,
            auth=(GITEA_USER, GITEA_PASS) if GITEA_PASS else None
        )
        
        response, status, error = client.post(
            f"/api/v1/repos/{repo}/issues/{issue_number}/comments",
            {"body": body}
        )
        
        if error:
            return f"Error posting comment: {error}"
        
        result = json.loads(response)
        return f"✓ Comment posted: {result['html_url']}"
        
    except Exception as e:
        return f"Error: {str(e)}"


def gitea_list_issues(
    repo: str = "Timmy_Foundation/timmy-home",
    state: str = "open",
    assignee: str = None
) -> str:
    """
    List Gitea issues.
    
    Args:
        repo: Repository path
        state: open, closed, or all
        assignee: Filter by assignee username
        
    Returns:
        JSON list of issues
    """
    try:
        client = HTTPClient(
            base_url=GITEA_URL,
            auth=(GITEA_USER, GITEA_PASS) if GITEA_PASS else None
        )
        
        url = f"/api/v1/repos/{repo}/issues?state={state}"
        if assignee:
            url += f"&assignee={assignee}"
        
        response, status, error = client.get(url)
        
        if error:
            return f"Error fetching issues: {error}"
        
        issues = json.loads(response)
        
        # Simplify output
        simplified = []
        for issue in issues:
            simplified.append({
                "number": issue["number"],
                "title": issue["title"],
                "state": issue["state"],
                "assignee": issue.get("assignee", {}).get("login") if issue.get("assignee") else None,
                "url": issue["html_url"]
            })
        
        return json.dumps({
            "count": len(simplified),
            "issues": simplified
        }, indent=2)
        
    except Exception as e:
        return f"Error: {str(e)}"


def gitea_get_issue(repo: str = "Timmy_Foundation/timmy-home", issue_number: int = None) -> str:
    """
    Get details of a specific Gitea issue.
    
    Args:
        repo: Repository path
        issue_number: Issue number (required)
        
    Returns:
        Issue details
    """
    if not issue_number:
        return "Error: issue_number is required"
    
    try:
        client = HTTPClient(
            base_url=GITEA_URL,
            auth=(GITEA_USER, GITEA_PASS) if GITEA_PASS else None
        )
        
        response, status, error = client.get(
            f"/api/v1/repos/{repo}/issues/{issue_number}"
        )
        
        if error:
            return f"Error fetching issue: {error}"
        
        issue = json.loads(response)
        
        return json.dumps({
            "number": issue["number"],
            "title": issue["title"],
            "body": issue["body"][:500] + "..." if len(issue["body"]) > 500 else issue["body"],
            "state": issue["state"],
            "assignee": issue.get("assignee", {}).get("login") if issue.get("assignee") else None,
            "created_at": issue["created_at"],
            "url": issue["html_url"]
        }, indent=2)
        
    except Exception as e:
        return f"Error: {str(e)}"


# Register all network tools
def register_all():
    registry.register(
        name="http_get",
        handler=http_get,
        description="Perform HTTP GET request",
        parameters={
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "URL to fetch"
                }
            },
            "required": ["url"]
        },
        category="network"
    )
    
    registry.register(
        name="http_post",
        handler=http_post,
        description="Perform HTTP POST request with JSON body",
        parameters={
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "URL to post to"
                },
                "body": {
                    "type": "object",
                    "description": "JSON body as dictionary"
                }
            },
            "required": ["url", "body"]
        },
        category="network"
    )
    
    registry.register(
        name="gitea_create_issue",
        handler=gitea_create_issue,
        description="Create a Gitea issue",
        parameters={
            "type": "object",
            "properties": {
                "repo": {
                    "type": "string",
                    "description": "Repository path (owner/repo)",
                    "default": "Timmy_Foundation/timmy-home"
                },
                "title": {
                    "type": "string",
                    "description": "Issue title"
                },
                "body": {
                    "type": "string",
                    "description": "Issue body"
                },
                "labels": {
                    "type": "array",
                    "description": "List of label names",
                    "items": {"type": "string"}
                }
            },
            "required": ["title"]
        },
        category="network"
    )
    
    registry.register(
        name="gitea_comment",
        handler=gitea_comment,
        description="Comment on a Gitea issue",
        parameters={
            "type": "object",
            "properties": {
                "repo": {
                    "type": "string",
                    "description": "Repository path",
                    "default": "Timmy_Foundation/timmy-home"
                },
                "issue_number": {
                    "type": "integer",
                    "description": "Issue number"
                },
                "body": {
                    "type": "string",
                    "description": "Comment body"
                }
            },
            "required": ["issue_number", "body"]
        },
        category="network"
    )
    
    registry.register(
        name="gitea_list_issues",
        handler=gitea_list_issues,
        description="List Gitea issues",
        parameters={
            "type": "object",
            "properties": {
                "repo": {
                    "type": "string",
                    "description": "Repository path",
                    "default": "Timmy_Foundation/timmy-home"
                },
                "state": {
                    "type": "string",
                    "enum": ["open", "closed", "all"],
                    "description": "Issue state",
                    "default": "open"
                },
                "assignee": {
                    "type": "string",
                    "description": "Filter by assignee username"
                }
            }
        },
        category="network"
    )
    
    registry.register(
        name="gitea_get_issue",
        handler=gitea_get_issue,
        description="Get details of a specific Gitea issue",
        parameters={
            "type": "object",
            "properties": {
                "repo": {
                    "type": "string",
                    "description": "Repository path",
                    "default": "Timmy_Foundation/timmy-home"
                },
                "issue_number": {
                    "type": "integer",
                    "description": "Issue number"
                }
            },
            "required": ["issue_number"]
        },
        category="network"
    )


register_all()
