from __future__ import annotations

from typing import Any, Dict, Optional

from .errors import MetaApiError
from .logging import get_logger
from .meta_client import get_client, MetaClient
from .schemas import ToolResult

logger = get_logger(__name__)


async def create_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Create a new lead generation form.
    
    Args:
        arguments: {
            "page_id": "123",
            "name": "Contact Form",
            "questions": [...],
            "privacy_policy_url": "https://...",
            "locale": "en_US"
        }
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with created form ID
    """
    try:
        client = client or get_client()
        page_id = arguments.get("page_id")
        
        if not page_id:
            return ToolResult(ok=False, error={"message": "page_id is required"})
        
        form_data = {
            "name": arguments.get("name"),
            "questions": arguments.get("questions", []),
            "privacy_policy_url": arguments.get("privacy_policy_url"),
            "locale": arguments.get("locale", "en_US"),
        }
        
        # Add optional fields
        if "follow_up_action_url" in arguments:
            form_data["follow_up_action_url"] = arguments["follow_up_action_url"]
        if "thank_you_page" in arguments:
            form_data["thank_you_page"] = arguments["thank_you_page"]
        
        response = await client.post(
            f"{page_id}/leadgen_forms",
            body=form_data
        )
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("create_leadgen_form_failed", **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def get_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Get details of a specific lead generation form.
    
    Args:
        arguments: {"form_id": "123"}
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with form details
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        fields = [
            "id",
            "name",
            "status",
            "locale",
            "questions",
            "privacy_policy_url",
            "follow_up_action_url",
            "leads_count",
            "created_time",
        ]
        
        response = await client.get(
            form_id,
            params={"fields": ",".join(fields)}
        )
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("get_leadgen_form_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def update_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Update an existing lead generation form.
    
    Args:
        arguments: {
            "form_id": "123",
            "name": "Updated Name",
            "status": "ACTIVE"
        }
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with success status
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        update_data = {}
        
        # Add fields to update
        if "name" in arguments:
            update_data["name"] = arguments["name"]
        if "status" in arguments:
            update_data["status"] = arguments["status"]
        if "questions" in arguments:
            update_data["questions"] = arguments["questions"]
        if "privacy_policy_url" in arguments:
            update_data["privacy_policy_url"] = arguments["privacy_policy_url"]
        
        response = await client.post(form_id, body=update_data)
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("update_leadgen_form_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def delete_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Delete a lead generation form.
    
    Args:
        arguments: {"form_id": "123"}
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with success status
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        response = await client.delete(form_id)
        
        return ToolResult(ok=True, data=response)
    except MetaApiError as exc:
        logger.error("delete_leadgen_form_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def list_leadgen_leads_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """List all leads from a lead generation form.
    
    Args:
        arguments: {
            "form_id": "123",
            "limit": 100
        }
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with list of leads
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        limit = arguments.get("limit", 100)
        
        response = await client.get(
            f"{form_id}/leads",
            params={
                "limit": limit,
                "fields": "id,created_time,field_data,ad_id,form_id"
            }
        )
        
        leads = response.get("data", [])
        
        return ToolResult(
            ok=True,
            data={
                "leads": leads,
                "count": len(leads),
                "form_id": form_id,
                "paging": response.get("paging"),
            }
        )
    except MetaApiError as exc:
        logger.error("list_leadgen_leads_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def export_leadgen_leads_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Export all leads from a form with detailed field data.
    
    Args:
        arguments: {
            "form_id": "123",
            "format": "csv"  # or "json"
        }
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with exported leads data
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        export_format = arguments.get("format", "json")
        
        # Fetch all leads (handle pagination)
        all_leads = []
        next_url = f"{form_id}/leads"
        
        while next_url:
            response = await client.get(
                next_url,
                params={"fields": "id,created_time,field_data,ad_id,form_id,ad_name,campaign_name"}
            )
            
            all_leads.extend(response.get("data", []))
            
            # Check for next page
            paging = response.get("paging", {})
            next_url = paging.get("next")
            if not next_url:
                break
        
        # Format leads based on requested format
        if export_format == "csv":
            # Convert to CSV-friendly format
            csv_data = []
            for lead in all_leads:
                lead_row = {
                    "lead_id": lead.get("id"),
                    "created_time": lead.get("created_time"),
                    "ad_id": lead.get("ad_id"),
                    "form_id": lead.get("form_id"),
                }
                
                # Flatten field_data
                for field in lead.get("field_data", []):
                    field_name = field.get("name", "unknown")
                    field_values = field.get("values", [])
                    lead_row[field_name] = ", ".join(field_values) if field_values else ""
                
                csv_data.append(lead_row)
            
            return ToolResult(
                ok=True,
                data={
                    "leads": csv_data,
                    "count": len(csv_data),
                    "format": "csv",
                }
            )
        else:
            # Return as JSON
            return ToolResult(
                ok=True,
                data={
                    "leads": all_leads,
                    "count": len(all_leads),
                    "format": "json",
                }
            )
    except MetaApiError as exc:
        logger.error("export_leadgen_leads_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def preview_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Get a preview URL for a lead generation form.
    
    Args:
        arguments: {"form_id": "123"}
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with preview URL
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        response = await client.get(
            form_id,
            params={"fields": "id,name,preview_url"}
        )
        
        return ToolResult(
            ok=True,
            data={
                "form_id": response.get("id"),
                "name": response.get("name"),
                "preview_url": response.get("preview_url"),
            }
        )
    except MetaApiError as exc:
        logger.error("preview_leadgen_form_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


async def test_leadgen_form_handler(arguments: Dict[str, Any], client: Optional[MetaClient] = None) -> ToolResult:
    """Submit a test lead to a form for testing purposes.
    
    Args:
        arguments: {
            "form_id": "123",
            "field_data": [{"name": "email", "values": ["test@example.com"]}]
        }
        client: Optional MetaClient instance
        
    Returns:
        ToolResult with test submission result
    """
    try:
        client = client or get_client()
        form_id = arguments.get("form_id")
        field_data = arguments.get("field_data", [])
        
        if not form_id:
            return ToolResult(ok=False, error={"message": "form_id is required"})
        
        test_data = {
            "field_data": field_data,
        }
        
        response = await client.post(
            f"{form_id}/test_submit",
            body=test_data
        )
        
        return ToolResult(
            ok=True,
            data={
                "success": response.get("success", True),
                "form_id": form_id,
                "message": "Test lead submitted successfully",
            }
        )
    except MetaApiError as exc:
        logger.error("test_leadgen_form_failed", form_id=form_id, **exc.to_dict())
        return ToolResult(ok=False, error=exc.to_dict())


