#!/usr/bin/env python3
"""Phase 3 server-side tests - form logic validation."""
import sys
import os
import json

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.services.form_logic import (
    evaluate_all_conditions,
    validate_submission,
    compute_all_fields,
    evaluate_condition,
)

# Sample field config embedded to avoid DB dependency
SAMPLE_FIELD_CONFIG = {
    "fields": [
        {
            "key": "service",
            "name": "service",
            "type": "select",
            "label": "Service Type",
            "required": True,
            "options": ["Web Development", "SEO Audit", "Logo Design", "Full Package"],
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "budget",
            "name": "budget",
            "type": "number",
            "label": "Budget Range",
            "required": False,
            "condition": {"field": "service", "operator": "eq", "value": "Web Development"},
            "validation": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "timeline",
            "name": "timeline",
            "type": "select",
            "label": "Timeline",
            "required": True,
            "condition": {
                "any": [
                    {"field": "service", "operator": "eq", "value": "Web Development"},
                    {"field": "service", "operator": "eq", "value": "SEO Audit"},
                ]
            },
            "options": ["ASAP", "1-2 weeks", "1 month", "Flexible"],
            "validation": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "logo_style",
            "name": "logo_style",
            "type": "select",
            "label": "Logo Style Preference",
            "required": True,
            "condition": {"field": "service", "operator": "eq", "value": "Logo Design"},
            "options": ["Minimalist", "Vintage", "Modern", "Abstract"],
            "validation": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "priority",
            "name": "priority",
            "type": "select",
            "label": "Priority Level",
            "required": True,
            "conditional_required": {
                "field": "service",
                "operator": "eq",
                "value": "Full Package",
                "message": "Priority is required for Full Package",
            },
            "options": ["Low", "Medium", "High", "Critical"],
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "discount",
            "name": "discount",
            "type": "computed",
            "label": "Discount %",
            "computed_from": "priority",
            "computed_method": "map",
            "computed_map": {"Low": "0", "Medium": "5", "High": "10", "Critical": "15"},
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
            "required": False,
        },
        {
            "key": "rush_fee",
            "name": "rush_fee",
            "type": "computed",
            "label": "Rush Fee",
            "computed_from": "timeline",
            "computed_method": "map",
            "computed_map": {
                "ASAP": "500",
                "1-2 weeks": "100",
                "1 month": "0",
                "Flexible": "0",
            },
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
            "required": False,
        },
        {
            "key": "estimated_total",
            "name": "estimated_total",
            "type": "computed",
            "label": "Estimated Total",
            "computed_method": "expression",
            "computed_expression": "{{budget}} + {{rush_fee}} - ({{budget}} * {{discount}} / 100)",
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
            "required": False,
        },
        {
            "key": "notes",
            "name": "notes",
            "type": "textarea",
            "label": "Additional Notes",
            "required": False,
            "conditional_default": {
                "condition": {
                    "field": "service",
                    "operator": "eq",
                    "value": "Full Package",
                },
                "value": "Full package inquiry - please provide detailed requirements.",
            },
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
        },
        {
            "key": "contact",
            "name": "contact",
            "type": "select",
            "label": "Preferred Contact Method",
            "required": False,
            "options": ["Email", "Phone", "Video Call"],
            "conditional_required": {
                "field": "service",
                "operator": "eq",
                "value": "Web Development",
            },
            "validation": None,
            "condition": None,
            "calculation": None,
            "step": 1,
        },
    ]
}


class TestFormLogic:
    """Test form logic evaluation."""

    def test_simple_condition(self):
        """Test 1: Simple condition (budget visible for Web Dev)."""
        result = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Web Development"})
        assert result["budget"]["visible"] is True

    def test_any_group_condition(self):
        """Test 2: ANY group (timeline visible for SEO, budget hidden)."""
        result = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "SEO Audit"})
        assert result["timeline"]["visible"] is True
        assert result["budget"]["visible"] is False

    def test_all_group_condition(self):
        """Test 3: ALL group via manual construct."""
        test_field_all = {
            "key": "test",
            "condition": {
                "all": [
                    {"field": "service", "operator": "eq", "value": "Web Development"},
                    {"field": "timeline", "operator": "eq", "value": "1-2 weeks"},
                ]
            },
        }
        assert (
            evaluate_condition(
                test_field_all, {"service": "Web Development", "timeline": "1-2 weeks"}
            )
            is True
        )
        assert (
            evaluate_condition(
                test_field_all, {"service": "Web Development", "timeline": "ASAP"}
            )
            is False
        )
        assert (
            evaluate_condition(
                test_field_all, {"service": "SEO Audit", "timeline": "1-2 weeks"}
            )
            is False
        )

    def test_conditional_required(self):
        """Test 4: Conditional required."""
        result = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Full Package"})
        assert result["priority"]["required"] is True

        result3 = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Web Development"})
        assert result3["contact"]["required"] is True

        result4 = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "SEO Audit"})
        assert result4["contact"]["required"] is False

    def test_computed_field_map(self):
        """Test 5: Computed field - map (discount from priority)."""
        fields = SAMPLE_FIELD_CONFIG["fields"]
        result = compute_all_fields(fields, {"priority": "High"})
        assert result["discount"] == 10

    def test_computed_field_expression(self):
        """Test 6: Computed field - expression."""
        fields = SAMPLE_FIELD_CONFIG["fields"]
        result = compute_all_fields(fields, {"priority": "High", "timeline": "ASAP", "budget": "10000"})
        assert result["rush_fee"] == 500
        assert result["estimated_total"] == 10000 + 500 - (10000 * 10 / 100)  # 9500

    def test_conditional_default(self):
        """Test 7: Conditional default (notes for Full Package)."""
        result = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Full Package"})
        assert "Full package" in result["notes"]["default"]

        result2 = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Web Development"})
        assert result2["notes"]["default"] == ""

    def test_conditional_validation(self):
        """Test 8: Conditional validation (contact required for Web Dev)."""
        errors = validate_submission(
            SAMPLE_FIELD_CONFIG, {"service": "Web Development", "contact": "", "priority": "Medium"}
        )
        assert len(errors) > 0
        assert any(e["field"] == "contact" for e in errors)

        errors2 = validate_submission(
            SAMPLE_FIELD_CONFIG,
            {"service": "Logo Design", "contact": "", "priority": "Medium", "logo_style": "Minimalist"},
        )
        assert len(errors2) == 0

    def test_multi_field_computation(self):
        """Test 9: Multi-field computation."""
        fields = SAMPLE_FIELD_CONFIG["fields"]
        computed = compute_all_fields(
            fields, {"priority": "High", "timeline": "ASAP", "budget": "10000"}
        )
        assert computed["rush_fee"] == 500
        assert computed["discount"] == 10

    def test_backward_compat_formula(self):
        """Test 10: Backward compatibility (legacy calculation.formula)."""
        legacy_field = {
            "key": "test_total",
            "type": "computed",
            "label": "Total",
            "calculation": {"formula": "{{price}} x {{qty}}"},
        }
        legacy_result = compute_all_fields([legacy_field], {"price": "100", "qty": "5"})
        assert legacy_result["test_total"] == "100 x 5"

    def test_cascade_independent_visibility(self):
        """Test 11: Cascade - hidden dependency."""
        result = evaluate_all_conditions(SAMPLE_FIELD_CONFIG, {"service": "Logo Design"})
        assert result["timeline"]["visible"] is False
        assert result["logo_style"]["visible"] is True

    def test_cascade_hidden_dependency_chains(self):
        """Test 12: Cascade - field that DOES depend on hidden field."""
        all_result = evaluate_all_conditions(
            SAMPLE_FIELD_CONFIG, {"service": "Logo Design", "budget": "5000"}
        )
        assert all_result["budget"]["visible"] is False
