"""
DSS Settings and Configuration Management
Includes test utilities and reset functionality
"""

import os
import shutil
import subprocess
from pathlib import Path
from typing import Dict, List, Optional
from pydantic import ConfigDict
from pydantic_settings import BaseSettings


class DSSSettings(BaseSettings):
    """DSS Configuration Settings"""
    model_config = ConfigDict(
        env_file=".env",
        case_sensitive=True,
        extra="ignore"
    )

    # Project paths
    PROJECT_ROOT: Path = Path(__file__).parent.parent
    DSS_DIR: Path = Path(__file__).parent
    TESTS_DIR: Path = PROJECT_ROOT / "tests"
    CACHE_DIR: Path = Path.home() / ".dss" / "cache"

    # API Configuration
    ANTHROPIC_API_KEY: Optional[str] = None
    FIGMA_TOKEN: Optional[str] = None
    FIGMA_FILE_KEY: Optional[str] = None

    # Database
    DATABASE_PATH: Path = Path.home() / ".dss" / "dss.db"

    # Test Configuration
    TEST_DATABASE_PATH: Path = Path.home() / ".dss" / "test.db"
    USE_MOCK_APIS: bool = True

    # Server Configuration
    SERVER_HOST: str = "0.0.0.0"  # Host to bind server to
    SERVER_PORT: int = 3456

    # Storybook Configuration
    STORYBOOK_HOST: str = "0.0.0.0"  # Host for Storybook server (uses SERVER_HOST if not set)
    STORYBOOK_PORT: int = 6006  # Default Storybook port
    STORYBOOK_AUTO_OPEN: bool = False  # Don't auto-open browser


class DSSManager:
    """Management utilities for DSS projects and system health."""

    def __init__(self, settings: Optional[DSSSettings] = None):
        self.settings = settings or DSSSettings()
        self.project_root = self.settings.PROJECT_ROOT
        self.dss_dir = self.settings.DSS_DIR

    def run_tests(
        self,
        test_path: Optional[str] = None,
        verbose: bool = True,
        coverage: bool = False,
        markers: Optional[str] = None
    ) -> subprocess.CompletedProcess:
        """
        Run pytest test suite.

        Args:
            test_path: Specific test path (default: all tests)
            verbose: Show verbose output
            coverage: Generate coverage report
            markers: Filter tests by marker (e.g., "unit", "integration")

        Returns:
            CompletedProcess with test results
        """
        cmd = ["python3", "-m", "pytest"]

        # Add test path
        if test_path:
            cmd.append(test_path)
        else:
            cmd.append("tests/")

        # Add options
        if verbose:
            cmd.append("-v")

        if coverage:
            cmd.extend(["--cov=dss", "--cov-report=term-missing", "--cov-report=html"])

        if markers:
            cmd.extend(["-m", markers])

        print(f"Running tests: {' '.join(cmd)}")
        result = subprocess.run(cmd, cwd=self.project_root, capture_output=True, text=True)

        print(result.stdout)
        if result.stderr:
            print("STDERR:", result.stderr)

        return result

    def run_unit_tests(self) -> subprocess.CompletedProcess:
        """Run only unit tests"""
        return self.run_tests(markers="unit", verbose=True)

    def run_integration_tests(self) -> subprocess.CompletedProcess:
        """Run only integration tests"""
        return self.run_tests(markers="integration", verbose=True)

    def run_all_tests_with_coverage(self) -> subprocess.CompletedProcess:
        """Run all tests with coverage report"""
        return self.run_tests(coverage=True, verbose=True)

    def reset_dss(
        self,
        keep_structure: bool = True,
        confirm: bool = True
    ) -> Dict[str, any]:
        """
        Reset DSS to a fresh state.

        Deletes accumulated data while preserving directory structure.

        Args:
            keep_structure: Preserve directory structure (default: True)
            confirm: Require user confirmation before reset (default: True)

        Returns:
            Dict with reset results (deleted, kept, errors)
        """
        if confirm:
            response = input(
                "WARNING: This will delete all project data (themes, projects, cache).\n"
                "Directory structure will be preserved.\n"
                "Type 'RESET' to confirm: "
            )
            if response != "RESET":
                return {"status": "cancelled", "message": "Reset cancelled"}

        results = {
            "status": "success",
            "deleted": [],
            "kept": [],
            "errors": []
        }

        # Delete user-created themes
        themes_dir = self.dss_dir / "themes"
        if themes_dir.exists():
            for theme_file in themes_dir.glob("*.py"):
                if theme_file.name not in ["__init__.py", "default_themes.py"]:
                    try:
                        theme_file.unlink()
                        results["deleted"].append(str(theme_file))
                    except Exception as e:
                        results["errors"].append(f"Failed to delete theme: {e}")
            results["kept"].append(str(themes_dir / "default_themes.py"))

        # Clear cache directory
        cache_dir = self.settings.CACHE_DIR
        if cache_dir.exists():
            try:
                shutil.rmtree(cache_dir)
                results["deleted"].append(str(cache_dir))
                if keep_structure:
                    cache_dir.mkdir(parents=True, exist_ok=True)
                    results["kept"].append(str(cache_dir) + " (structure preserved)")
            except Exception as e:
                results["errors"].append(f"Failed to clear cache: {e}")

        # Clear Figma cache
        figma_cache = Path.home() / ".dss" / "figma_cache.json"
        if figma_cache.exists():
            try:
                figma_cache.unlink()
                results["deleted"].append(str(figma_cache))
            except Exception as e:
                results["errors"].append(f"Failed to clear Figma cache: {e}")

        # Reset database
        db_path = self.settings.DATABASE_PATH
        if db_path.exists():
            try:
                db_path.unlink()
                results["deleted"].append(str(db_path))
            except Exception as e:
                results["errors"].append(f"Failed to reset database: {e}")

        # Clear test database
        test_db_path = self.settings.TEST_DATABASE_PATH
        if test_db_path.exists():
            try:
                test_db_path.unlink()
                results["deleted"].append(str(test_db_path))
            except Exception as e:
                results["errors"].append(f"Failed to clear test database: {e}")

        # Clear Python cache
        for pycache in self.project_root.rglob("__pycache__"):
            try:
                shutil.rmtree(pycache)
                results["deleted"].append(str(pycache))
            except Exception as e:
                results["errors"].append(f"Failed to clear cache: {e}")

        # Preserve core directories
        structure_dirs = [
            self.dss_dir / "models",
            self.dss_dir / "validators",
            self.dss_dir / "tools",
            self.dss_dir / "themes",
            self.dss_dir / "api",
            self.project_root / "tests" / "fixtures",
            self.project_root / "tests" / "unit",
            self.project_root / "tests" / "integration",
        ]

        for dir_path in structure_dirs:
            if dir_path.exists():
                results["kept"].append(str(dir_path))

        return results

    def get_system_info(self) -> Dict[str, any]:
        """Get comprehensive system information and configuration status."""
        return {
            "project_root": str(self.project_root),
            "dss_dir": str(self.dss_dir),
            "tests_dir": str(self.settings.TESTS_DIR),
            "cache_dir": str(self.settings.CACHE_DIR),
            "database_path": str(self.settings.DATABASE_PATH),
            "has_anthropic_key": bool(self.settings.ANTHROPIC_API_KEY),
            "has_figma_token": bool(self.settings.FIGMA_TOKEN),
            "use_mock_apis": self.settings.USE_MOCK_APIS
        }

    def check_dependencies(self) -> Dict[str, bool]:
        """
        Verify all required dependencies are installed and functional.

        Returns:
            Dict with dependency health status (True=installed, False=missing)
        """
        dependencies = {}

        # Pydantic for data validation
        try:
            import pydantic
            dependencies["pydantic"] = True
        except ImportError:
            dependencies["pydantic"] = False

        # FastAPI for API framework
        try:
            import fastapi
            dependencies["fastapi"] = True
        except ImportError:
            dependencies["fastapi"] = False

        # Pytest for testing
        try:
            import pytest
            dependencies["pytest"] = True
        except ImportError:
            dependencies["pytest"] = False

        # Requests for HTTP operations
        try:
            import requests
            dependencies["requests"] = True
        except ImportError:
            dependencies["requests"] = False

        # Style Dictionary for token transformation
        try:
            result = subprocess.run(
                ["npx", "style-dictionary", "--version"],
                capture_output=True,
                timeout=5
            )
            dependencies["style-dictionary"] = result.returncode == 0
        except Exception:
            dependencies["style-dictionary"] = False

        return dependencies


# Singleton instance
settings = DSSSettings()
manager = DSSManager(settings)


if __name__ == "__main__":
    # DSS Settings Management CLI
    import sys

    if len(sys.argv) < 2:
        print("""
DSS Settings Management

Manage DSS configuration, testing, and system health.

Usage:
  python -m dss.settings <command>

Test Commands:
  test [path]          Run tests (optional: specific test path)
  test-unit            Run unit tests only
  test-integration     Run integration tests only
  test-coverage        Run all tests with coverage report

Management Commands:
  reset                Reset DSS to fresh state
  info                 Display system information and status
  check-deps           Verify all dependencies are installed
        """)
        sys.exit(0)

    command = sys.argv[1]

    if command == "test":
        test_path = sys.argv[2] if len(sys.argv) > 2 else None
        manager.run_tests(test_path)

    elif command == "test-unit":
        manager.run_unit_tests()

    elif command == "test-integration":
        manager.run_integration_tests()

    elif command == "test-coverage":
        manager.run_all_tests_with_coverage()

    elif command == "reset":
        # Check for --no-confirm flag
        no_confirm = "--no-confirm" in sys.argv
        results = manager.reset_dss(confirm=(not no_confirm))
        if results.get("status") != "cancelled":
            print("\nReset complete:")
            print(f"   Deleted: {len(results.get('deleted', []))} items")
            print(f"   Preserved: {len(results.get('kept', []))} items")
            if results.get('errors'):
                print(f"   Errors: {len(results['errors'])} items failed")

    elif command == "info":
        info = manager.get_system_info()
        print("\nSystem Information:")
        print(f"   Project root: {info['project_root']}")
        print(f"   DSS directory: {info['dss_dir']}")
        print(f"   Tests directory: {info['tests_dir']}")
        print(f"   Cache directory: {info['cache_dir']}")
        print(f"   Database path: {info['database_path']}")
        print(f"   Anthropic API: {'Configured' if info['has_anthropic_key'] else 'Not configured'}")
        print(f"   Figma token: {'Configured' if info['has_figma_token'] else 'Not configured'}")
        print(f"   API mode: {'Mock' if info['use_mock_apis'] else 'Live'}")

    elif command == "check-deps":
        deps = manager.check_dependencies()
        print("\nDependency Check:")
        healthy = sum(1 for v in deps.values() if v)
        total = len(deps)
        print(f"   Status: {healthy}/{total} dependencies installed")
        print()
        for dep, installed in deps.items():
            status = "OK" if installed else "MISSING"
            print(f"   {status}: {dep}")
        if healthy < total:
            print("\n   Some dependencies are missing.")
            print("   Run: pip install -r requirements.txt")

    else:
        print(f"\nUnknown command: '{command}'")
        print("Run: python -m dss.settings (without arguments for help)")
        sys.exit(1)
