import httpx
import time
import json
import os
from typing import Optional, Dict, Any, List
from .signer import VoniSigner
from .exceptions import VoniAuthError, VoniApiError
from .resources.projects import ProjectResource
from .resources.chat import ChatResource
from .resources.webhooks import WebhookResource
from .resources.conversations import ConversationResource
from .resources.messages import MessageResource
from .resources.documents import DocumentResource
from .resources.users import UserResource
from .resources.analytics import AnalyticsResource
from .resources.appointments import AppointmentResource
from .resources.leads import LeadResource
from .resources.crawl import CrawlResource
from .resources.prompt_templates import PromptTemplateResource
from .resources.integrations import IntegrationResource
from .resources.workflows import WorkflowResource
from .resources.captcha import CaptchaResource
from .resources.translations import TranslationsResource
from .resources.invitations import InvitationResource
from .resources.api_keys import ApiKeysResource
from .resources.conflicts import ConflictsResource
from .resources.project_members import ProjectMembersResource
from .resources.logs import LogsResource
from .resources.system import SystemResource
from .resources.contact import ContactResource

class Voni:
    """
    Voni AI Python SDK Client.
    
    The programmable gateway to the Voniai Infrastructure.
    """
    
    def __init__(
        self, 
        api_key: Optional[str] = None, 
        api_url: str = "https://api.voni.dev",
        timeout: float = 30.0
    ):
        self.api_key = api_key or os.environ.get("VONI_API_KEY")
        self.api_url = api_url.rstrip("/")
        self.timeout = timeout
        
        # Initialize resources
        self.projects = ProjectResource(self)
        self.chat = ChatResource(self)
        self.webhooks = WebhookResource(self)
        self.conversations = ConversationResource(self)
        self.messages = MessageResource(self)
        self.documents = DocumentResource(self)
        self.users = UserResource(self)
        self.analytics = AnalyticsResource(self)
        self.appointments = AppointmentResource(self)
        self.leads = LeadResource(self)
        self.crawl = CrawlResource(self)
        self.prompt_templates = PromptTemplateResource(self)
        self.integrations = IntegrationResource(self)
        self.workflows = WorkflowResource(self)
        self.captcha = CaptchaResource(self)
        self.translations = TranslationsResource(self)
        self.invitations = InvitationResource(self)
        self.api_keys = ApiKeysResource(self)
        self.conflicts = ConflictsResource(self)
        self.project_members = ProjectMembersResource(self)
        self.logs = LogsResource(self)
        self.system = SystemResource(self)
        self.contact = ContactResource(self)
        
        self._client = httpx.Client(
            base_url=self.api_url,
            timeout=self.timeout
        )

    def _request(
        self, 
        method: str, 
        path: str, 
        params: Optional[Dict[str, Any]] = None,
        json_data: Optional[Dict[str, Any]] = None,
        files: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """Internal helper to make signed requests."""
        
        url_path = f"/api/v1{path}"
        timestamp = str(int(time.time()))
        body_str = json.dumps(json_data) if json_data else ""
        
        headers = {
            # "Content-Type": "application/json" # Let httpx handle content type for files
        }
        if not files:
            headers["Content-Type"] = "application/json"
        
        # Only sign if API key is present
        if self.api_key:
            # Generate signature
            # For file uploads, we sign with empty body or as is?
            # Assuming empty body for signature if files are present to avoid reading file twice
            sign_body = body_str if not files else ""
            
            signature = VoniSigner.sign_request(
                api_key=self.api_key,
                method=method,
                path=url_path,
                body=sign_body,
                timestamp=int(timestamp)
            )
            
            headers.update({
                "X-API-Key": self.api_key,
                "X-Voni-Timestamp": timestamp,
                "X-Voni-Signature": signature
            })
        
        response = self._client.request(
            method=method,
            url=url_path,
            params=params,
            headers=headers,
            content=body_str if body_str and not files else None,
            files=files
        )
        
        if response.status_code == 401:
            raise VoniAuthError("Invalid API Key or Signature")
        
        if response.status_code >= 400:
            raise VoniApiError(
                f"API Error: {response.text}", 
                status_code=response.status_code,
                response=response.text
            )
            
        return response.json()

    def close(self):
        """Close the underlying HTTP client."""
        self._client.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
