"""
Real Estate Agent Specialized Tools

Tools specific to real estate operations:
- Property listings and search
- Property tours/viewings
- Lead management
- Agent assignment
"""
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 SearchPropertiesTool(ReadOnlyTool):
    """Search property listings"""

    name = "search_properties"
    description = "Search available properties based on criteria (location, price, type, bedrooms)"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="location",
            type=ParameterType.STRING,
            description="City, area, or neighborhood",
            required=False
        ),
        ToolParameter(
            name="property_type",
            type=ParameterType.STRING,
            description="Type: apartment, house, villa, plot, commercial, office",
            required=False
        ),
        ToolParameter(
            name="listing_type",
            type=ParameterType.STRING,
            description="Purpose: sale, rent, lease",
            required=False
        ),
        ToolParameter(
            name="min_price",
            type=ParameterType.NUMBER,
            description="Minimum price/budget",
            required=False
        ),
        ToolParameter(
            name="max_price",
            type=ParameterType.NUMBER,
            description="Maximum price/budget",
            required=False
        ),
        ToolParameter(
            name="bedrooms",
            type=ParameterType.INTEGER,
            description="Number of bedrooms (min)",
            required=False
        ),
        ToolParameter(
            name="bathrooms",
            type=ParameterType.INTEGER,
            description="Number of bathrooms (min)",
            required=False
        ),
        ToolParameter(
            name="min_area",
            type=ParameterType.NUMBER,
            description="Minimum area in sq ft",
            required=False
        ),
        ToolParameter(
            name="amenities",
            type=ParameterType.ARRAY,
            description="Required amenities: parking, pool, gym, garden, security",
            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.search_properties(**params)
            return ToolResult.success_result(data, "Properties found")
        except Exception as e:
            return ToolResult.error_result(f"Failed to search properties: {str(e)}")


@register_tool
class GetPropertyDetailsTool(ReadOnlyTool):
    """Get detailed property information"""

    name = "get_property_details"
    description = "Get comprehensive property details including photos, amenities, and history"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

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

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


@register_tool
class GetFeaturedPropertiesTool(ReadOnlyTool):
    """Get featured/premium listings"""

    name = "get_featured_properties"
    description = "Get featured or premium property listings"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="location",
            type=ParameterType.STRING,
            description="Filter by location",
            required=False
        ),
        ToolParameter(
            name="property_type",
            type=ParameterType.STRING,
            description="Filter by property type",
            required=False
        ),
        ToolParameter(
            name="limit",
            type=ParameterType.INTEGER,
            description="Number of properties to return",
            required=False
        ),
    ]

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


@register_tool
class SchedulePropertyTourTool(WriteTool):
    """Schedule a property viewing/tour"""

    name = "schedule_property_tour"
    description = "Schedule a property viewing or tour appointment"
    category = "real_estate"
    agent_types = ["real_estate", "property"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="property_id",
            type=ParameterType.STRING,
            description="Property ID to visit",
            required=True
        ),
        ToolParameter(
            name="visitor_name",
            type=ParameterType.STRING,
            description="Visitor's full name",
            required=True
        ),
        ToolParameter(
            name="visitor_phone",
            type=ParameterType.STRING,
            description="Visitor's phone number",
            required=True
        ),
        ToolParameter(
            name="visitor_email",
            type=ParameterType.STRING,
            description="Visitor's email address",
            required=False
        ),
        ToolParameter(
            name="preferred_date",
            type=ParameterType.STRING,
            description="Preferred date (YYYY-MM-DD)",
            required=True
        ),
        ToolParameter(
            name="preferred_time",
            type=ParameterType.STRING,
            description="Preferred time (HH:MM)",
            required=True
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Additional notes or requirements",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            data = await connector.schedule_property_tour(**params)
            return ToolResult.success_result(data, "Property tour scheduled")
        except Exception as e:
            return ToolResult.error_result(f"Failed to schedule tour: {str(e)}")


@register_tool
class GetScheduledToursTool(ReadOnlyTool):
    """Get scheduled property tours"""

    name = "get_scheduled_tours"
    description = "Get list of scheduled property tours/viewings"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Filter by date (YYYY-MM-DD)",
            required=False
        ),
        ToolParameter(
            name="property_id",
            type=ParameterType.STRING,
            description="Filter by property ID",
            required=False
        ),
        ToolParameter(
            name="agent_id",
            type=ParameterType.STRING,
            description="Filter by agent ID",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: scheduled, completed, cancelled",
            required=False
        ),
    ]

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


@register_tool
class CreateLeadTool(WriteTool):
    """Create a new property lead"""

    name = "create_property_lead"
    description = "Create a new lead/inquiry for property interest"
    category = "real_estate"
    agent_types = ["real_estate", "property"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="name",
            type=ParameterType.STRING,
            description="Lead's full name",
            required=True
        ),
        ToolParameter(
            name="phone",
            type=ParameterType.STRING,
            description="Phone number",
            required=True
        ),
        ToolParameter(
            name="email",
            type=ParameterType.STRING,
            description="Email address",
            required=False
        ),
        ToolParameter(
            name="property_id",
            type=ParameterType.STRING,
            description="Property of interest (if specific)",
            required=False
        ),
        ToolParameter(
            name="requirements",
            type=ParameterType.STRING,
            description="Property requirements description",
            required=False
        ),
        ToolParameter(
            name="budget_min",
            type=ParameterType.NUMBER,
            description="Minimum budget",
            required=False
        ),
        ToolParameter(
            name="budget_max",
            type=ParameterType.NUMBER,
            description="Maximum budget",
            required=False
        ),
        ToolParameter(
            name="source",
            type=ParameterType.STRING,
            description="Lead source: website, whatsapp, referral, walk_in",
            required=False
        ),
    ]

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


@register_tool
class GetAgentsTool(ReadOnlyTool):
    """Get real estate agents"""

    name = "get_agents"
    description = "Get list of real estate agents"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="location",
            type=ParameterType.STRING,
            description="Filter by area expertise",
            required=False
        ),
        ToolParameter(
            name="specialization",
            type=ParameterType.STRING,
            description="Filter by specialization: residential, commercial, luxury",
            required=False
        ),
        ToolParameter(
            name="available",
            type=ParameterType.BOOLEAN,
            description="Only show currently available agents",
            required=False
        ),
    ]

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


@register_tool
class GetAreaInfoTool(ReadOnlyTool):
    """Get area/neighborhood information"""

    name = "get_area_info"
    description = "Get information about a neighborhood or area (schools, hospitals, amenities)"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="area",
            type=ParameterType.STRING,
            description="Area or neighborhood name",
            required=True
        ),
        ToolParameter(
            name="include_amenities",
            type=ParameterType.BOOLEAN,
            description="Include nearby amenities",
            required=False
        ),
        ToolParameter(
            name="include_price_trends",
            type=ParameterType.BOOLEAN,
            description="Include property price trends",
            required=False
        ),
    ]

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


@register_tool
class CalculateEmiTool(ReadOnlyTool):
    """Calculate EMI for property"""

    name = "calculate_emi"
    description = "Calculate monthly EMI for a property loan"
    category = "real_estate"
    agent_types = ["real_estate", "property"]

    parameters = [
        ToolParameter(
            name="property_price",
            type=ParameterType.NUMBER,
            description="Property price",
            required=True
        ),
        ToolParameter(
            name="down_payment_percent",
            type=ParameterType.NUMBER,
            description="Down payment percentage (default 20)",
            required=False
        ),
        ToolParameter(
            name="interest_rate",
            type=ParameterType.NUMBER,
            description="Annual interest rate (default 8.5)",
            required=False
        ),
        ToolParameter(
            name="loan_tenure_years",
            type=ParameterType.INTEGER,
            description="Loan tenure in years (default 20)",
            required=False
        ),
    ]

    async def execute(self, connector, params: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        try:
            # Calculate EMI locally (no connector needed)
            price = params.get("property_price", 0)
            down_payment_pct = params.get("down_payment_percent", 20)
            interest_rate = params.get("interest_rate", 8.5)
            tenure_years = params.get("loan_tenure_years", 20)

            loan_amount = price * (1 - down_payment_pct / 100)
            monthly_rate = interest_rate / 12 / 100
            num_payments = tenure_years * 12

            if monthly_rate > 0:
                emi = loan_amount * monthly_rate * ((1 + monthly_rate) ** num_payments) / (((1 + monthly_rate) ** num_payments) - 1)
            else:
                emi = loan_amount / num_payments

            total_payment = emi * num_payments
            total_interest = total_payment - loan_amount

            data = {
                "property_price": price,
                "down_payment": price * down_payment_pct / 100,
                "loan_amount": round(loan_amount, 2),
                "interest_rate": interest_rate,
                "tenure_years": tenure_years,
                "monthly_emi": round(emi, 2),
                "total_payment": round(total_payment, 2),
                "total_interest": round(total_interest, 2)
            }
            return ToolResult.success_result(data, "EMI calculated")
        except Exception as e:
            return ToolResult.error_result(f"Failed to calculate EMI: {str(e)}")
