"""
Storybook Configuration Management

Ensures Storybook uses project host settings instead of localhost.
"""

import os
import json
from pathlib import Path
from typing import Dict, Any, Optional
from dss.settings import settings


def get_storybook_host() -> str:
    """
    Get the configured Storybook host.

    Priority:
    1. STORYBOOK_HOST environment variable
    2. STORYBOOK_HOST from settings
    3. SERVER_HOST from settings
    4. Fall back to 0.0.0.0
    """
    return os.getenv("STORYBOOK_HOST") or settings.STORYBOOK_HOST or settings.SERVER_HOST or "0.0.0.0"


def get_storybook_port() -> int:
    """
    Get the configured Storybook port.

    Priority:
    1. STORYBOOK_PORT environment variable
    2. STORYBOOK_PORT from settings
    3. Fall back to 6006
    """
    try:
        return int(os.getenv("STORYBOOK_PORT", settings.STORYBOOK_PORT))
    except (ValueError, AttributeError):
        return 6006


def create_storybook_config(project_path: Path) -> Dict[str, Any]:
    """
    Create Storybook configuration with correct host settings.

    Args:
        project_path: Path to the project directory

    Returns:
        Dictionary with Storybook configuration
    """
    host = get_storybook_host()
    port = get_storybook_port()

    config = {
        "stories": [
            "../src/**/*.stories.@(js|jsx|ts|tsx|mdx)",
            "../components/**/*.stories.@(js|jsx|ts|tsx|mdx)"
        ],
        "addons": [
            "@storybook/addon-links",
            "@storybook/addon-essentials",
            "@storybook/addon-interactions"
        ],
        "framework": {
            "name": "@storybook/react-vite",
            "options": {}
        },
        "core": {
            "builder": "@storybook/builder-vite"
        },
        "viteFinal": {
            "server": {
                "host": host,
                "port": port,
                "strictPort": False,
                "open": settings.STORYBOOK_AUTO_OPEN
            }
        }
    }

    return config


def generate_storybook_start_command(project_path: Path) -> str:
    """
    Generate the Storybook start command with correct host.

    Args:
        project_path: Path to the project directory

    Returns:
        Command string to start Storybook
    """
    host = get_storybook_host()
    port = get_storybook_port()

    # Use npx to ensure we use project's Storybook version
    cmd = f"npx storybook dev -p {port} -h {host}"

    if not settings.STORYBOOK_AUTO_OPEN:
        cmd += " --no-open"

    return cmd


def get_storybook_url(project_path: Optional[Path] = None) -> str:
    """
    Get the Storybook URL based on configuration.

    Args:
        project_path: Optional path to the project directory

    Returns:
        Full URL to access Storybook
    """
    host = get_storybook_host()
    port = get_storybook_port()

    # If host is 0.0.0.0, use the actual server hostname
    if host == "0.0.0.0":
        # Try to get from SERVER_NAME env var or use localhost as fallback for display
        display_host = os.getenv("SERVER_NAME", "localhost")
    else:
        display_host = host

    return f"http://{display_host}:{port}"


def write_storybook_config_file(project_path: Path, config_dir: Path = None) -> Path:
    """
    Write Storybook configuration to project's .storybook directory.

    Args:
        project_path: Path to the project directory
        config_dir: Optional custom config directory (default: .storybook)

    Returns:
        Path to the created config file
    """
    if config_dir is None:
        config_dir = project_path / ".storybook"

    config_dir.mkdir(parents=True, exist_ok=True)

    # Create main.js with proper host configuration
    main_js = config_dir / "main.js"
    config = create_storybook_config(project_path)

    # Convert to JS module format
    js_content = f"""/** @type {{import('@storybook/react-vite').StorybookConfig}} */
const config = {json.dumps(config, indent=2)};

export default config;
"""

    main_js.write_text(js_content)

    # Create preview.js if it doesn't exist
    preview_js = config_dir / "preview.js"
    if not preview_js.exists():
        preview_content = """/** @type {import('@storybook/react').Preview} */
const preview = {
  parameters: {
    actions: { argTypesRegex: '^on[A-Z].*' },
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/,
      },
    },
  },
};

export default preview;
"""
        preview_js.write_text(preview_content)

    return main_js


def get_storybook_status(project_path: Path) -> Dict[str, Any]:
    """
    Get Storybook configuration status for a project.

    Args:
        project_path: Path to the project directory

    Returns:
        Dictionary with Storybook status information
    """
    config_dir = project_path / ".storybook"
    has_config = config_dir.exists() and (config_dir / "main.js").exists()

    # Check if Storybook is installed
    package_json = project_path / "package.json"
    has_storybook = False
    storybook_version = None

    if package_json.exists():
        try:
            pkg = json.loads(package_json.read_text())
            deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}

            for pkg_name in ["@storybook/react", "storybook"]:
                if pkg_name in deps:
                    has_storybook = True
                    storybook_version = deps[pkg_name]
                    break
        except (json.JSONDecodeError, FileNotFoundError):
            pass

    return {
        "configured": has_config,
        "installed": has_storybook,
        "version": storybook_version,
        "config_dir": str(config_dir),
        "url": get_storybook_url(project_path),
        "host": get_storybook_host(),
        "port": get_storybook_port(),
        "start_command": generate_storybook_start_command(project_path)
    }
