"""End-to-end integration tests for complete ticket lifecycle workflows."""

import os
import tempfile
import json
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
from typing import Dict, Any, List, Optional

import pytest
from typer.testing import CliRunner
from rich.console import Console

from ai_trackdown_pytools.cli import app
from ai_trackdown_pytools.core.project import Project
from ai_trackdown_pytools.core.task import TaskManager


@pytest.fixture
def e2e_runner():
    """Create a CLI runner for end-to-end testing."""
    return CliRunner()


@pytest.fixture
def e2e_project_setup():
    """Set up a complete project environment for E2E testing."""
    with tempfile.TemporaryDirectory() as temp_dir:
        project_path = Path(temp_dir) / "e2e_test_project"
        project_path.mkdir()

        # Initialize the project
        project = Project.create(project_path, name="E2E Test Project")

        # Change to project directory
        original_cwd = os.getcwd()
        os.chdir(str(project_path))

        try:
            yield {
                "project_path": project_path,
                "project": project,
                "temp_dir": temp_dir,
            }
        finally:
            os.chdir(original_cwd)


class TestCompleteTicketLifecycle:
    """Test complete ticket lifecycle from creation to deletion."""

    def test_complete_project_epic_issue_task_workflow(
        self, e2e_runner, e2e_project_setup
    ):
        """Test complete workflow: Project → Epic → Issue → Task → Comments → Deletion."""

        # Store created IDs for cleanup
        created_items = {"epics": [], "issues": [], "tasks": [], "projects": []}

        try:
            # Step 1: Create a project (already done in setup, but verify)
            result = e2e_runner.invoke(app, ["status", "project"])
            assert result.exit_code == 0, f"Project status failed: {result.output}"

            # Step 2: Create an Epic
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create_epic:
                mock_epic = Mock(id="EP-001", title="E2E Test Epic", type="epic")
                mock_create_epic.return_value = mock_epic

                result = e2e_runner.invoke(
                    app,
                    [
                        "epic",
                        "create",
                        "E2E Test Epic",
                        "--description",
                        "Epic for end-to-end testing",
                        "--goal",
                        "Complete E2E test coverage",
                        "--business-value",
                        "Ensures system reliability",
                        "--priority",
                        "high",
                    ],
                )
                assert result.exit_code == 0, f"Epic creation failed: {result.output}"
                created_items["epics"].append("EP-001")

            # Step 3: Create an Issue associated with the Epic
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create_issue:
                mock_issue = Mock(id="ISS-001", title="E2E Test Issue", type="issue")
                mock_create_issue.return_value = mock_issue

                result = e2e_runner.invoke(
                    app,
                    [
                        "issue",
                        "create",
                        "E2E Test Issue",
                        "--description",
                        "Issue for testing epic association",
                        "--epic",
                        "EP-001",
                        "--issue-type",
                        "bug",
                        "--severity",
                        "medium",
                        "--priority",
                        "high",
                    ],
                )
                assert result.exit_code == 0, f"Issue creation failed: {result.output}"
                created_items["issues"].append("ISS-001")

            # Step 4: Create multiple Tasks associated with the Issue
            task_titles = [
                "Implement E2E Test Framework",
                "Write Test Cases",
                "Setup CI Integration",
                "Document Test Procedures",
            ]

            for i, title in enumerate(task_titles, 1):
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.create_task"
                ) as mock_create_task:
                    mock_task = Mock(id=f"TSK-{i:03d}", title=title, type="task")
                    mock_create_task.return_value = mock_task

                    result = e2e_runner.invoke(
                        app,
                        [
                            "task",
                            "create",
                            title,
                            "--description",
                            f"Task {i} for E2E testing",
                            "--issue",
                            "ISS-001",
                            "--assignee",
                            f"developer{i}",
                            "--priority",
                            ["low", "medium", "high", "critical"][i % 4],
                            "--estimate",
                            f"{i * 2}h",
                            "--tag",
                            "e2e",
                            "--tag",
                            "testing",
                        ],
                    )
                    assert (
                        result.exit_code == 0
                    ), f"Task {i} creation failed: {result.output}"
                    created_items["tasks"].append(f"TSK-{i:03d}")

            # Step 5: Create a subtask
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create_subtask:
                mock_subtask = Mock(
                    id="TSK-005", title="Subtask for testing", type="task"
                )
                mock_create_subtask.return_value = mock_subtask

                result = e2e_runner.invoke(
                    app,
                    [
                        "task",
                        "create",
                        "Setup Test Data",
                        "--description",
                        "Subtask for test data preparation",
                        "--parent",
                        "TSK-001",
                        "--assignee",
                        "tester1",
                        "--priority",
                        "medium",
                        "--tag",
                        "subtask",
                    ],
                )
                assert (
                    result.exit_code == 0
                ), f"Subtask creation failed: {result.output}"
                created_items["tasks"].append("TSK-005")

            # Step 6: Update task statuses
            status_updates = [
                ("TSK-001", "in_progress"),
                ("TSK-002", "completed"),
                ("TSK-003", "blocked"),
                ("TSK-004", "open"),
                ("TSK-005", "in_progress"),
            ]

            for task_id, status in status_updates:
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.update_task"
                ) as mock_update:
                    result = e2e_runner.invoke(
                        app, ["task", "update", task_id, "--status", status]
                    )
                    # Note: This might fail if update command doesn't exist
                    # In that case, we'll mock the entire call

            # Step 7: Add comments to tasks
            comment_data = [
                ("TSK-001", "Starting implementation of E2E framework"),
                ("TSK-002", "Test cases completed and reviewed"),
                ("TSK-003", "Blocked waiting for CI environment"),
                ("TSK-004", "Documentation template created"),
                ("TSK-005", "Test data structure defined"),
            ]

            for task_id, comment in comment_data:
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.add_comment"
                ) as mock_comment:
                    result = e2e_runner.invoke(
                        app,
                        [
                            "task",
                            "comment",
                            task_id,
                            "--message",
                            comment,
                            "--author",
                            "e2e_tester",
                        ],
                    )
                    # Comment functionality might not exist yet

            # Step 8: Search and verify relationships
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.task.TaskManager"
            ) as mock_task_mgr:

                mock_exists.return_value = True

                # Mock search results
                mock_tasks = [
                    Mock(
                        id="TSK-001",
                        title="Implement E2E Test Framework",
                        description="Task 1 for E2E testing",
                        tags=["e2e", "testing"],
                        status="in_progress",
                    ),
                    Mock(
                        id="TSK-002",
                        title="Write Test Cases",
                        description="Task 2 for E2E testing",
                        tags=["e2e", "testing"],
                        status="completed",
                    ),
                    Mock(
                        id="EP-001",
                        title="E2E Test Epic",
                        description="Epic for end-to-end testing",
                        tags=["epic"],
                        status="active",
                    ),
                    Mock(
                        id="ISS-001",
                        title="E2E Test Issue",
                        description="Issue for testing epic association",
                        tags=["issue"],
                        status="open",
                    ),
                ]
                mock_task_mgr.return_value.list_tasks.return_value = mock_tasks

                # Search for all E2E related items
                result = e2e_runner.invoke(app, ["search", "E2E", "--limit", "20"])
                assert result.exit_code == 0, f"Search failed: {result.output}"

                # Search by type
                result = e2e_runner.invoke(
                    app, ["search", "test", "--type", "task", "--limit", "10"]
                )
                assert result.exit_code == 0, f"Type search failed: {result.output}"

                # Search by status
                result = e2e_runner.invoke(
                    app, ["search", "E2E", "--status", "in_progress"]
                )
                assert result.exit_code == 0, f"Status search failed: {result.output}"

            # Step 9: Generate reports and status
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.project.Project.load"
            ) as mock_load, patch(
                "ai_trackdown_pytools.core.task.TaskManager"
            ) as mock_task_mgr, patch(
                "ai_trackdown_pytools.utils.git.GitUtils"
            ) as mock_git:

                mock_exists.return_value = True
                mock_project = Mock(
                    name="E2E Test Project", description="End-to-end testing project"
                )
                mock_load.return_value = mock_project

                # Project status
                result = e2e_runner.invoke(app, ["status", "project", "--verbose"])
                assert result.exit_code == 0, f"Project status failed: {result.output}"

                # Task status summary
                result = e2e_runner.invoke(app, ["status", "tasks"])
                # This might not exist, so we'll mock if needed

            # Step 10: Test validation
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.utils.validation.validate_project_structure"
            ) as mock_validate:

                mock_exists.return_value = True
                mock_validate.return_value = {
                    "valid": True,
                    "errors": [],
                    "warnings": [],
                }

                result = e2e_runner.invoke(app, ["validate", "project"])
                assert (
                    result.exit_code == 0
                ), f"Project validation failed: {result.output}"

        finally:
            # Step 11: Cleanup - Delete all created items in reverse order
            self._cleanup_created_items(e2e_runner, created_items)

    def test_portfolio_backlog_workflow(self, e2e_runner, e2e_project_setup):
        """Test portfolio and backlog management workflow."""

        created_items = {"projects": [], "epics": [], "issues": [], "tasks": []}

        try:
            # Step 1: Create multiple projects for portfolio
            project_data = [
                ("Frontend Modernization", "React migration project"),
                ("API Enhancement", "REST API improvements"),
                ("Security Audit", "Comprehensive security review"),
            ]

            for i, (name, desc) in enumerate(project_data, 1):
                with patch(
                    "ai_trackdown_pytools.core.project.Project.create"
                ) as mock_create:
                    mock_project = Mock(id=f"PROJ-{i:03d}", name=name)
                    mock_create.return_value = mock_project

                    result = e2e_runner.invoke(
                        app,
                        [
                            "portfolio",
                            "create-project",
                            name,
                            "--description",
                            desc,
                            "--priority",
                            ["high", "medium", "low"][i % 3],
                            "--team-size",
                            str(i * 2 + 3),
                        ],
                    )
                    # This command might not exist, so we'll mock the entire flow
                    created_items["projects"].append(f"PROJ-{i:03d}")

            # Step 2: Create epics for different projects
            epic_data = [
                ("User Authentication Overhaul", "PROJ-001", "high"),
                ("Component Library", "PROJ-001", "medium"),
                ("Rate Limiting Implementation", "PROJ-002", "high"),
                ("Vulnerability Assessment", "PROJ-003", "critical"),
            ]

            for i, (title, project, priority) in enumerate(epic_data, 1):
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.create_task"
                ) as mock_create:
                    mock_epic = Mock(id=f"EP-{i:03d}", title=title, type="epic")
                    mock_create.return_value = mock_epic

                    result = e2e_runner.invoke(
                        app,
                        [
                            "epic",
                            "create",
                            title,
                            "--project",
                            project,
                            "--priority",
                            priority,
                            "--business-value",
                            f"Value proposition {i}",
                            "--target-date",
                            "2024-12-31",
                        ],
                    )
                    created_items["epics"].append(f"EP-{i:03d}")

            # Step 3: Create backlog items
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.list_tasks"
            ) as mock_list:
                mock_backlog_items = [
                    Mock(
                        id=f"TSK-{i:03d}",
                        title=f"Backlog Item {i}",
                        priority=["low", "medium", "high"][i % 3],
                        status="backlog",
                    )
                    for i in range(1, 11)
                ]
                mock_list.return_value = mock_backlog_items

                result = e2e_runner.invoke(
                    app, ["portfolio", "backlog", "--limit", "10"]
                )
                # Mock the portfolio backlog view

            # Step 4: Prioritize backlog
            prioritization_commands = [
                (["portfolio", "prioritize", "TSK-001", "--priority", "critical"]),
                (["portfolio", "prioritize", "TSK-002", "--priority", "high"]),
                (["portfolio", "move-to-sprint", "TSK-001", "--sprint", "2024-Q4"]),
            ]

            for cmd in prioritization_commands:
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.update_task"
                ) as mock_update:
                    result = e2e_runner.invoke(app, cmd)
                    # These commands might not exist yet

        finally:
            self._cleanup_created_items(e2e_runner, created_items)

    def test_sync_and_migration_workflow(self, e2e_runner, e2e_project_setup):
        """Test sync with external platforms and migration workflow."""

        created_items = {"synced_items": [], "migrated_items": []}

        try:
            # Step 1: Setup sync with GitHub
            with patch(
                "ai_trackdown_pytools.utils.git.GitUtils.is_git_repo"
            ) as mock_git:
                mock_git.return_value = True

                result = e2e_runner.invoke(
                    app,
                    [
                        "sync",
                        "configure",
                        "github",
                        "--token",
                        "test_token",
                        "--repo",
                        "test-org/test-repo",
                    ],
                )
                # This might not exist yet

            # Step 2: Import issues from GitHub
            with patch("requests.get") as mock_get:
                mock_response = Mock()
                mock_response.json.return_value = [
                    {
                        "id": 1,
                        "number": 42,
                        "title": "Imported GitHub Issue",
                        "body": "Issue imported from GitHub",
                        "state": "open",
                        "labels": [{"name": "bug"}, {"name": "high-priority"}],
                    }
                ]
                mock_get.return_value = mock_response

                result = e2e_runner.invoke(
                    app,
                    ["sync", "import", "github", "--type", "issues", "--limit", "10"],
                )
                created_items["synced_items"].append("github-issue-42")

            # Step 3: Export tasks to GitHub
            with patch("requests.post") as mock_post:
                mock_post.return_value = Mock(
                    status_code=201, json=lambda: {"number": 43}
                )

                result = e2e_runner.invoke(
                    app,
                    [
                        "sync",
                        "export",
                        "github",
                        "--task-id",
                        "TSK-001",
                        "--create-issue",
                    ],
                )

            # Step 4: Test migration from old format
            old_data = {
                "tasks": [
                    {
                        "id": "OLD-001",
                        "title": "Legacy Task",
                        "status": "open",
                        "priority": "medium",
                        "legacy_field": "should_be_migrated",
                    }
                ]
            }

            with patch("builtins.open", create=True) as mock_open:
                mock_file = Mock()
                mock_file.read.return_value = json.dumps(old_data)
                mock_open.return_value.__enter__.return_value = mock_file

                result = e2e_runner.invoke(
                    app,
                    [
                        "migrate",
                        "from-json",
                        "--source",
                        "/path/to/old_data.json",
                        "--dry-run",
                    ],
                )
                created_items["migrated_items"].append("OLD-001")

            # Step 5: Test schema migration
            result = e2e_runner.invoke(
                app,
                [
                    "migrate",
                    "schema",
                    "--from-version",
                    "1.0",
                    "--to-version",
                    "2.0",
                    "--backup",
                ],
            )

        finally:
            self._cleanup_created_items(e2e_runner, created_items)

    def test_template_and_automation_workflow(self, e2e_runner, e2e_project_setup):
        """Test template management and automation workflow."""

        created_items = {"templates": [], "automated_tasks": []}

        try:
            # Step 1: List available templates
            with patch(
                "ai_trackdown_pytools.utils.templates.TemplateManager.list_templates"
            ) as mock_list:
                mock_list.return_value = [
                    "default",
                    "bug_report",
                    "feature_request",
                    "epic",
                ]

                result = e2e_runner.invoke(app, ["template", "list"])
                assert result.exit_code == 0

            # Step 2: Create custom template
            template_content = """---
name: "Custom E2E Template"
type: "task"
fields:
  - name: "title"
    required: true
  - name: "test_type"
    type: "choice"
    choices: ["unit", "integration", "e2e"]
---
# {{title}}

## Test Type: {{test_type}}

## Description
{{description}}

## Test Cases
- [ ] Test case 1
- [ ] Test case 2
- [ ] Test case 3

## Acceptance Criteria
- [ ] Criteria 1
- [ ] Criteria 2
"""

            with patch("builtins.open", create=True) as mock_open:
                result = e2e_runner.invoke(
                    app,
                    [
                        "template",
                        "create",
                        "e2e_test",
                        "--type",
                        "task",
                        "--interactive",
                    ],
                )
                created_items["templates"].append("e2e_test")

            # Step 3: Apply template to create tasks
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create:
                mock_task = Mock(id="TSK-TEMPLATE-001", title="Template Generated Task")
                mock_create.return_value = mock_task

                result = e2e_runner.invoke(
                    app,
                    [
                        "task",
                        "create",
                        "Template Generated Task",
                        "--template",
                        "e2e_test",
                        "--test-type",
                        "e2e",
                    ],
                )
                created_items["automated_tasks"].append("TSK-TEMPLATE-001")

            # Step 4: Validate template
            with patch(
                "ai_trackdown_pytools.utils.validation.SchemaValidator.validate_template"
            ) as mock_validate:
                mock_validate.return_value = {
                    "valid": True,
                    "errors": [],
                    "warnings": [],
                }

                result = e2e_runner.invoke(app, ["template", "validate", "e2e_test"])
                assert result.exit_code == 0

            # Step 5: Export template
            result = e2e_runner.invoke(
                app,
                [
                    "template",
                    "export",
                    "e2e_test",
                    "--output",
                    "/tmp/e2e_test_template.yaml",
                ],
            )

        finally:
            self._cleanup_created_items(e2e_runner, created_items)

    def test_ai_integration_workflow(self, e2e_runner, e2e_project_setup):
        """Test AI-specific features and integration workflow."""

        created_items = {"ai_sessions": [], "ai_tasks": []}

        try:
            # Step 1: Initialize AI context
            result = e2e_runner.invoke(
                app, ["ai", "init", "--model", "gpt-4", "--context-window", "8000"]
            )
            created_items["ai_sessions"].append("ai-session-001")

            # Step 2: Generate task from AI prompt
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create:
                mock_task = Mock(id="AI-TSK-001", title="AI Generated Task")
                mock_create.return_value = mock_task

                result = e2e_runner.invoke(
                    app,
                    [
                        "ai",
                        "generate",
                        "task",
                        "--prompt",
                        "Create a task for implementing user authentication with OAuth2",
                        "--auto-assign",
                        "ai-team",
                    ],
                )
                created_items["ai_tasks"].append("AI-TSK-001")

            # Step 3: AI code review integration
            result = e2e_runner.invoke(
                app,
                ["ai", "review", "TSK-001", "--include-diff", "--suggest-improvements"],
            )

            # Step 4: AI estimation
            result = e2e_runner.invoke(
                app,
                [
                    "ai",
                    "estimate",
                    "TSK-001",
                    "--method",
                    "planning-poker",
                    "--consider-complexity",
                ],
            )

            # Step 5: Export AI context
            result = e2e_runner.invoke(
                app,
                [
                    "ai",
                    "export-context",
                    "--format",
                    "json",
                    "--output",
                    "/tmp/ai_context.json",
                ],
            )

        finally:
            self._cleanup_created_items(e2e_runner, created_items)

    def test_comprehensive_validation_workflow(self, e2e_runner, e2e_project_setup):
        """Test comprehensive validation across all components."""

        try:
            # Step 1: Validate project structure
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.utils.validation.validate_project_structure"
            ) as mock_validate:

                mock_exists.return_value = True
                mock_validate.return_value = {
                    "valid": True,
                    "errors": [],
                    "warnings": ["Templates directory empty"],
                }

                result = e2e_runner.invoke(app, ["validate", "project"])
                assert result.exit_code == 0
                assert "valid" in result.output.lower()

            # Step 2: Validate all tasks
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.task.TaskManager"
            ) as mock_task_mgr, patch(
                "ai_trackdown_pytools.utils.validation.validate_task_file"
            ) as mock_validate_task:

                mock_exists.return_value = True
                mock_tasks = [
                    Mock(id="TSK-001", file_path="/path/to/task1.md"),
                    Mock(id="TSK-002", file_path="/path/to/task2.md"),
                ]
                mock_task_mgr.return_value.list_tasks.return_value = mock_tasks
                mock_validate_task.return_value = {
                    "valid": True,
                    "errors": [],
                    "warnings": [],
                }

                result = e2e_runner.invoke(app, ["validate", "tasks"])
                assert result.exit_code == 0

            # Step 3: Validate configuration
            with patch(
                "ai_trackdown_pytools.core.config.Config.load"
            ) as mock_load, patch(
                "ai_trackdown_pytools.utils.validation.SchemaValidator"
            ) as mock_validator_class:

                mock_config = Mock()
                mock_config.to_dict.return_value = {"project": {"name": "Test"}}
                mock_load.return_value = mock_config

                mock_validator = Mock()
                mock_validator.validate_config.return_value = {
                    "valid": True,
                    "errors": [],
                    "warnings": [],
                }
                mock_validator_class.return_value = mock_validator

                result = e2e_runner.invoke(app, ["validate", "config"])
                assert result.exit_code == 0

            # Step 4: Validate with fix option
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.utils.validation.validate_project_structure"
            ) as mock_validate:

                mock_exists.return_value = True
                mock_validate.return_value = {
                    "valid": False,
                    "errors": ["Missing directory structure"],
                    "warnings": [],
                }

                result = e2e_runner.invoke(app, ["validate", "project", "--fix"])
                # Should attempt to fix issues

            # Step 5: Run comprehensive health check
            with patch(
                "ai_trackdown_pytools.utils.health.check_health"
            ) as mock_health, patch(
                "ai_trackdown_pytools.utils.health.check_project_health"
            ) as mock_project_health, patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.config.Config.load"
            ) as mock_config, patch(
                "ai_trackdown_pytools.utils.git.GitUtils"
            ) as mock_git:

                mock_health.return_value = {
                    "overall": True,
                    "checks": {"dependencies": {"status": True, "message": "OK"}},
                }
                mock_exists.return_value = True
                mock_project_health.return_value = {
                    "checks": {"structure": {"status": True, "message": "OK"}}
                }
                mock_config.return_value = Mock(
                    config_path="/test", project_root="/test"
                )

                result = e2e_runner.invoke(app, ["doctor"])
                assert result.exit_code == 0
                assert "System Health" in result.output

        except Exception as e:
            pytest.fail(f"Comprehensive validation workflow failed: {e}")

    def _cleanup_created_items(
        self, runner: CliRunner, created_items: Dict[str, List[str]]
    ):
        """Clean up all created items in reverse dependency order."""

        # Delete in reverse order: tasks → issues → epics → projects
        cleanup_order = [
            "tasks",
            "issues",
            "epics",
            "projects",
            "templates",
            "ai_sessions",
            "ai_tasks",
            "synced_items",
            "migrated_items",
            "automated_tasks",
        ]

        for item_type in cleanup_order:
            if item_type in created_items:
                for item_id in created_items[item_type]:
                    try:
                        # Attempt deletion (might not be implemented)
                        if item_type == "tasks":
                            result = runner.invoke(
                                app, ["task", "delete", item_id, "--force"]
                            )
                        elif item_type == "issues":
                            result = runner.invoke(
                                app, ["issue", "delete", item_id, "--force"]
                            )
                        elif item_type == "epics":
                            result = runner.invoke(
                                app, ["epic", "delete", item_id, "--force"]
                            )
                        elif item_type == "projects":
                            result = runner.invoke(
                                app, ["portfolio", "delete-project", item_id, "--force"]
                            )
                        elif item_type == "templates":
                            result = runner.invoke(
                                app, ["template", "delete", item_id, "--force"]
                            )
                        # Add more deletion commands as needed

                        # Don't assert on cleanup failures since delete commands might not exist
                    except Exception:
                        # Ignore cleanup failures
                        pass


class TestConcurrentOperations:
    """Test concurrent operations and race conditions."""

    def test_concurrent_task_creation(self, e2e_runner, e2e_project_setup):
        """Test multiple tasks created simultaneously."""

        created_tasks = []

        try:
            # Simulate concurrent task creation
            task_data = [
                ("Concurrent Task 1", "developer1"),
                ("Concurrent Task 2", "developer2"),
                ("Concurrent Task 3", "developer3"),
                ("Concurrent Task 4", "developer4"),
                ("Concurrent Task 5", "developer5"),
            ]

            for i, (title, assignee) in enumerate(task_data, 1):
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.create_task"
                ) as mock_create:
                    mock_task = Mock(id=f"CONCURRENT-{i:03d}", title=title)
                    mock_create.return_value = mock_task

                    result = e2e_runner.invoke(
                        app,
                        [
                            "task",
                            "create",
                            title,
                            "--assignee",
                            assignee,
                            "--priority",
                            "medium",
                        ],
                    )
                    assert result.exit_code == 0
                    created_tasks.append(f"CONCURRENT-{i:03d}")

            # Verify all tasks were created
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.task.TaskManager"
            ) as mock_task_mgr:

                mock_exists.return_value = True
                mock_tasks = [
                    Mock(
                        id=task_id,
                        title=f"Concurrent Task {i+1}",
                        description="",
                        tags=[],
                        status="open",
                    )
                    for i, task_id in enumerate(created_tasks)
                ]
                mock_task_mgr.return_value.list_tasks.return_value = mock_tasks

                result = e2e_runner.invoke(app, ["search", "Concurrent"])
                assert result.exit_code == 0

                # Check that all concurrent tasks are found
                for task_id in created_tasks:
                    assert task_id in result.output or "Concurrent" in result.output

        finally:
            # Cleanup
            for task_id in created_tasks:
                try:
                    e2e_runner.invoke(app, ["task", "delete", task_id, "--force"])
                except Exception:
                    pass

    def test_large_scale_operations(self, e2e_runner, e2e_project_setup):
        """Test operations with large datasets."""

        created_items = []

        try:
            # Create large number of tasks
            with patch(
                "ai_trackdown_pytools.core.task.TaskManager.create_task"
            ) as mock_create:
                for i in range(1, 101):  # 100 tasks
                    mock_task = Mock(id=f"SCALE-{i:03d}", title=f"Scale Test Task {i}")
                    mock_create.return_value = mock_task

                    result = e2e_runner.invoke(
                        app,
                        [
                            "task",
                            "create",
                            f"Scale Test Task {i}",
                            "--priority",
                            ["low", "medium", "high"][i % 3],
                            "--tag",
                            f"batch-{(i-1)//10 + 1}",
                        ],
                    )
                    if result.exit_code == 0:
                        created_items.append(f"SCALE-{i:03d}")

            # Test search performance with large dataset
            with patch(
                "ai_trackdown_pytools.core.project.Project.exists"
            ) as mock_exists, patch(
                "ai_trackdown_pytools.core.task.TaskManager"
            ) as mock_task_mgr:

                mock_exists.return_value = True
                mock_tasks = [
                    Mock(
                        id=f"SCALE-{i:03d}",
                        title=f"Scale Test Task {i}",
                        description="Scale testing",
                        tags=[f"batch-{(i-1)//10 + 1}"],
                        status="open",
                    )
                    for i in range(1, 101)
                ]
                mock_task_mgr.return_value.list_tasks.return_value = mock_tasks

                # Test search with different limits
                for limit in [10, 25, 50, 100]:
                    result = e2e_runner.invoke(
                        app, ["search", "Scale", "--limit", str(limit)]
                    )
                    assert result.exit_code == 0

                # Test filtered searches
                result = e2e_runner.invoke(
                    app, ["search", "Scale", "--status", "open", "--limit", "50"]
                )
                assert result.exit_code == 0

        finally:
            # Cleanup large dataset
            for item_id in created_items:
                try:
                    e2e_runner.invoke(app, ["task", "delete", item_id, "--force"])
                except Exception:
                    pass


class TestErrorRecovery:
    """Test error handling and recovery scenarios."""

    def test_network_failure_recovery(self, e2e_runner, e2e_project_setup):
        """Test recovery from network failures during sync operations."""

        try:
            # Simulate network failure during GitHub sync
            with patch(
                "requests.get", side_effect=ConnectionError("Network unavailable")
            ):
                result = e2e_runner.invoke(
                    app, ["sync", "import", "github", "--retry", "3", "--timeout", "30"]
                )
                # Should handle network failure gracefully

        except Exception as e:
            # Should not crash the application
            assert "Network" in str(e) or "Connection" in str(e)

    def test_file_corruption_handling(self, e2e_runner, e2e_project_setup):
        """Test handling of corrupted files."""

        try:
            # Simulate corrupted task file
            with patch("builtins.open", side_effect=OSError("File corrupted")):
                result = e2e_runner.invoke(app, ["validate", "tasks"])
                # Should handle file corruption gracefully

        except Exception as e:
            # Should provide meaningful error message
            assert "corrupted" in str(e).lower() or "error" in str(e).lower()

    def test_partial_operation_recovery(self, e2e_runner, e2e_project_setup):
        """Test recovery from partial operation failures."""

        created_items = []

        try:
            # Start batch operation that partially fails
            batch_tasks = [
                ("Success Task 1", True),
                ("Failure Task", False),  # This will fail
                ("Success Task 2", True),
                ("Success Task 3", True),
            ]

            for i, (title, should_succeed) in enumerate(batch_tasks, 1):
                with patch(
                    "ai_trackdown_pytools.core.task.TaskManager.create_task"
                ) as mock_create:
                    if should_succeed:
                        mock_task = Mock(id=f"RECOVERY-{i:03d}", title=title)
                        mock_create.return_value = mock_task
                        created_items.append(f"RECOVERY-{i:03d}")
                    else:
                        mock_create.side_effect = Exception("Simulated failure")

                    result = e2e_runner.invoke(
                        app, ["task", "create", title, "--priority", "medium"]
                    )

                    if should_succeed:
                        assert result.exit_code == 0
                    # Don't assert on failure cases - just continue

            # Verify successful tasks were created despite failures
            assert len(created_items) == 3  # Should have 3 successful tasks

        finally:
            # Cleanup successful items
            for item_id in created_items:
                try:
                    e2e_runner.invoke(app, ["task", "delete", item_id, "--force"])
                except Exception:
                    pass


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