"""Unit tests for onboarding services."""

import pytest
from django.contrib.auth.models import User

from accounts import services
from accounts.models import (
    CommunityChannelChoices,
    CompanySizeChoices,
    MarketingProfile,
    OnboardingProgress,
    RoleChoices,
)


@pytest.fixture
def user(db):
    """Create a test user without onboarding records."""
    user = User.objects.create_user(
        username="testuser",
        email="test@example.com",
        password="testpass123",
    )
    # Remove any auto-created records
    OnboardingProgress.objects.filter(user=user).delete()
    MarketingProfile.objects.filter(user=user).delete()
    return user


class TestGetOrCreateOnboarding:
    """Tests for get_or_create_onboarding service."""

    def test_creates_both_records_when_missing(self, user):
        """Should create both OnboardingProgress and MarketingProfile."""
        progress, profile = services.get_or_create_onboarding(user=user)

        assert progress.user == user
        assert profile.user == user
        assert progress.has_completed_onboarding is False
        assert progress.completed_welcome is False
        assert profile.role is None
        assert profile.company_size is None
        assert profile.community_channels == []

    def test_returns_existing_records(self, user):
        """Should return existing records if they exist."""
        OnboardingProgress.objects.create(
            user=user,
            has_completed_onboarding=True,
            completed_welcome=True,
        )
        MarketingProfile.objects.create(
            user=user,
            role=RoleChoices.DEVREL,
        )

        progress, profile = services.get_or_create_onboarding(user=user)

        assert progress.has_completed_onboarding is True
        assert profile.role == RoleChoices.DEVREL


class TestCompleteWelcomeStep:
    """Tests for complete_welcome_step service."""

    def test_marks_welcome_completed(self, user):
        """Should mark welcome step as completed."""
        progress = services.complete_welcome_step(user=user)

        assert progress.completed_welcome is True
        assert progress.completed_role is False
        assert progress.has_completed_onboarding is False

    def test_creates_records_if_missing(self, user):
        """Should create onboarding records if they don't exist."""
        services.complete_welcome_step(user=user)

        assert OnboardingProgress.objects.filter(user=user).exists()
        assert MarketingProfile.objects.filter(user=user).exists()


class TestUpdateOnboardingRole:
    """Tests for update_onboarding_role service."""

    def test_updates_role_when_not_skipped(self, user):
        """Should save role when skip is False."""
        progress = services.update_onboarding_role(
            user=user,
            role=RoleChoices.DEVREL,
            skip=False,
        )

        assert progress.completed_role is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.role == RoleChoices.DEVREL

    def test_skips_role_when_skip_true(self, user):
        """Should not save role when skip is True."""
        progress = services.update_onboarding_role(
            user=user,
            role=RoleChoices.DEVREL,
            skip=True,
        )

        assert progress.completed_role is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.role is None


class TestUpdateOnboardingCompany:
    """Tests for update_onboarding_company service."""

    def test_updates_company_size_when_not_skipped(self, user):
        """Should save company size when skip is False."""
        progress = services.update_onboarding_company(
            user=user,
            company_size=CompanySizeChoices.STARTUP,
            skip=False,
        )

        assert progress.completed_company is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.company_size == CompanySizeChoices.STARTUP

    def test_skips_company_size_when_skip_true(self, user):
        """Should not save company size when skip is True."""
        progress = services.update_onboarding_company(
            user=user,
            company_size=CompanySizeChoices.STARTUP,
            skip=True,
        )

        assert progress.completed_company is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.company_size is None


class TestUpdateOnboardingChannels:
    """Tests for update_onboarding_channels service."""

    def test_updates_channels_and_completes_onboarding(self, user):
        """Should save channels and mark onboarding as completed."""
        channels = [CommunityChannelChoices.GITHUB, CommunityChannelChoices.DISCORD]
        progress = services.update_onboarding_channels(
            user=user,
            community_channels=[ch.value for ch in channels],
            skip=False,
        )

        assert progress.completed_channels is True
        assert progress.has_completed_onboarding is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.community_channels == ["github", "discord"]

    def test_skips_channels_when_skip_true(self, user):
        """Should not save channels when skip is True but still complete onboarding."""
        progress = services.update_onboarding_channels(
            user=user,
            community_channels=["github"],
            skip=True,
        )

        assert progress.completed_channels is True
        assert progress.has_completed_onboarding is True
        profile = MarketingProfile.objects.get(user=user)
        assert profile.community_channels == []


class TestSkipOnboarding:
    """Tests for skip_onboarding service."""

    def test_marks_all_steps_completed(self, user):
        """Should mark all steps and onboarding as completed."""
        progress = services.skip_onboarding(user=user)

        assert progress.completed_welcome is True
        assert progress.completed_role is True
        assert progress.completed_company is True
        assert progress.completed_channels is True
        assert progress.has_completed_onboarding is True

    def test_does_not_modify_marketing_profile(self, user):
        """Should not populate any marketing data."""
        services.skip_onboarding(user=user)

        profile = MarketingProfile.objects.get(user=user)
        assert profile.role is None
        assert profile.company_size is None
        assert profile.community_channels == []
