"""
Test for Issue #65: Template Engine Foundation - Integration Tests

This test module validates complete template engine integration scenarios
for business document generation, implementing TDD8 Cycle 3.

Tests focus on:
- Real business document template rendering (invoices, reports)
- End-to-end template processing workflows
- Performance with realistic data volumes
- Integration with MarkdownMatters metadata structure
"""

import pytest
from typing import Dict, Any


class TestTemplateEngineIntegration:
    """Test suite for template engine integration scenarios."""

    def setup_method(self):
        """Set up test environment for each test."""
        try:
            from markitect.template.engine import TemplateEngine
            self.engine = TemplateEngine()
        except ImportError:
            self.engine = None

    def test_render_complete_invoice_template(self):
        """Test rendering a complete business invoice template.

        Reference: Issue #65 - Template Engine Foundation
        TDD Phase: Integration test for business use case
        """
        # Arrange - Complete invoice template from examples/invoice_template.md
        invoice_template = """---
title: "Invoice {{invoice_number}}"
date: "{{date}}"
due_date: "{{due_date}}"
customer_id: "{{customer.id}}"
---

{{company.name}}
{{company.address}}
{{company.city}}, {{company.state}} {{company.zip}}
{{company.email}} | {{company.phone}}

# Invoice {{invoice_number}}

**Bill To:**
{{customer.name}}
{{customer.address}}
{{customer.city}}, {{customer.state}} {{customer.zip}}

**Invoice Date:** {{date}}
**Due Date:** {{due_date}}
**Customer ID:** {{customer.id}}

## Summary

**Subtotal:** {{subtotal}}
**Tax ({{tax_rate}}%):** {{tax_amount}}
**Total:** {{total}} {{currency}}

## Payment Information
Please remit payment to {{company.name}} within {{payment_terms}} days.

---
{{!contentmatter}}
invoice_number: "{{invoice_number}}"
customer: "{{customer.name}}"
total_amount: {{total}}
currency: "{{currency}}"
status: "generated"
{{!/contentmatter}}
"""

        # Test data representing realistic invoice data
        invoice_data = {
            "invoice_number": "INV-2025-001",
            "date": "2025-01-15",
            "due_date": "2025-02-14",
            "company": {
                "name": "MarkiTect Solutions",
                "address": "123 Business Park",
                "city": "Tech City",
                "state": "CA",
                "zip": "90210",
                "email": "billing@markitect.com",
                "phone": "(555) 123-4567"
            },
            "customer": {
                "id": "CUST-001",
                "name": "Acme Corporation",
                "address": "456 Industry Blvd",
                "city": "Enterprise",
                "state": "NY",
                "zip": "10001"
            },
            "subtotal": 1500.00,
            "tax_rate": 8.5,
            "tax_amount": 127.50,
            "total": 1627.50,
            "currency": "USD",
            "payment_terms": "30"
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet - TDD integration phase")

        result = self.engine.render(invoice_template, invoice_data)

        # Verify critical invoice elements are rendered correctly
        assert "Invoice INV-2025-001" in result
        assert "MarkiTect Solutions" in result
        assert "Acme Corporation" in result
        assert "123 Business Park" in result
        assert "Tech City, CA 90210" in result
        assert "Invoice Date:** 2025-01-15" in result
        assert "Due Date:** 2025-02-14" in result
        assert "Customer ID:** CUST-001" in result
        assert "**Total:** 1627.5 USD" in result
        assert "Tax (8.5%):** 127.5" in result
        assert "within 30 days" in result

        # Verify frontmatter is rendered
        assert 'title: "Invoice INV-2025-001"' in result
        assert 'customer_id: "CUST-001"' in result

        # Verify contentmatter placeholders are rendered
        assert 'invoice_number: "INV-2025-001"' in result
        assert 'customer: "Acme Corporation"' in result
        assert 'total_amount: 1627.5' in result

    def test_render_business_report_template(self):
        """Test rendering a business report template with calculations.

        Reference: Issue #65 - Template Engine Foundation
        """
        # Arrange
        report_template = """---
title: "{{report_type}} Report - {{period}}"
generated: "{{generated_date}}"
department: "{{department.name}}"
---

# {{report_type}} Report
**Period:** {{period}}
**Department:** {{department.name}}
**Generated:** {{generated_date}}

## Summary
- Total Revenue: {{metrics.revenue}} {{currency}}
- Total Expenses: {{metrics.expenses}} {{currency}}
- Net Profit: {{metrics.profit}} {{currency}}
- Profit Margin: {{metrics.profit_margin}}%

## Department Performance
**Manager:** {{department.manager}}
**Team Size:** {{department.team_size}}
**Budget Utilization:** {{department.budget_utilization}}%

Contact: {{department.contact.email}}
"""

        report_data = {
            "report_type": "Monthly Financial",
            "period": "January 2025",
            "generated_date": "2025-02-01",
            "currency": "USD",
            "department": {
                "name": "Sales",
                "manager": "Sarah Johnson",
                "team_size": 12,
                "budget_utilization": 85.5,
                "contact": {
                    "email": "sales@company.com"
                }
            },
            "metrics": {
                "revenue": 125000.00,
                "expenses": 87500.00,
                "profit": 37500.00,
                "profit_margin": 30.0
            }
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet")

        result = self.engine.render(report_template, report_data)

        # Verify report structure and data
        assert "Monthly Financial Report" in result
        assert "Period:** January 2025" in result
        assert "Department:** Sales" in result
        assert "Total Revenue: 125000.0 USD" in result
        assert "Net Profit: 37500.0 USD" in result
        assert "Profit Margin: 30.0%" in result
        assert "Manager:** Sarah Johnson" in result
        assert "Budget Utilization:** 85.5%" in result
        assert "sales@company.com" in result

    def test_error_handling_missing_nested_data(self):
        """Test comprehensive error handling with detailed context.

        Reference: Issue #65 - Template Engine Foundation
        """
        # Arrange
        template = "Customer: {{customer.profile.details.name}}, Order: {{order.items.first.description}}"
        incomplete_data = {
            "customer": {
                "profile": {
                    # Missing 'details' key
                }
            },
            "order": {
                # Missing 'items' key
                "id": "ORD-001"
            }
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet")

        # Test strict mode error with context
        with pytest.raises(Exception) as exc_info:
            self.engine.render(template, incomplete_data, strict=True)

        error_message = str(exc_info.value)
        # Should provide helpful context about what was available
        assert ("details" in error_message.lower() or
                "customer.profile.details.name" in error_message)

        # Test lenient mode preserves placeholders
        result = self.engine.render(template, incomplete_data, strict=False)
        assert "{{customer.profile.details.name}}" in result
        assert "{{order.items.first.description}}" in result

    def test_performance_large_business_document(self):
        """Test performance with realistic large business document.

        Reference: Issue #65 - Performance Requirements
        """
        # Arrange - Large template with many variables
        large_template = """# Annual Report {{year}}

## Executive Summary
Company: {{company.name}}
CEO: {{company.ceo}}
Revenue: {{financials.revenue}} {{currency}}

## Department Reports
"""

        # Add many department sections
        for i in range(50):
            dept_prefix = f"departments.dept_{i}"
            large_template += f"""
### Department {{{{{dept_prefix}.name}}}}
Manager: {{{{{dept_prefix}.manager}}}}
Budget: {{{{{dept_prefix}.budget}}}} {{{{currency}}}}
Team Size: {{{{{dept_prefix}.team_size}}}}
"""

        # Generate corresponding data
        departments_data = {}
        for i in range(50):
            departments_data[f"dept_{i}"] = {
                "name": f"Department {i+1}",
                "manager": f"Manager {i+1}",
                "budget": (i+1) * 10000,
                "team_size": (i % 20) + 5
            }

        large_data = {
            "year": "2025",
            "currency": "USD",
            "company": {
                "name": "Enterprise Corp",
                "ceo": "John CEO"
            },
            "financials": {
                "revenue": 50000000
            },
            "departments": departments_data
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet")

        import time
        start_time = time.time()
        result = self.engine.render(large_template, large_data)
        render_time = time.time() - start_time

        # Performance requirement: <100ms for large documents
        assert render_time < 0.1

        # Verify content was rendered
        assert "Annual Report 2025" in result
        assert "Enterprise Corp" in result
        assert "50000000 USD" in result
        assert "Department 1" in result
        assert "Department 50" in result

    def test_markdown_structure_preservation(self):
        """Test that complex markdown structure is preserved during rendering.

        Reference: Issue #65 - Template Engine Foundation
        """
        # Arrange - Complex markdown with various elements
        complex_template = """---
title: "{{document.title}}"
author: "{{document.author}}"
---

# {{document.title}}

## Table of Contents
- [Introduction](#introduction)
- [Analysis](#analysis-{{section.id}})
- [Conclusion](#conclusion)

## Introduction

Welcome to **{{document.title}}** by *{{document.author}}*.

> This document provides {{description.type}} analysis for {{client.name}}.

### Code Example
```python
def process_{{operation.name}}():
    return "{{operation.result}}"
```

## Analysis {{section.id}}

| Metric | Value | Target |
|--------|-------|--------|
| {{metrics.primary.name}} | {{metrics.primary.value}} | {{metrics.primary.target}} |
| {{metrics.secondary.name}} | {{metrics.secondary.value}} | {{metrics.secondary.target}} |

### Subsection
1. First point about {{analysis.point1}}
2. Second point about {{analysis.point2}}
3. Third point with [link]({{external.url}})

---

*Generated on {{generation.date}} by {{generation.system}}*
"""

        template_data = {
            "document": {
                "title": "Business Analysis Report",
                "author": "Analytics Team"
            },
            "description": {
                "type": "comprehensive"
            },
            "client": {
                "name": "Global Enterprises"
            },
            "section": {
                "id": "Q1-2025"
            },
            "operation": {
                "name": "quarterly_analysis",
                "result": "success"
            },
            "metrics": {
                "primary": {
                    "name": "Revenue",
                    "value": "$125K",
                    "target": "$120K"
                },
                "secondary": {
                    "name": "Growth",
                    "value": "12%",
                    "target": "10%"
                }
            },
            "analysis": {
                "point1": "market expansion",
                "point2": "customer acquisition"
            },
            "external": {
                "url": "https://example.com/data"
            },
            "generation": {
                "date": "2025-01-15",
                "system": "MarkiTect"
            }
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet")

        result = self.engine.render(complex_template, template_data)

        # Verify markdown structure preservation
        assert "---" in result  # Frontmatter
        assert "# Business Analysis Report" in result  # H1
        assert "## Table of Contents" in result  # H2
        assert "- [Introduction](#introduction)" in result  # List
        assert "> This document provides" in result  # Blockquote
        assert "```python" in result  # Code block
        assert "def process_quarterly_analysis():" in result  # Rendered in code
        assert "| Revenue | $125K | $120K |" in result  # Table
        assert "1. First point about market expansion" in result  # Numbered list
        assert "[link](https://example.com/data)" in result  # Link
        assert "*Generated on 2025-01-15 by MarkiTect*" in result  # Emphasis

        # Verify frontmatter variables were rendered
        assert 'title: "Business Analysis Report"' in result
        assert 'author: "Analytics Team"' in result


class TestTemplateEngineWorkflows:
    """Test complete template processing workflows."""

    def setup_method(self):
        """Set up test environment."""
        try:
            from markitect.template.engine import TemplateEngine
            from markitect.template.parser import TemplateParser
            self.engine = TemplateEngine()
            self.parser = TemplateParser()
        except ImportError:
            self.engine = None
            self.parser = None

    def test_template_validation_workflow(self):
        """Test complete template validation before rendering workflow.

        Reference: Issue #65 - Template Engine Foundation
        """
        # Arrange
        template_with_errors = "Valid: {{name}}, Invalid: {{broken, Incomplete: {missing}"
        valid_template = "Hello {{name}}, welcome to {{company}}!"
        test_data = {"name": "Alice", "company": "MarkiTect"}

        # Act & Assert
        if self.engine is None or self.parser is None:
            pytest.skip("Template components not implemented yet")

        # Test validation of problematic template
        errors = self.engine.validate_template(template_with_errors)
        assert len(errors) > 0

        # Test validation of good template
        errors = self.engine.validate_template(valid_template)
        assert len(errors) == 0

        # Test rendering after validation
        result = self.engine.render(valid_template, test_data)
        assert result == "Hello Alice, welcome to MarkiTect!"

    def test_data_completeness_analysis_workflow(self):
        """Test data completeness analysis before rendering.

        Reference: Issue #65 - Template Engine Foundation
        """
        # Arrange
        template = "Invoice {{invoice_number}} for {{customer.name}} - Total: {{total}} {{currency}}"
        complete_data = {
            "invoice_number": "INV-001",
            "customer": {"name": "Acme Corp"},
            "total": 1500.00,
            "currency": "USD"
        }
        incomplete_data = {
            "invoice_number": "INV-001",
            "customer": {"name": "Acme Corp"}
            # Missing 'total' and 'currency'
        }

        # Act & Assert
        if self.engine is None:
            pytest.skip("TemplateEngine not implemented yet")

        # Test with complete data
        completeness = self.engine.check_data_completeness(template, complete_data)
        assert completeness['completeness'] == 1.0
        assert len(completeness['missing']) == 0
        assert len(completeness['available']) == 4

        # Test with incomplete data
        completeness = self.engine.check_data_completeness(template, incomplete_data)
        assert completeness['completeness'] < 1.0
        assert 'total' in completeness['missing']
        assert 'currency' in completeness['missing']
        assert 'invoice_number' in completeness['available']
        assert 'customer.name' in completeness['available']


if __name__ == '__main__':
    pytest.main([__file__, '-v'])