#!/usr/bin/env python3
"""
DSS Storybook Reminder Hook
Reminds developers to update Storybook stories when components change.
Written from scratch for DSS.
"""

import json
import os
import re
import sys
from pathlib import Path

def get_config():
    """Load hook configuration."""
    config_path = Path.home() / ".dss" / "hooks-config.json"
    default_config = {
        "storybook_reminder": {
            "enabled": True,
            "component_patterns": ["**/components/**/*.tsx", "**/ui/**/*.tsx"],
            "story_extensions": [".stories.tsx", ".stories.jsx", ".stories.ts", ".stories.js"],
            "remind_on_new": True,
            "remind_on_props_change": True
        }
    }
    
    if config_path.exists():
        try:
            with open(config_path) as f:
                user_config = json.load(f)
                return {**default_config, **user_config}
        except:
            pass
    return default_config

def is_component_file(file_path: str) -> bool:
    """Check if file is a React component."""
    path = Path(file_path)
    
    # Must be a tsx/jsx file
    if path.suffix.lower() not in [".tsx", ".jsx"]:
        return False
    
    # Skip story files, test files, index files
    name = path.stem.lower()
    if any(x in name for x in [".stories", ".story", ".test", ".spec", "index"]):
        return False
    
    # Check if in component-like directory
    parts = str(path).lower()
    component_dirs = ["components", "ui", "atoms", "molecules", "organisms", "templates"]
    return any(d in parts for d in component_dirs)

def find_story_file(component_path: str) -> tuple:
    """Find corresponding story file for a component."""
    path = Path(component_path)
    base_name = path.stem
    parent = path.parent
    
    story_extensions = [".stories.tsx", ".stories.jsx", ".stories.ts", ".stories.js"]
    
    # Check same directory
    for ext in story_extensions:
        story_path = parent / f"{base_name}{ext}"
        if story_path.exists():
            return (True, str(story_path))
    
    # Check __stories__ subdirectory
    stories_dir = parent / "__stories__"
    if stories_dir.exists():
        for ext in story_extensions:
            story_path = stories_dir / f"{base_name}{ext}"
            if story_path.exists():
                return (True, str(story_path))
    
    # Check stories subdirectory
    stories_dir = parent / "stories"
    if stories_dir.exists():
        for ext in story_extensions:
            story_path = stories_dir / f"{base_name}{ext}"
            if story_path.exists():
                return (True, str(story_path))
    
    return (False, None)

def detect_props_change(content: str) -> bool:
    """Detect if content includes prop changes."""
    prop_patterns = [
        r"interface\s+\w+Props",
        r"type\s+\w+Props\s*=",
        r"Props\s*=\s*\{",
        r"defaultProps\s*=",
        r"propTypes\s*="
    ]
    
    for pattern in prop_patterns:
        if re.search(pattern, content):
            return True
    return False

def format_reminder(file_path: str, has_story: bool, story_path: str, props_changed: bool) -> str:
    """Format the reminder message."""
    lines = [f"\n=== DSS Storybook Reminder ===\n"]
    
    component_name = Path(file_path).stem
    
    if not has_story:
        lines.append(f"[NEW] Component '{component_name}' has no Storybook story!")
        lines.append(f"    Consider creating: {component_name}.stories.tsx")
        lines.append("")
        lines.append("    Quick template:")
        lines.append(f"    import {{ {component_name} }} from './{component_name}';")
        lines.append(f"    export default {{ title: 'Components/{component_name}' }};")
        lines.append(f"    export const Default = () => <{component_name} />;")
    elif props_changed:
        lines.append(f"[UPDATE] Props changed in '{component_name}'")
        lines.append(f"    Story file: {story_path}")
        lines.append("    Consider updating stories to reflect new props.")
    
    lines.append("")
    lines.append("=" * 40)
    return "\n".join(lines)

def main():
    """Main hook entry point."""
    config = get_config()
    
    if not config.get("storybook_reminder", {}).get("enabled", True):
        sys.exit(0)
    
    # Read hook input from stdin
    try:
        input_data = json.loads(sys.stdin.read())
    except json.JSONDecodeError:
        sys.exit(0)
    
    tool_name = input_data.get("tool_name", "")
    tool_input = input_data.get("tool_input", {})
    
    if tool_name not in ["Edit", "Write"]:
        sys.exit(0)
    
    file_path = tool_input.get("file_path", "")
    
    # Only check component files
    if not is_component_file(file_path):
        sys.exit(0)
    
    # Get content
    if tool_name == "Write":
        content = tool_input.get("content", "")
    elif tool_name == "Edit":
        content = tool_input.get("new_string", "")
    else:
        content = ""
    
    # Check for story file
    has_story, story_path = find_story_file(file_path)
    
    # Check for props changes
    props_changed = detect_props_change(content) if content else False
    
    reminder_config = config.get("storybook_reminder", {})
    
    # Determine if we should show reminder
    should_remind = False
    if not has_story and reminder_config.get("remind_on_new", True):
        should_remind = True
    elif has_story and props_changed and reminder_config.get("remind_on_props_change", True):
        should_remind = True
    
    if should_remind:
        output = format_reminder(file_path, has_story, story_path, props_changed)
        print(output, file=sys.stderr)
    
    sys.exit(0)

if __name__ == "__main__":
    main()
