"""Tests for vr delete commands."""

import pytest
from unittest.mock import patch, Mock

from typer.testing import CliRunner

from vr_cli.cli import app
from vr_cli.entities.agent import Agent
from vr_cli.entities.agent_function import AgentFunction
from vr_cli.entities.agent_environment import AgentEnvironment
from vr_cli.entities.agent_secret import AgentSecret
from vr_cli.entities.organization_phone_number import OrganizationPhoneNumber
from vr_cli.entities.organization_secret import OrganizationSecret
from vr_cli.entities.organization_telephony import OrganizationTelephony


runner = CliRunner()


# ============================================================================
# Delete Agent Tests
# ============================================================================


class TestDeleteAgent:
    """Tests for delete agent command."""

    def test_delete_agent_by_name(self, mock_agent):
        """Should delete an agent by name."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_repo_class:
            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_agent
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "agent", "Test Agent"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        assert "Test Agent" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-agent-id-123")

    def test_delete_agent_by_id(self, mock_agent):
        """Should delete an agent by ID."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_repo_class:
            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_agent
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "agent", "test-agent-id-123"])

        assert result.exit_code == 0
        mock_repo.get_by_name_or_id.assert_called_once_with("test-agent-id-123")

    def test_delete_agent_not_found(self):
        """Should fail when agent not found."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_repo_class:
            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = None
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "agent", "nonexistent"])

        assert result.exit_code != 0
        assert "Agent not found" in result.output

    def test_delete_agent_api_failure(self, mock_agent):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_repo_class:
            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_agent
            mock_repo.delete_by_id.return_value = False
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "agent", "Test Agent"])

        assert result.exit_code != 0
        assert "Failed to delete agent" in result.output


# ============================================================================
# Delete Function Tests
# ============================================================================


class TestDeleteFunction:
    """Tests for delete function command."""

    def test_delete_function_success(self, mock_agent, mock_function):
        """Should delete a function by name."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentFunctionRepository") as mock_func_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_func_repo = Mock()
            mock_func_repo.get_by_name_or_id.return_value = mock_function
            mock_func_repo.delete_by_id.return_value = True
            mock_func_repo_class.return_value = mock_func_repo

            result = runner.invoke(app, ["delete", "function", "Test Agent", "Test Function"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_func_repo.delete_by_id.assert_called_once_with("test-function-id-123")

    def test_delete_function_agent_not_found(self):
        """Should fail when agent not found."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class:
            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = None
            mock_agent_repo_class.return_value = mock_agent_repo

            result = runner.invoke(app, ["delete", "function", "nonexistent", "func"])

        assert result.exit_code != 0
        assert "Agent not found" in result.output

    def test_delete_function_not_found(self, mock_agent):
        """Should fail when function not found."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentFunctionRepository") as mock_func_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_func_repo = Mock()
            mock_func_repo.get_by_name_or_id.return_value = None
            mock_func_repo_class.return_value = mock_func_repo

            result = runner.invoke(app, ["delete", "function", "Test Agent", "nonexistent"])

        assert result.exit_code != 0
        assert "Function not found" in result.output

    def test_delete_function_api_failure(self, mock_agent, mock_function):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentFunctionRepository") as mock_func_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_func_repo = Mock()
            mock_func_repo.get_by_name_or_id.return_value = mock_function
            mock_func_repo.delete_by_id.return_value = False
            mock_func_repo_class.return_value = mock_func_repo

            result = runner.invoke(app, ["delete", "function", "Test Agent", "Test Function"])

        assert result.exit_code != 0
        assert "Failed to delete function" in result.output


# ============================================================================
# Delete Environment Tests
# ============================================================================


class TestDeleteEnvironment:
    """Tests for delete environment command."""

    def test_delete_environment_success(self, mock_agent, mock_environment):
        """Should delete an environment by name."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentEnvironmentRepository") as mock_env_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_env_repo = Mock()
            mock_env_repo.get_by_name_or_id.return_value = mock_environment
            mock_env_repo.delete_by_id.return_value = True
            mock_env_repo_class.return_value = mock_env_repo

            result = runner.invoke(app, ["delete", "environment", "Test Agent", "Test Environment"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_env_repo.delete_by_id.assert_called_once_with("test-env-id-123")

    def test_delete_environment_agent_not_found(self):
        """Should fail when agent not found."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class:
            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = None
            mock_agent_repo_class.return_value = mock_agent_repo

            result = runner.invoke(app, ["delete", "environment", "nonexistent", "env"])

        assert result.exit_code != 0
        assert "Agent not found" in result.output

    def test_delete_environment_not_found(self, mock_agent):
        """Should fail when environment not found."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentEnvironmentRepository") as mock_env_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_env_repo = Mock()
            mock_env_repo.get_by_name_or_id.return_value = None
            mock_env_repo_class.return_value = mock_env_repo

            result = runner.invoke(app, ["delete", "environment", "Test Agent", "nonexistent"])

        assert result.exit_code != 0
        assert "Environment not found" in result.output

    def test_delete_environment_api_failure(self, mock_agent, mock_environment):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentEnvironmentRepository") as mock_env_repo_class:

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_env_repo = Mock()
            mock_env_repo.get_by_name_or_id.return_value = mock_environment
            mock_env_repo.delete_by_id.return_value = False
            mock_env_repo_class.return_value = mock_env_repo

            result = runner.invoke(app, ["delete", "environment", "Test Agent", "Test Environment"])

        assert result.exit_code != 0
        assert "Failed to delete environment" in result.output


# ============================================================================
# Delete Secret Tests
# ============================================================================


class TestDeleteSecret:
    """Tests for delete secret command."""

    def test_delete_org_secret(self, mock_user, mock_organization_secret):
        """Should delete an organization secret."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationSecretRepository") as mock_repo_class, \
             patch("vr_cli.commands.delete.Path") as mock_path:

            mock_get_org.return_value = mock_user.organization_id

            mock_voicerun_dir = Mock()
            mock_voicerun_dir.exists.return_value = False
            mock_path.cwd.return_value.__truediv__.return_value = mock_voicerun_dir

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_organization_secret
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "secret", "ORG_API_KEY"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        assert "ORG_API_KEY" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-org-secret-id-123")

    def test_delete_agent_secret_with_flag(self, mock_user, mock_agent, mock_secret):
        """Should delete an agent secret when --agent is provided."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationSecretRepository") as mock_org_repo_class, \
             patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentSecretRepository") as mock_agent_secret_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            # Org repo returns nothing
            mock_org_repo = Mock()
            mock_org_repo.get_by_name_or_id.return_value = None
            mock_org_repo_class.return_value = mock_org_repo

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_agent_secret_repo = Mock()
            mock_agent_secret_repo.get_by_name_or_id.return_value = mock_secret
            mock_agent_secret_repo.delete_by_id.return_value = True
            mock_agent_secret_repo_class.return_value = mock_agent_secret_repo

            result = runner.invoke(app, ["delete", "secret", "API_KEY", "--agent", "Test Agent"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        assert "API_KEY" in result.output
        mock_agent_secret_repo.delete_by_id.assert_called_once_with("test-secret-id-123")

    def test_delete_secret_with_agent_lock(self, mock_user, mock_agent, mock_secret):
        """Should fall back to agent secret via agent.lock when org secret not found."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationSecretRepository") as mock_org_repo_class, \
             patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class, \
             patch("vr_cli.commands.delete.AgentSecretRepository") as mock_agent_secret_repo_class, \
             patch("vr_cli.commands.delete.Path") as mock_path, \
             patch("vr_cli.commands.delete.load_agent_lock") as mock_load_lock:

            mock_get_org.return_value = mock_user.organization_id

            mock_voicerun_dir = Mock()
            mock_voicerun_dir.exists.return_value = True
            mock_path.cwd.return_value.__truediv__.return_value = mock_voicerun_dir

            mock_load_lock.return_value = {"id": "test-agent-id-123"}

            # Org repo returns nothing
            mock_org_repo = Mock()
            mock_org_repo.get_by_name_or_id.return_value = None
            mock_org_repo_class.return_value = mock_org_repo

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_id.return_value = mock_agent
            mock_agent_repo_class.return_value = mock_agent_repo

            mock_agent_secret_repo = Mock()
            mock_agent_secret_repo.get_by_name_or_id.return_value = mock_secret
            mock_agent_secret_repo.delete_by_id.return_value = True
            mock_agent_secret_repo_class.return_value = mock_agent_secret_repo

            result = runner.invoke(app, ["delete", "secret", "API_KEY"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_agent_secret_repo.delete_by_id.assert_called_once_with("test-secret-id-123")

    def test_delete_secret_not_found(self, mock_user):
        """Should fail when secret not found."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationSecretRepository") as mock_repo_class, \
             patch("vr_cli.commands.delete.Path") as mock_path:

            mock_get_org.return_value = mock_user.organization_id

            mock_voicerun_dir = Mock()
            mock_voicerun_dir.exists.return_value = False
            mock_path.cwd.return_value.__truediv__.return_value = mock_voicerun_dir

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = None
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "secret", "nonexistent"])

        assert result.exit_code != 0
        assert "Secret not found" in result.output

    def test_delete_secret_no_organization(self):
        """Should fail when unable to determine organization."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org:
            mock_get_org.return_value = None

            result = runner.invoke(app, ["delete", "secret", "API_KEY"])

        assert result.exit_code != 0
        assert "Unable to determine organization" in result.output

    def test_delete_secret_agent_not_found(self, mock_user):
        """Should fail when --agent specifies a nonexistent agent."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.AgentRepository") as mock_agent_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_agent_repo = Mock()
            mock_agent_repo.get_by_name_or_id.return_value = None
            mock_agent_repo_class.return_value = mock_agent_repo

            result = runner.invoke(app, ["delete", "secret", "API_KEY", "-a", "nonexistent"])

        assert result.exit_code != 0
        assert "Agent not found" in result.output

    def test_delete_secret_api_failure(self, mock_user, mock_organization_secret):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationSecretRepository") as mock_repo_class, \
             patch("vr_cli.commands.delete.Path") as mock_path:

            mock_get_org.return_value = mock_user.organization_id

            mock_voicerun_dir = Mock()
            mock_voicerun_dir.exists.return_value = False
            mock_path.cwd.return_value.__truediv__.return_value = mock_voicerun_dir

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_organization_secret
            mock_repo.delete_by_id.return_value = False
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "secret", "ORG_API_KEY"])

        assert result.exit_code != 0
        assert "Failed to delete secret" in result.output


# ============================================================================
# Delete Phone Number Tests
# ============================================================================


class TestDeletePhoneNumber:
    """Tests for delete phonenumber command."""

    def test_delete_phonenumber_by_id(self, mock_user, mock_phone_number):
        """Should delete a phone number by ID."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = mock_phone_number
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "test-pn-id-123"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        assert "+15551234567" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-pn-id-123")

    def test_delete_phonenumber_by_phone_number(self, mock_user, mock_phone_number):
        """Should delete by matching phone number string."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = None
            mock_repo.get.return_value = [mock_phone_number]
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "+15551234567"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-pn-id-123")

    def test_delete_phonenumber_by_friendly_name(self, mock_user, mock_phone_number):
        """Should delete by matching friendly name."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = None
            mock_repo.get.return_value = [mock_phone_number]
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "Main Line"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-pn-id-123")

    def test_delete_phonenumber_not_found(self, mock_user):
        """Should fail when phone number not found."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = None
            mock_repo.get.return_value = []
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "nonexistent"])

        assert result.exit_code != 0
        assert "Phone number not found" in result.output

    def test_delete_phonenumber_no_organization(self):
        """Should fail when unable to determine organization."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org:
            mock_get_org.return_value = None

            result = runner.invoke(app, ["delete", "phonenumber", "pn-123"])

        assert result.exit_code != 0
        assert "Unable to determine organization" in result.output

    def test_delete_phonenumber_api_failure(self, mock_user, mock_phone_number):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = mock_phone_number
            mock_repo.delete_by_id.return_value = False
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "test-pn-id-123"])

        assert result.exit_code != 0
        assert "Failed to delete phone number" in result.output


# ============================================================================
# Delete Phone Number with --release Tests
# ============================================================================


class TestDeletePhoneNumberRelease:
    """Tests for delete phonenumber --release command."""

    def test_release_phonenumber_by_id(self, mock_user, mock_phone_number):
        """Should release a phone number by ID."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = mock_phone_number
            mock_repo.release.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "test-pn-id-123", "--release"])

        assert result.exit_code == 0
        assert "released successfully" in result.output
        assert "+15551234567" in result.output
        mock_repo.release.assert_called_once_with("test-pn-id-123")
        mock_repo.delete_by_id.assert_not_called()

    def test_release_phonenumber_by_phone_number(self, mock_user, mock_phone_number):
        """Should release by matching phone number string."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = None
            mock_repo.get.return_value = [mock_phone_number]
            mock_repo.release.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "+15551234567", "--release"])

        assert result.exit_code == 0
        assert "released successfully" in result.output
        mock_repo.release.assert_called_once_with("test-pn-id-123")

    def test_release_phonenumber_api_failure(self, mock_user, mock_phone_number):
        """Should fail when release returns failure."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = mock_phone_number
            mock_repo.release.return_value = False
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "test-pn-id-123", "--release"])

        assert result.exit_code != 0
        assert "Failed to release phone number" in result.output

    def test_release_phonenumber_not_found(self, mock_user):
        """Should fail when phone number not found."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = None
            mock_repo.get.return_value = []
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "nonexistent", "--release"])

        assert result.exit_code != 0
        assert "Phone number not found" in result.output

    def test_without_release_calls_delete(self, mock_user, mock_phone_number):
        """Should call delete_by_id when --release is not set."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationPhoneNumberRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_id.return_value = mock_phone_number
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "phonenumber", "test-pn-id-123"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-pn-id-123")
        mock_repo.release.assert_not_called()


# ============================================================================
# Delete Telephony Tests
# ============================================================================


class TestDeleteTelephony:
    """Tests for delete telephony command."""

    def test_delete_telephony_by_name(self, mock_user, mock_telephony):
        """Should delete a telephony provider by name."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationTelephonyRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_telephony
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "telephony", "My Twilio"])

        assert result.exit_code == 0
        assert "deleted successfully" in result.output
        assert "My Twilio" in result.output
        mock_repo.delete_by_id.assert_called_once_with("test-tel-id-789")

    def test_delete_telephony_by_id(self, mock_user, mock_telephony):
        """Should delete a telephony provider by ID."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationTelephonyRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_telephony
            mock_repo.delete_by_id.return_value = True
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "telephony", "test-tel-id-789"])

        assert result.exit_code == 0
        mock_repo.get_by_name_or_id.assert_called_once_with("test-tel-id-789")

    def test_delete_telephony_not_found(self, mock_user):
        """Should fail when telephony provider not found."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationTelephonyRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = None
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "telephony", "nonexistent"])

        assert result.exit_code != 0
        assert "Telephony provider not found" in result.output

    def test_delete_telephony_no_organization(self):
        """Should fail when unable to determine organization."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org:
            mock_get_org.return_value = None

            result = runner.invoke(app, ["delete", "telephony", "test"])

        assert result.exit_code != 0
        assert "Unable to determine organization" in result.output

    def test_delete_telephony_api_failure(self, mock_user, mock_telephony):
        """Should fail when API delete returns failure."""
        with patch("vr_cli.commands.delete.get_effective_organization_id") as mock_get_org, \
             patch("vr_cli.commands.delete.OrganizationTelephonyRepository") as mock_repo_class:

            mock_get_org.return_value = mock_user.organization_id

            mock_repo = Mock()
            mock_repo.get_by_name_or_id.return_value = mock_telephony
            mock_repo.delete_by_id.return_value = False
            mock_repo_class.return_value = mock_repo

            result = runner.invoke(app, ["delete", "telephony", "My Twilio"])

        assert result.exit_code != 0
        assert "Failed to delete telephony provider" in result.output


# ============================================================================
# Help Output Tests
# ============================================================================


class TestDeleteHelp:
    """Tests for delete command help output."""

    def test_delete_help(self):
        """Should show help listing all delete subcommands."""
        result = runner.invoke(app, ["delete", "--help"])

        assert result.exit_code == 0
        assert "agent" in result.output
        assert "function" in result.output
        assert "environment" in result.output
        assert "secret" in result.output
        assert "phonenumber" in result.output
        assert "telephony" in result.output

    def test_delete_agent_help(self):
        """Should show help for delete agent command."""
        result = runner.invoke(app, ["delete", "agent", "--help"])

        assert result.exit_code == 0
        assert "Agent name or ID" in result.output

    def test_delete_function_help(self):
        """Should show help for delete function command."""
        result = runner.invoke(app, ["delete", "function", "--help"])

        assert result.exit_code == 0
        assert "Agent name or ID" in result.output
        assert "Function name" in result.output or "name_or_id" in result.output

    def test_delete_environment_help(self):
        """Should show help for delete environment command."""
        result = runner.invoke(app, ["delete", "environment", "--help"])

        assert result.exit_code == 0
        assert "Agent name or ID" in result.output
        assert "Environment name" in result.output or "name_or_id" in result.output

    def test_delete_secret_help(self):
        """Should show help for delete secret command."""
        result = runner.invoke(app, ["delete", "secret", "--help"])

        assert result.exit_code == 0
        assert "Secret name or ID" in result.output
        assert "--agent" in result.output

    def test_delete_phonenumber_help(self):
        """Should show help for delete phonenumber command."""
        result = runner.invoke(app, ["delete", "phonenumber", "--help"])

        assert result.exit_code == 0
        assert "Phone number ID" in result.output
        assert "--release" in result.output

    def test_delete_telephony_help(self):
        """Should show help for delete telephony command."""
        result = runner.invoke(app, ["delete", "telephony", "--help"])

        assert result.exit_code == 0
        assert "Telephony provider name or ID" in result.output
