"""
WhatsApp Flows Tools for Meta Ads MCP Server

This module provides tools for WhatsApp Flows - structured interactive forms
that businesses can send to customers for lead generation, surveys, and more.

Based on Meta WhatsApp Flows API:
https://developers.facebook.com/docs/whatsapp/flows
"""

from __future__ import annotations

from typing import Dict, Any, Optional

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

logger = get_logger(__name__)


class WhatsAppFlowsEngine:
    """Handles WhatsApp Flows operations"""
    
    def __init__(self, client: MetaClient):
        self.client = client
    
    async def create_flow(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Create a new WhatsApp Flow.
        
        Args:
            arguments: {
                "waba_id": "123",  # WhatsApp Business Account ID
                "name": "Lead Capture Flow",
                "categories": ["LEAD_GENERATION"],
                "clone_flow_id": "456"  # Optional: clone existing flow
            }
        
        Returns:
            ToolResult with flow ID
        """
        try:
            waba_id = arguments.get("waba_id")
            name = arguments.get("name")
            categories = arguments.get("categories", ["OTHER"])
            
            if not waba_id or not name:
                return ToolResult(
                    ok=False,
                    error={"message": "waba_id and name are required"}
                )
            
            logger.info(f"Creating WhatsApp Flow: {name}")
            
            body = {
                "name": name,
                "categories": categories
            }
            
            # Clone from existing flow if specified
            if "clone_flow_id" in arguments:
                body["clone_flow_id"] = arguments["clone_flow_id"]
            
            response = await self.client.post(
                f"{waba_id}/flows",
                body=body
            )
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": response.get("id"),
                    "name": name,
                    "categories": categories,
                    "status": "DRAFT",
                    "message": "WhatsApp Flow created successfully",
                    "next_steps": [
                        "Update flow JSON with screens and components",
                        "Test flow in preview mode",
                        "Publish flow when ready",
                        "Send flow to customers via message template"
                    ],
                    "available_categories": [
                        "LEAD_GENERATION",
                        "SIGN_UP",
                        "BOOKING_APPOINTMENT",
                        "CONTACT_US",
                        "CUSTOMER_SUPPORT",
                        "SURVEY",
                        "OTHER"
                    ]
                }
            )
            
        except MetaApiError as exc:
            logger.error("create_flow_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"create_flow_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def update_flow_json(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Update the JSON definition of a WhatsApp Flow.
        
        Args:
            arguments: {
                "flow_id": "123",
                "flow_json": {
                    "version": "3.0",
                    "screens": [...]
                }
            }
        
        Returns:
            ToolResult with update status
        """
        try:
            flow_id = arguments.get("flow_id")
            flow_json = arguments.get("flow_json")
            
            if not flow_id or not flow_json:
                return ToolResult(
                    ok=False,
                    error={"message": "flow_id and flow_json are required"}
                )
            
            logger.info(f"Updating WhatsApp Flow JSON: {flow_id}")
            
            response = await self.client.post(
                f"{flow_id}/assets",
                body={
                    "name": "flow.json",
                    "asset_type": "FLOW_JSON",
                    "file": flow_json
                }
            )
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": flow_id,
                    "success": response.get("success", True),
                    "message": "Flow JSON updated successfully",
                    "validation": response.get("validation_errors", [])
                }
            )
            
        except MetaApiError as exc:
            logger.error("update_flow_json_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"update_flow_json_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def publish_flow(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Publish a WhatsApp Flow to make it available for use.
        
        Args:
            arguments: {
                "flow_id": "123"
            }
        
        Returns:
            ToolResult with publish status
        """
        try:
            flow_id = arguments.get("flow_id")
            
            if not flow_id:
                return ToolResult(
                    ok=False,
                    error={"message": "flow_id is required"}
                )
            
            logger.info(f"Publishing WhatsApp Flow: {flow_id}")
            
            response = await self.client.post(
                f"{flow_id}/publish",
                body={}
            )
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": flow_id,
                    "status": "PUBLISHED",
                    "success": response.get("success", True),
                    "message": "Flow published successfully",
                    "usage": "Flow can now be sent via message templates"
                }
            )
            
        except MetaApiError as exc:
            logger.error("publish_flow_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"publish_flow_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def get_flow(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Get details of a WhatsApp Flow.
        
        Args:
            arguments: {
                "flow_id": "123"
            }
        
        Returns:
            ToolResult with flow details
        """
        try:
            flow_id = arguments.get("flow_id")
            
            if not flow_id:
                return ToolResult(
                    ok=False,
                    error={"message": "flow_id is required"}
                )
            
            logger.info(f"Getting WhatsApp Flow: {flow_id}")
            
            response = await self.client.get(
                flow_id,
                params={
                    "fields": "id,name,status,categories,validation_errors,json_version,preview"
                }
            )
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": flow_id,
                    "name": response.get("name"),
                    "status": response.get("status"),
                    "categories": response.get("categories", []),
                    "json_version": response.get("json_version"),
                    "validation_errors": response.get("validation_errors", []),
                    "preview_url": response.get("preview", {}).get("url")
                }
            )
            
        except MetaApiError as exc:
            logger.error("get_flow_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"get_flow_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def list_flows(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        List all WhatsApp Flows for a business account.
        
        Args:
            arguments: {
                "waba_id": "123"
            }
        
        Returns:
            ToolResult with list of flows
        """
        try:
            waba_id = arguments.get("waba_id")
            
            if not waba_id:
                return ToolResult(
                    ok=False,
                    error={"message": "waba_id is required"}
                )
            
            logger.info(f"Listing WhatsApp Flows for: {waba_id}")
            
            response = await self.client.get(
                f"{waba_id}/flows",
                params={
                    "fields": "id,name,status,categories"
                }
            )
            
            flows = response.get("data", [])
            
            return ToolResult(
                ok=True,
                data={
                    "waba_id": waba_id,
                    "flows": flows,
                    "count": len(flows),
                    "status_breakdown": {
                        "draft": sum(1 for f in flows if f.get("status") == "DRAFT"),
                        "published": sum(1 for f in flows if f.get("status") == "PUBLISHED"),
                        "deprecated": sum(1 for f in flows if f.get("status") == "DEPRECATED")
                    }
                }
            )
            
        except MetaApiError as exc:
            logger.error("list_flows_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"list_flows_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def delete_flow(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Delete a WhatsApp Flow (only works for DRAFT flows).
        
        Args:
            arguments: {
                "flow_id": "123"
            }
        
        Returns:
            ToolResult with deletion status
        """
        try:
            flow_id = arguments.get("flow_id")
            
            if not flow_id:
                return ToolResult(
                    ok=False,
                    error={"message": "flow_id is required"}
                )
            
            logger.info(f"Deleting WhatsApp Flow: {flow_id}")
            
            await self.client.delete(flow_id)
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": flow_id,
                    "deleted": True,
                    "message": "Flow deleted successfully"
                }
            )
            
        except MetaApiError as exc:
            logger.error("delete_flow_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"delete_flow_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})
    
    async def deprecate_flow(
        self, 
        arguments: Dict[str, Any]
    ) -> ToolResult:
        """
        Deprecate a published WhatsApp Flow.
        
        Args:
            arguments: {
                "flow_id": "123"
            }
        
        Returns:
            ToolResult with deprecation status
        """
        try:
            flow_id = arguments.get("flow_id")
            
            if not flow_id:
                return ToolResult(
                    ok=False,
                    error={"message": "flow_id is required"}
                )
            
            logger.info(f"Deprecating WhatsApp Flow: {flow_id}")
            
            response = await self.client.post(
                f"{flow_id}/deprecate",
                body={}
            )
            
            return ToolResult(
                ok=True,
                data={
                    "flow_id": flow_id,
                    "status": "DEPRECATED",
                    "success": response.get("success", True),
                    "message": "Flow deprecated successfully",
                    "note": "Deprecated flows cannot be used in new messages but existing flows continue to work"
                }
            )
            
        except MetaApiError as exc:
            logger.error("deprecate_flow_failed", **exc.to_dict())
            return ToolResult(ok=False, error=exc.to_dict())
        except Exception as exc:
            logger.error(f"deprecate_flow_error: {exc}")
            return ToolResult(ok=False, error={"message": str(exc)})


_whatsapp_flows_engine: Optional[WhatsAppFlowsEngine] = None


def get_whatsapp_flows_engine() -> WhatsAppFlowsEngine:
    """Get the global WhatsAppFlowsEngine instance"""
    global _whatsapp_flows_engine
    if _whatsapp_flows_engine is None:
        from .meta_client import get_client
        _whatsapp_flows_engine = WhatsAppFlowsEngine(get_client())
    return _whatsapp_flows_engine
