from typing import List, Dict, Any, Callable
from .health_read import HealthReader
from .health_write import HealthWriter
from .obsidian import ObsidianTool
from .garmin import GarminTool
from .garmin import GarminTool
from .analytics import AnalyticsTool
from .web import WebSearchTool
from .shell_tool import execute_shell
from .file_ops import download_file, save_file
from .system_ops import get_system_status
from .process_ops import kill_process, get_process_list

# Tool Definitions
TOOLS_SCHEMA = [
    # --- Garmin & Metrics Read ---
    {
        "type": "function",
        "function": {
            "name": "get_daily_detailed_stats",
            "description": "Get a comprehensive ONE-DAY SUMMARY (Metrics + Activity + Log Counts). Use for 'how was my day'. Do NOT use for filtering specific logs (use get_manual_history).",
            "parameters": {
                "type": "object",
                "properties": {"target_date": {"type": "string", "description": "YYYY-MM-DD"}},
                "required": ["target_date"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_metric_history",
            "description": "**USE THIS when user asks about time-based trends**: 'past X days/weeks/months', 'recent changes', 'last year', 'how has X changed', 'X trend over time'. Returns analyzed trends with statistics for time ranges >7 days, raw data for ≤7 days. Supported metrics: rhr (resting heart rate), hrv, sleep, stress, steps, heart_rate, weight. Example: user asks 'past 2 months RHR' → call this with metric_type='rhr', start_date=60 days ago, end_date=today.",
            "parameters": {
                "type": "object",
                "properties": {
                    "metric_type": {"type": "string", "description": "Metric name: rhr, hrv, sleep, stress, steps, heart_rate, weight"},
                    "start_date": {"type": "string", "description": "Start date YYYY-MM-DD (calculate from user's time range, e.g. 'past 2 months' = 60 days ago)"},
                    "end_date": {"type": "string", "description": "End date YYYY-MM-DD (typically today)"}
                },
                "required": ["metric_type", "start_date", "end_date"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_activity_history",
            "description": "Get list of workouts/activities in a date range.",
            "parameters": {
                "type": "object",
                "properties": {
                    "start_date": {"type": "string", "description": "YYYY-MM-DD"},
                    "end_date": {"type": "string", "description": "YYYY-MM-DD"}
                },
                "required": ["start_date", "end_date"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_aggregated_analysis",
            "description": "**REQUIRED for time-range questions**: When user asks 'past X days/weeks/months/years', 'recent trend', 'change over time', 'how has X changed', use THIS tool (not get_metric_history). Returns analyzed trends with statistics, yearly comparisons, and 30-day rolling averages. Examples: 'past 2 months RHR', 'HRV trend this year', 'sleep quality last 90 days'.",
            "parameters": {
                "type": "object",
                "properties": {
                    "start_date": {
                        "type": "string",
                        "description": "Start date YYYY-MM-DD (optional, defaults to 2 years ago)"
                    },
                    "end_date": {
                        "type": "string",
                        "description": "End date YYYY-MM-DD (optional, defaults to today)"
                    },
                    "metrics": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Metrics to analyze: ['rhr', 'hrv', 'sleep', 'stress', 'steps']. If omitted, analyzes all."
                    }
                },
                "required": []
            }
        }
    },
    # --- Manual Read ---
    {
        "type": "function",
        "function": {
            "name": "get_manual_history",
            "description": "query manual logs (diet, alcohol, etc) over a range.",
            "parameters": {
                "type": "object",
                "properties": {
                    "start_date": {"type": "string", "description": "YYYY-MM-DD"},
                    "end_date": {"type": "string", "description": "YYYY-MM-DD"},
                    "category": {
                        "type": "string", 
                        "enum": ["diet", "alcohol", "supplements", "feelings", "fasting", "all"],
                        "description": "Category of logs to retrieve"
                    }
                },
                "required": ["start_date", "end_date"]
            }
        }
    },
    # --- Manual Write (Operate) ---
    {
        "type": "function",
        "function": {
            "name": "log_diet",
            "description": "Log food/meal.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string"},
                    "description": {"type": "string"},
                    "meal_type": {"type": "string", "enum": ["breakfast", "lunch", "dinner", "snack"]},
                    "time": {"type": "string", "description": "HH:MM (optional)"}
                },
                "required": ["target_date", "description"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "log_alcohol",
            "description": "Log alcohol.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string"},
                    "alcohol_type": {"type": "string"},
                    "amount": {"type": "string"},
                    "time": {"type": "string", "description": "HH:MM (optional)"}
                },
                "required": ["target_date", "alcohol_type", "amount"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "log_supplement",
            "description": "Log supplement.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string"},
                    "name": {"type": "string"},
                    "dosage": {"type": "string"},
                    "time": {"type": "string", "description": "HH:MM (optional)"}
                },
                "required": ["target_date", "name", "dosage"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "log_feeling",
            "description": "Log body feeling or symptom.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string"},
                    "feeling_type": {"type": "string"},
                    "severity": {"type": "integer", "description": "1-10"},
                    "description": {"type": "string"},
                    "time": {"type": "string", "description": "HH:MM (optional)"}
                },
                "required": ["target_date", "feeling_type", "severity", "description"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "log_fasting",
            "description": "Log fasting mode.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string"},
                    "mode": {"type": "string", "description": "OMAD, PSMF, etc"}
                },
                "required": ["target_date", "mode"]
            }
        }
    },
    # --- Sync ---
    {
        "type": "function",
        "function": {
            "name": "sync_obsidian",
            "description": "Sync Obsidian note.",
            "parameters": {
                "type": "object",
                "properties": {"target_date": {"type": "string"}},
                "required": ["target_date"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "sync_garmin",
            "description": "Action to synchronize the latest health data from Garmin Connect. You MUST use this tool when the user asks to 'sync', 'update', or 'fetch' data. Do not assume data is already up-to-date.",
            "parameters": {
                "type": "object",
                "properties": {
                    "target_date": {"type": "string", "description": "YYYY-MM-DD (optional, default to today)"}
                },
                "required": []
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_health_insights",
            "description": "Get advanced health insights, correlations, and trends (e.g., alcohol impact on sleep, heart rate trends).",
            "parameters": {
                "type": "object",
                "properties": {
                    "analysis_type": {
                        "type": "string",
                        "description": "Type of analysis: 'recovery_correlations' (alcohol/activity impact), 'fitness_trends' (RHR/fitness), 'lifestyle_impact' (fasting/supplements)."
                    },
                    "lookback_days": {
                        "type": "integer",
                        "description": "Number of days to analyze (default 30, recommend 30-90 for trends)."
                    }
                },
                "required": ["analysis_type"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "analyze_driver",
            "description": "Analyze if a specific factor (Driver) impacts a health metric (Target). e.g., 'Does Magnesium improve sleep?'.",
            "parameters": {
                "type": "object",
                "properties": {
                    "driver_metric": {
                        "type": "string",
                        "description": "The cause/driver column. Examples: 'alcohol_units', 'stress', 'steps', 'fasting_mode', 'has_magnesium', 'has_alcohol'."
                    },
                    "target_metric": {
                        "type": "string",
                        "description": "The effect/target column. Examples: 'sleep', 'rhr', 'hrv', 'body_battery'."
                    },
                    "method": {
                        "type": "string",
                        "enum": ["correlation", "group_compare"],
                        "description": "Use 'correlation' for continuous values (alcohol units vs sleep) or 'group_compare' for events (Magnesium YES/NO vs Sleep)."
                    },
                    "lookback_days": {
                        "type": "integer",
                        "description": "Days to analyze (default 30)."
                    }
                },
                "required": ["driver_metric", "target_metric", "method"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_web",
            "description": "Search the web for real-time information, latest scientific research, or biohacker experiences.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Search query (e.g. 'latest study on NAD+ effects')"
                    }
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "execute_shell",
            "description": "Execute a shell command (zsh) in a persistent session. Use for system questions, file checks, or running scripts. If user asks 'how to X', providing a numbered list, you can use this to execute the user's choice.",
            "parameters": {
                "type": "object",
                "properties": {
                    "command": {
                        "type": "string", 
                        "description": "Command to execute (e.g. 'ls -la', 'git status', 'python3 script.py')"
                    },
                    "timeout": {
                        "type": "number",
                        "description": "Timeout in seconds to wait for output (default 2.0). Increase for long-running commands like 'top' (to get a snapshot) or 'sleep 5'.",
                        "default": 2.0
                    }
                },
                "required": ["command"]
            }
        }
    },
    # --- New Shell Tools (Tier 1 & 2) ---
    {
        "type": "function",
        "function": {
            "name": "download_file",
            "description": "Upload a file from the server to Slack. Use when user wants to see a log file or config.",
            "parameters": {
                "type": "object",
                "properties": {
                    "file_path": {"type": "string", "description": "Absolute path to the file"}
                },
                "required": ["file_path"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "save_file",
            "description": "Save content to a file on the server. Use to create/edit configs.",
            "parameters": {
                "type": "object",
                "properties": {
                    "file_path": {"type": "string", "description": "Target absolute path"},
                    "content": {"type": "string", "description": "Text content to save"},
                    "overwrite": {"type": "boolean", "description": "Allow overwriting existing file"}
                },
                "required": ["file_path", "content"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_system_status",
            "description": "Get a visual dashboard of system health (CPU, Memory, Disk, Top Processes).",
            "parameters": {
                "type": "object",
                "properties": {},
                "required": []
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "kill_process",
            "description": "Terminate a process by PID.",
            "parameters": {
                "type": "object",
                "properties": {
                    "pid": {"type": "integer", "description": "Process ID"},
                    "signal_type": {"type": "string", "enum": ["SIGTERM", "SIGKILL"], "default": "SIGTERM"}
                },
                "required": ["pid"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_process_list",
            "description": "List running processes with optional name filtering.",
            "parameters": {
                "type": "object",
                "properties": {
                    "filter_name": {"type": "string", "description": "Filter by process name (case-insensitive)"},
                    "limit": {"type": "integer", "default": 15}
                },
                "required": []
            }
        }
    }
]

# Function Map
TOOL_FUNCTIONS: Dict[str, Callable] = {
    "get_daily_detailed_stats": HealthReader.get_daily_detailed_stats,
    "get_metric_history": HealthReader.get_metric_history,
    "get_activity_history": HealthReader.get_activity_history,
    "get_manual_history": HealthReader.get_manual_history,
    "get_aggregated_analysis": HealthReader.get_aggregated_analysis,
    
    "log_diet": HealthWriter.log_diet,
    "log_alcohol": HealthWriter.log_alcohol,
    "log_supplement": HealthWriter.log_supplement,
    "log_feeling": HealthWriter.log_feeling,
    "log_fasting": HealthWriter.log_fasting,
    
    "sync_obsidian": ObsidianTool.sync_obsidian,
    "sync_garmin": GarminTool.sync_garmin,

    "get_health_insights": AnalyticsTool.get_health_insights,
    "analyze_driver": AnalyticsTool.analyze_driver,
    
    "search_web": WebSearchTool.search_web,
    
    "execute_shell": execute_shell,
    "download_file": download_file,
    "save_file": save_file,
    "get_system_status": get_system_status,
    "kill_process": kill_process,
    "get_process_list": get_process_list
}
