"""
CRM Agent Specialized Tools

Tools specific to Customer Relationship Management:
- Contacts management
- Deals/Opportunities
- Sales pipeline
- Activities and tasks
"""
from typing import Any, Dict
from app.tools.base import ReadOnlyTool, WriteTool, ToolParameter, ParameterType, ToolResult
from app.tools.registry import register_tool


@register_tool
class GetContactsTool(ReadOnlyTool):
    """Get CRM contacts"""

    name = "get_contacts"
    description = "Get list of contacts/leads with filters"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="search",
            type=ParameterType.STRING,
            description="Search by name, email, company, or phone",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: lead, prospect, customer, inactive",
            required=False
        ),
        ToolParameter(
            name="source",
            type=ParameterType.STRING,
            description="Filter by lead source: website, referral, ads, events",
            required=False
        ),
        ToolParameter(
            name="owner_id",
            type=ParameterType.STRING,
            description="Filter by sales rep/owner ID",
            required=False
        ),
        ToolParameter(
            name="limit",
            type=ParameterType.INTEGER,
            description="Maximum results to return",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_contacts(**params)
            return ToolResult.success_result(data, "Contacts retrieved successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get contacts: {str(e)}")


@register_tool
class GetContactDetailsTool(ReadOnlyTool):
    """Get detailed contact information"""

    name = "get_contact_details"
    description = "Get comprehensive contact profile with activity history"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="contact_id",
            type=ParameterType.STRING,
            description="Contact ID",
            required=True
        ),
        ToolParameter(
            name="include_activities",
            type=ParameterType.BOOLEAN,
            description="Include recent activities",
            required=False
        ),
        ToolParameter(
            name="include_deals",
            type=ParameterType.BOOLEAN,
            description="Include associated deals",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_contact_details(**params)
            return ToolResult.success_result(data, "Contact details retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get contact details: {str(e)}")


@register_tool
class CreateContactTool(WriteTool):
    """Create a new contact"""

    name = "create_contact"
    description = "Create a new contact or lead in CRM"
    category = "crm"
    agent_types = ["crm", "sales"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="first_name",
            type=ParameterType.STRING,
            description="First name",
            required=True
        ),
        ToolParameter(
            name="last_name",
            type=ParameterType.STRING,
            description="Last name",
            required=True
        ),
        ToolParameter(
            name="email",
            type=ParameterType.STRING,
            description="Email address",
            required=True
        ),
        ToolParameter(
            name="phone",
            type=ParameterType.STRING,
            description="Phone number",
            required=False
        ),
        ToolParameter(
            name="company",
            type=ParameterType.STRING,
            description="Company name",
            required=False
        ),
        ToolParameter(
            name="source",
            type=ParameterType.STRING,
            description="Lead source",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.create_contact(**params)
            return ToolResult.success_result(data, "Contact created successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to create contact: {str(e)}")


@register_tool
class GetDealsTool(ReadOnlyTool):
    """Get deals/opportunities"""

    name = "get_deals"
    description = "Get list of deals/opportunities in the sales pipeline"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="stage",
            type=ParameterType.STRING,
            description="Filter by stage: qualification, proposal, negotiation, closed_won, closed_lost",
            required=False
        ),
        ToolParameter(
            name="owner_id",
            type=ParameterType.STRING,
            description="Filter by sales rep/owner ID",
            required=False
        ),
        ToolParameter(
            name="contact_id",
            type=ParameterType.STRING,
            description="Filter by contact ID",
            required=False
        ),
        ToolParameter(
            name="min_value",
            type=ParameterType.NUMBER,
            description="Minimum deal value",
            required=False
        ),
        ToolParameter(
            name="closing_date_from",
            type=ParameterType.STRING,
            description="Expected close date from",
            required=False
        ),
        ToolParameter(
            name="closing_date_to",
            type=ParameterType.STRING,
            description="Expected close date to",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_deals(**params)
            return ToolResult.success_result(data, "Deals retrieved successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get deals: {str(e)}")


@register_tool
class GetDealDetailsTool(ReadOnlyTool):
    """Get detailed deal information"""

    name = "get_deal_details"
    description = "Get comprehensive deal information with timeline and activities"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="deal_id",
            type=ParameterType.STRING,
            description="Deal ID",
            required=True
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_deal_details(**params)
            return ToolResult.success_result(data, "Deal details retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get deal details: {str(e)}")


@register_tool
class UpdateDealStageTool(WriteTool):
    """Update deal stage"""

    name = "update_deal_stage"
    description = "Move a deal to a different pipeline stage"
    category = "crm"
    agent_types = ["crm", "sales"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="deal_id",
            type=ParameterType.STRING,
            description="Deal ID",
            required=True
        ),
        ToolParameter(
            name="stage",
            type=ParameterType.STRING,
            description="New stage: qualification, proposal, negotiation, closed_won, closed_lost",
            required=True
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Notes about the stage change",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.update_deal_stage(**params)
            return ToolResult.success_result(data, "Deal stage updated")
        except Exception as e:
            return ToolResult.error_result(f"Failed to update deal stage: {str(e)}")


@register_tool
class GetPipelineSummaryTool(ReadOnlyTool):
    """Get sales pipeline summary"""

    name = "get_pipeline_summary"
    description = "Get pipeline overview with deals by stage and total values"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="owner_id",
            type=ParameterType.STRING,
            description="Filter by sales rep/owner ID",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Filter by expected close date from",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="Filter by expected close date to",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_pipeline_summary(**params)
            return ToolResult.success_result(data, "Pipeline summary retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get pipeline summary: {str(e)}")


@register_tool
class GetActivitiesTool(ReadOnlyTool):
    """Get CRM activities"""

    name = "get_activities"
    description = "Get activities like calls, meetings, emails, tasks"
    category = "crm"
    agent_types = ["crm", "sales"]

    parameters = [
        ToolParameter(
            name="contact_id",
            type=ParameterType.STRING,
            description="Filter by contact ID",
            required=False
        ),
        ToolParameter(
            name="deal_id",
            type=ParameterType.STRING,
            description="Filter by deal ID",
            required=False
        ),
        ToolParameter(
            name="type",
            type=ParameterType.STRING,
            description="Activity type: call, meeting, email, task, note",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Status: scheduled, completed, overdue",
            required=False
        ),
        ToolParameter(
            name="owner_id",
            type=ParameterType.STRING,
            description="Filter by owner/assignee ID",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.get_activities(**params)
            return ToolResult.success_result(data, "Activities retrieved")
        except Exception as e:
            return ToolResult.error_result(f"Failed to get activities: {str(e)}")


@register_tool
class CreateActivityTool(WriteTool):
    """Create a new activity"""

    name = "create_activity"
    description = "Log or schedule an activity (call, meeting, task)"
    category = "crm"
    agent_types = ["crm", "sales"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="type",
            type=ParameterType.STRING,
            description="Activity type: call, meeting, email, task, note",
            required=True
        ),
        ToolParameter(
            name="subject",
            type=ParameterType.STRING,
            description="Activity subject/title",
            required=True
        ),
        ToolParameter(
            name="contact_id",
            type=ParameterType.STRING,
            description="Associated contact ID",
            required=False
        ),
        ToolParameter(
            name="deal_id",
            type=ParameterType.STRING,
            description="Associated deal ID",
            required=False
        ),
        ToolParameter(
            name="scheduled_at",
            type=ParameterType.STRING,
            description="Scheduled date/time for future activities",
            required=False
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Activity notes or description",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.create_activity(**params)
            return ToolResult.success_result(data, "Activity created successfully")
        except Exception as e:
            return ToolResult.error_result(f"Failed to create activity: {str(e)}")
