"""
Test Condition Parsing - Alle Formate und Verschachtelungen

Testet ob Pydantic die verschiedenen Condition-Formate korrekt deserialisiert.
"""
import sys
import os

# Force UTF-8 encoding on Windows
if sys.platform == 'win32':
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

sys.path.insert(0, 'backend')

from workflow_models import LogicExpression, Condition, WorkflowNode, LogicOperator
from pydantic import ValidationError
import json

def test_case(name, data, expected_type, should_fail=False):
    """Test a single condition format"""
    print(f"\n{'='*60}")
    print(f"TEST: {name}")
    print(f"{'='*60}")
    print(f"Input: {json.dumps(data, indent=2)}")

    try:
        # Test 1: Direct deserialization
        if expected_type == LogicExpression:
            result = LogicExpression(**data)
        elif expected_type == Condition:
            result = Condition(**data)

        if should_fail:
            print("❌ FAILED: Should have raised ValidationError but didn't")
            return False

        print(f"✅ PASSED: Deserialized as {type(result).__name__}")
        print(f"Result: {result.model_dump()}")

        # Test 2: As part of WorkflowNode
        node_data = {
            "id": "test_node",
            "type": "logic",
            "condition": data
        }
        node = WorkflowNode(**node_data)
        print(f"✅ PASSED: WorkflowNode.condition type: {type(node.condition).__name__}")

        return True

    except ValidationError as e:
        if should_fail:
            print(f"✅ PASSED: Correctly raised ValidationError")
            return True
        else:
            print(f"❌ FAILED: {e}")
            return False
    except Exception as e:
        print(f"❌ FAILED: Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return False


# ============================================================================
# Test Cases
# ============================================================================

test_results = []

# Test 1: Simple comparison (UI format - einfachster Fall)
test_results.append(test_case(
    "Simple comparison (eq)",
    {
        "operator": "eq",
        "ref": "node_1.q1",
        "value": "ja"
    },
    LogicExpression
))

# Test 2: Simple AND (UI format - wie im Workflow)
test_results.append(test_case(
    "Simple AND with 2 operands",
    {
        "operator": "and",
        "operands": [
            {"operator": "eq", "ref": "node_5.qTiefananalyseRecovery", "value": "ja"},
            {"operator": "neq", "ref": "node_6.qKonsistenz", "value": "nein"}
        ]
    },
    LogicExpression
))

# Test 3: Simple OR
test_results.append(test_case(
    "Simple OR with 3 operands",
    {
        "operator": "or",
        "operands": [
            {"operator": "eq", "ref": "node_1.q1", "value": "ja"},
            {"operator": "eq", "ref": "node_1.q2", "value": "nein"},
            {"operator": "eq", "ref": "node_1.q3", "value": "unklar"}
        ]
    },
    LogicExpression
))

# Test 4: Nested AND/OR
test_results.append(test_case(
    "Nested: OR with nested AND",
    {
        "operator": "or",
        "operands": [
            {
                "operator": "and",
                "operands": [
                    {"operator": "eq", "ref": "node_1.q1", "value": "ja"},
                    {"operator": "neq", "ref": "node_1.q2", "value": "nein"}
                ]
            },
            {"operator": "eq", "ref": "node_2.q1", "value": "hoch"}
        ]
    },
    LogicExpression
))

# Test 5: Deep nesting (3 levels)
test_results.append(test_case(
    "Deep nesting (3 levels)",
    {
        "operator": "and",
        "operands": [
            {
                "operator": "or",
                "operands": [
                    {"operator": "eq", "ref": "node_1.q1", "value": "ja"},
                    {
                        "operator": "and",
                        "operands": [
                            {"operator": "eq", "ref": "node_2.q1", "value": "hoch"},
                            {"operator": "neq", "ref": "node_2.q2", "value": "niedrig"}
                        ]
                    }
                ]
            },
            {"operator": "eq", "ref": "node_3.q1", "value": "aktiv"}
        ]
    },
    LogicExpression
))

# Test 6: Different operators
test_results.append(test_case(
    "Different comparison operators (gt, lt, in)",
    {
        "operator": "and",
        "operands": [
            {"operator": "gt", "ref": "node_1.score", "value": 50},
            {"operator": "lt", "ref": "node_1.score", "value": 100},
            {"operator": "in", "ref": "node_1.category", "value": ["high", "medium"]}
        ]
    },
    LogicExpression
))

# Test 7: Legacy format (wrapped in Condition)
test_results.append(test_case(
    "Legacy format: Condition with expression",
    {
        "type": "if",
        "expression": {
            "operator": "eq",
            "ref": "node_1.q1",
            "value": "ja"
        },
        "then_path": "edge_1",
        "else_path": "edge_2"
    },
    Condition
))

# Test 8: NOT operator
test_results.append(test_case(
    "NOT operator",
    {
        "operator": "not",
        "operands": [
            {"operator": "eq", "ref": "node_1.q1", "value": "nein"}
        ]
    },
    LogicExpression
))

# Test 9: Complex real-world scenario
test_results.append(test_case(
    "Complex real-world: Multiple nested conditions",
    {
        "operator": "and",
        "operands": [
            {
                "operator": "or",
                "operands": [
                    {"operator": "eq", "ref": "node_1.relevance", "value": "high"},
                    {
                        "operator": "and",
                        "operands": [
                            {"operator": "eq", "ref": "node_1.relevance", "value": "medium"},
                            {"operator": "gt", "ref": "node_1.priority", "value": 5}
                        ]
                    }
                ]
            },
            {"operator": "neq", "ref": "node_2.status", "value": "blocked"},
            {
                "operator": "in",
                "ref": "node_3.category",
                "value": ["training", "nutrition", "recovery"]
            }
        ]
    },
    LogicExpression
))

# ============================================================================
# Results Summary
# ============================================================================

print("\n" + "="*60)
print("TEST RESULTS SUMMARY")
print("="*60)

passed = sum(test_results)
total = len(test_results)
failed = total - passed

print(f"\n✅ Passed: {passed}/{total}")
if failed > 0:
    print(f"❌ Failed: {failed}/{total}")
    print(f"\n⚠️  CRITICAL: Some tests failed! Do NOT deploy until fixed.")
    sys.exit(1)
else:
    print(f"\n🎉 All tests passed! Safe to deploy.")
    sys.exit(0)
