"""
Atomizer Study Insights Module

Provides physics-focused visualizations for FEA optimization results.
Unlike the Analysis page (optimizer-centric), Insights show the engineering
reality of specific designs through interactive 3D visualizations.

Architecture:
- StudyInsight: Abstract base class for all insight types
- InsightRegistry: Central registry for available insight types
- InsightSpec: Config-driven insight specification (from optimization_config.json)
- InsightReport: Aggregates insights into HTML/PDF report with appendix
- Each insight generates standalone HTML or Plotly data for dashboard

Available Insight Types:
-----------------------
| Type ID          | Name                   | Description                              |
|------------------|------------------------|------------------------------------------|
| zernike_dashboard| Zernike Dashboard      | RECOMMENDED: Unified WFE dashboard       |
| zernike_wfe      | Zernike WFE Analysis   | 3D wavefront error with Zernike decomp   |
| msf_zernike      | MSF Zernike Analysis   | Mid-spatial frequency band decomposition |
| stress_field     | Stress Distribution    | Von Mises stress contours                |
| modal            | Modal Analysis         | Natural frequencies and mode shapes      |
| thermal          | Thermal Analysis       | Temperature distribution                 |
| design_space     | Design Space Explorer  | Parameter-objective relationships        |

Config Schema (in optimization_config.json):
-------------------------------------------
```json
"insights": [
    {
        "type": "zernike_wfe",
        "name": "WFE at 40 vs 20 deg",
        "enabled": true,
        "linked_objective": "rel_filtered_rms_40_vs_20",
        "config": { "target_subcase": "3", "reference_subcase": "2" },
        "include_in_report": true
    }
]
```

Quick Start:
-----------
```python
from optimization_engine.insights import (
    get_insight, list_available_insights,
    get_configured_insights, recommend_insights_for_study, InsightReport
)
from pathlib import Path

study_path = Path("studies/my_study")

# Get recommended insights based on objectives
recommendations = recommend_insights_for_study(study_path)
for rec in recommendations:
    print(f"{rec['type']}: {rec['reason']}")

# Generate report from configured insights
report = InsightReport(study_path)
results = report.generate_all()  # Uses specs from optimization_config.json
report_path = report.generate_report_html()  # Creates STUDY_INSIGHTS_REPORT.html
```

CLI Usage:
---------
```bash
# Generate all available insights for a study
python -m optimization_engine.insights generate studies/my_study

# Generate specific insight type
python -m optimization_engine.insights generate studies/my_study --type zernike_wfe

# Generate full report from config
python -m optimization_engine.insights report studies/my_study

# Get recommendations for a study
python -m optimization_engine.insights recommend studies/my_study

# List available insight types
python -m optimization_engine.insights list
```
"""

# Import base classes first
from .base import (
    StudyInsight,
    InsightConfig,
    InsightResult,
    InsightSpec,
    InsightReport,
    InsightRegistry,
    register_insight,
    get_insight,
    list_insights,
    list_available_insights,
    get_configured_insights,
    recommend_insights_for_study,
)

# Import insight implementations (triggers @register_insight decorators)
from .zernike_wfe import ZernikeWFEInsight
from .zernike_opd_comparison import ZernikeOPDComparisonInsight
from .msf_zernike import MSFZernikeInsight
from .zernike_dashboard import ZernikeDashboardInsight  # NEW: Unified dashboard
from .stress_field import StressFieldInsight
from .modal_analysis import ModalInsight
from .thermal_field import ThermalInsight
from .design_space import DesignSpaceInsight

# Public API
__all__ = [
    # Base classes
    'StudyInsight',
    'InsightConfig',
    'InsightResult',
    'InsightSpec',
    'InsightReport',
    'InsightRegistry',
    'register_insight',

    # API functions
    'get_insight',
    'list_insights',
    'list_available_insights',
    'get_configured_insights',
    'recommend_insights_for_study',

    # Insight implementations
    'ZernikeWFEInsight',
    'ZernikeOPDComparisonInsight',
    'MSFZernikeInsight',
    'ZernikeDashboardInsight',  # NEW: Unified dashboard
    'StressFieldInsight',
    'ModalInsight',
    'ThermalInsight',
    'DesignSpaceInsight',
]


def generate_all_insights(study_path, output_dir=None):
    """
    Generate all available insights for a study.

    Args:
        study_path: Path to study directory
        output_dir: Optional output directory (defaults to study/3_insights/)

    Returns:
        List of InsightResult objects
    """
    from pathlib import Path
    study_path = Path(study_path)

    results = []
    available = list_available_insights(study_path)

    for info in available:
        insight = get_insight(info['type'], study_path)
        if insight:
            config = InsightConfig()
            if output_dir:
                config.output_dir = Path(output_dir)

            result = insight.generate(config)
            results.append({
                'type': info['type'],
                'name': info['name'],
                'result': result
            })

    return results


# CLI entry point
if __name__ == '__main__':
    import sys
    from pathlib import Path

    def print_usage():
        print("Atomizer Study Insights")
        print("=" * 50)
        print()
        print("Usage:")
        print("  python -m optimization_engine.insights list")
        print("  python -m optimization_engine.insights generate <study_path> [--type TYPE]")
        print("  python -m optimization_engine.insights report <study_path>")
        print("  python -m optimization_engine.insights recommend <study_path>")
        print()
        print("Commands:")
        print("  list      - List all registered insight types")
        print("  generate  - Generate insights for a study")
        print("  report    - Generate full report from config")
        print("  recommend - Get AI recommendations for insights")
        print()
        print("Options:")
        print("  --type TYPE  Generate only the specified insight type")
        print()

    if len(sys.argv) < 2:
        print_usage()
        sys.exit(0)

    command = sys.argv[1]

    if command == 'list':
        print("\nRegistered Insight Types:")
        print("-" * 60)
        for info in list_insights():
            print(f"  {info['type']:15} - {info['name']}")
            print(f"                    {info['description']}")
            print(f"                    Applies to: {', '.join(info['applicable_to'])}")
            print()

    elif command == 'recommend':
        if len(sys.argv) < 3:
            print("Error: Missing study path")
            print_usage()
            sys.exit(1)

        study_path = Path(sys.argv[2])
        if not study_path.exists():
            print(f"Error: Study path does not exist: {study_path}")
            sys.exit(1)

        print(f"\nRecommended Insights for: {study_path.name}")
        print("-" * 60)

        recommendations = recommend_insights_for_study(study_path)
        if not recommendations:
            print("No recommendations available (no objectives found)")
            sys.exit(0)

        for rec in recommendations:
            linked = f" -> {rec['linked_objective']}" if rec.get('linked_objective') else ""
            print(f"\n  {rec['type']}{linked}")
            print(f"    Name: {rec['name']}")
            print(f"    Reason: {rec['reason']}")

        print()
        print("Add these to optimization_config.json under 'insights' key")

    elif command == 'report':
        if len(sys.argv) < 3:
            print("Error: Missing study path")
            print_usage()
            sys.exit(1)

        study_path = Path(sys.argv[2])
        if not study_path.exists():
            print(f"Error: Study path does not exist: {study_path}")
            sys.exit(1)

        print(f"\nGenerating Insight Report for: {study_path.name}")
        print("-" * 60)

        # Check for configured insights
        specs = get_configured_insights(study_path)
        if not specs:
            print("No insights configured in optimization_config.json")
            print("Using recommendations based on objectives...")
            recommendations = recommend_insights_for_study(study_path)
            specs = [
                InsightSpec(
                    type=rec['type'],
                    name=rec['name'],
                    linked_objective=rec.get('linked_objective'),
                    config=rec.get('config', {})
                )
                for rec in recommendations
            ]

        if not specs:
            print("No insights to generate")
            sys.exit(0)

        print(f"Generating {len(specs)} insight(s)...")

        report = InsightReport(study_path)
        results = report.generate_all(specs)

        for result in results:
            status = "OK" if result.success else f"FAIL: {result.error}"
            print(f"  {result.insight_name}: {status}")

        if any(r.success for r in results):
            report_path = report.generate_report_html()
            print(f"\nReport generated: {report_path}")
            print("Open in browser and use 'Save as PDF' button to export")
        else:
            print("\nNo insights generated successfully")

    elif command == 'generate':
        if len(sys.argv) < 3:
            print("Error: Missing study path")
            print_usage()
            sys.exit(1)

        study_path = Path(sys.argv[2])
        if not study_path.exists():
            print(f"Error: Study path does not exist: {study_path}")
            sys.exit(1)

        # Parse options
        insight_type = None
        for i, arg in enumerate(sys.argv[3:], 3):
            if arg == '--type' and i + 1 < len(sys.argv):
                insight_type = sys.argv[i + 1]

        print(f"\nGenerating insights for: {study_path}")
        print("-" * 60)

        if insight_type:
            # Generate specific type
            insight = get_insight(insight_type, study_path)
            if insight is None:
                print(f"Error: Unknown insight type: {insight_type}")
                sys.exit(1)

            if not insight.can_generate():
                print(f"Cannot generate {insight_type}: required data not found")
                sys.exit(1)

            result = insight.generate()
            if result.success:
                print(f"Generated: {result.html_path}")
                if result.summary:
                    print(f"Summary: {result.summary}")
            else:
                print(f"Error: {result.error}")
        else:
            # Generate all available
            available = list_available_insights(study_path)
            if not available:
                print("No insights available for this study")
                sys.exit(0)

            print(f"Found {len(available)} available insight(s)")
            print()

            for info in available:
                print(f"Generating {info['name']}...")
                insight = get_insight(info['type'], study_path)
                result = insight.generate()

                if result.success:
                    print(f"  Created: {result.html_path}")
                else:
                    print(f"  Error: {result.error}")

        print()
        print("Done!")

    else:
        print(f"Unknown command: {command}")
        print_usage()
        sys.exit(1)
