"""
Healthcare Agent Specialized Tools

Tools specific to healthcare operations:
- Patient management
- Appointment scheduling
- Prescriptions
- Medical records
"""
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 GetPatientsTool(ReadOnlyTool):
    """Get list of patients"""

    name = "get_patients"
    description = "Get list of patients with optional filters"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]

    parameters = [
        ToolParameter(
            name="search",
            type=ParameterType.STRING,
            description="Search by name, phone, or patient ID",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Patient status: active, inactive, discharged",
            required=False
        ),
        ToolParameter(
            name="limit",
            type=ParameterType.INTEGER,
            description="Maximum number of results",
            required=False
        ),
    ]

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


@register_tool
class GetPatientDetailsTool(ReadOnlyTool):
    """Get detailed patient information"""

    name = "get_patient_details"
    description = "Get comprehensive patient profile including medical history summary"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]

    parameters = [
        ToolParameter(
            name="patient_id",
            type=ParameterType.STRING,
            description="Patient ID",
            required=True
        ),
        ToolParameter(
            name="include_history",
            type=ParameterType.BOOLEAN,
            description="Include recent medical history",
            required=False
        ),
    ]

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


@register_tool
class GetAppointmentsTool(ReadOnlyTool):
    """Get appointments schedule"""

    name = "get_appointments"
    description = "Get appointments for a specific date, doctor, or patient"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]

    parameters = [
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Date for appointments (YYYY-MM-DD)",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Start date for range query",
            required=False
        ),
        ToolParameter(
            name="date_to",
            type=ParameterType.STRING,
            description="End date for range query",
            required=False
        ),
        ToolParameter(
            name="doctor_id",
            type=ParameterType.STRING,
            description="Filter by doctor ID",
            required=False
        ),
        ToolParameter(
            name="patient_id",
            type=ParameterType.STRING,
            description="Filter by patient ID",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Status: scheduled, confirmed, completed, cancelled, no_show",
            required=False
        ),
    ]

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


@register_tool
class CreateAppointmentTool(WriteTool):
    """Schedule a new appointment"""

    name = "create_appointment"
    description = "Schedule a new patient appointment"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="patient_id",
            type=ParameterType.STRING,
            description="Patient ID",
            required=True
        ),
        ToolParameter(
            name="doctor_id",
            type=ParameterType.STRING,
            description="Doctor ID",
            required=True
        ),
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Appointment date (YYYY-MM-DD)",
            required=True
        ),
        ToolParameter(
            name="time",
            type=ParameterType.STRING,
            description="Appointment time (HH:MM)",
            required=True
        ),
        ToolParameter(
            name="type",
            type=ParameterType.STRING,
            description="Appointment type: consultation, follow_up, checkup, procedure",
            required=True
        ),
        ToolParameter(
            name="notes",
            type=ParameterType.STRING,
            description="Appointment notes or reason",
            required=False
        ),
    ]

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


@register_tool
class UpdateAppointmentTool(WriteTool):
    """Update or reschedule an appointment"""

    name = "update_appointment"
    description = "Update appointment details or status"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]
    requires_confirmation = True

    parameters = [
        ToolParameter(
            name="appointment_id",
            type=ParameterType.STRING,
            description="Appointment ID",
            required=True
        ),
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="New date (YYYY-MM-DD)",
            required=False
        ),
        ToolParameter(
            name="time",
            type=ParameterType.STRING,
            description="New time (HH:MM)",
            required=False
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="New status: confirmed, cancelled, completed, no_show",
            required=False
        ),
    ]

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


@register_tool
class GetPrescriptionsTool(ReadOnlyTool):
    """Get patient prescriptions"""

    name = "get_prescriptions"
    description = "Get prescriptions for a patient"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital", "pharmacy"]

    parameters = [
        ToolParameter(
            name="patient_id",
            type=ParameterType.STRING,
            description="Patient ID",
            required=True
        ),
        ToolParameter(
            name="status",
            type=ParameterType.STRING,
            description="Filter by status: active, completed, expired",
            required=False
        ),
        ToolParameter(
            name="date_from",
            type=ParameterType.STRING,
            description="Filter prescriptions from date",
            required=False
        ),
    ]

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


@register_tool
class GetDoctorScheduleTool(ReadOnlyTool):
    """Get doctor's availability schedule"""

    name = "get_doctor_schedule"
    description = "Get available time slots for a doctor"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]

    parameters = [
        ToolParameter(
            name="doctor_id",
            type=ParameterType.STRING,
            description="Doctor ID",
            required=True
        ),
        ToolParameter(
            name="date",
            type=ParameterType.STRING,
            description="Date to check availability (YYYY-MM-DD)",
            required=True
        ),
    ]

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


@register_tool
class GetMedicalRecordsTool(ReadOnlyTool):
    """Get patient medical records"""

    name = "get_medical_records"
    description = "Get patient's medical records and visit history"
    category = "healthcare"
    agent_types = ["healthcare", "clinic", "hospital"]

    parameters = [
        ToolParameter(
            name="patient_id",
            type=ParameterType.STRING,
            description="Patient ID",
            required=True
        ),
        ToolParameter(
            name="record_type",
            type=ParameterType.STRING,
            description="Type: visit_notes, lab_results, imaging, procedures",
            required=False
        ),
        ToolParameter(
            name="limit",
            type=ParameterType.INTEGER,
            description="Number of recent records to retrieve",
            required=False
        ),
    ]

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