"""
Unit tests for Tenant Sites models.

Tests model methods and properties without database access.
"""
from unittest.mock import Mock, patch, MagicMock
import pytest


class TestSiteModel:
    """Test Site model methods."""

    def test_str_method(self):
        """Should return 'Site for {tenant.name}'."""
        from smoothschedule.platform.tenant_sites.models import Site

        site = Site()
        mock_tenant = Mock()
        mock_tenant.name = 'Test Business'
        site._state.fields_cache['tenant'] = mock_tenant

        result = str(site)

        assert result == 'Site for Test Business'

    def test_create_default_page_when_no_home_exists(self):
        """Should create default page when no home page exists."""
        from smoothschedule.platform.tenant_sites.models import Site, Page

        site = Site()
        site.id = 1
        mock_tenant = Mock()
        mock_tenant.name = 'My Business'
        site._state.fields_cache['tenant'] = mock_tenant

        mock_pages = Mock()
        mock_pages.filter.return_value.exists.return_value = False

        with patch.object(Site, 'pages', mock_pages, create=True):
            with patch.object(Page.objects, 'create') as mock_create:
                site.create_default_page()

                mock_create.assert_called_once()
                call_kwargs = mock_create.call_args[1]
                assert call_kwargs['site'] == site
                assert call_kwargs['slug'] == 'home'
                assert call_kwargs['path'] == '/'
                assert call_kwargs['is_home'] is True
                assert call_kwargs['is_published'] is True
                assert 'Welcome to My Business' in str(call_kwargs['puck_data'])

    def test_create_default_page_skips_when_home_exists(self):
        """Should not create page when home page already exists."""
        from smoothschedule.platform.tenant_sites.models import Site, Page

        site = Site()
        site.id = 1
        mock_tenant = Mock()
        mock_tenant.name = 'My Business'
        site._state.fields_cache['tenant'] = mock_tenant

        mock_pages = Mock()
        mock_pages.filter.return_value.exists.return_value = True

        with patch.object(Site, 'pages', mock_pages, create=True):
            with patch.object(Page.objects, 'create') as mock_create:
                site.create_default_page()

                mock_create.assert_not_called()

    def test_model_has_required_fields(self):
        """Should have tenant, primary_domain, is_enabled fields."""
        from smoothschedule.platform.tenant_sites.models import Site

        field_names = [f.name for f in Site._meta.get_fields()]
        assert 'tenant' in field_names
        assert 'primary_domain' in field_names
        assert 'is_enabled' in field_names
        assert 'template_key' in field_names
        assert 'created_at' in field_names
        assert 'updated_at' in field_names


class TestPageModel:
    """Test Page model methods."""

    def test_str_method(self):
        """Should return title with path."""
        from smoothschedule.platform.tenant_sites.models import Page

        page = Page()
        page.title = 'Contact Us'
        page.path = '/contact'

        result = str(page)

        assert result == 'Contact Us (/contact)'

    def test_model_has_required_fields(self):
        """Should have site, slug, path, title, etc."""
        from smoothschedule.platform.tenant_sites.models import Page

        field_names = [f.name for f in Page._meta.get_fields()]
        assert 'site' in field_names
        assert 'slug' in field_names
        assert 'path' in field_names
        assert 'title' in field_names
        assert 'is_home' in field_names
        assert 'is_published' in field_names
        assert 'order' in field_names
        assert 'puck_data' in field_names
        assert 'version' in field_names

    def test_unique_together_constraint(self):
        """Should have unique_together on site and path."""
        from smoothschedule.platform.tenant_sites.models import Page

        assert Page._meta.unique_together == (('site', 'path'),)


class TestDomainModel:
    """Test Domain model methods."""

    def test_str_method(self):
        """Should return host."""
        from smoothschedule.platform.tenant_sites.models import Domain

        domain = Domain()
        domain.host = 'mybusiness.com'

        result = str(domain)

        assert result == 'mybusiness.com'

    def test_model_has_required_fields(self):
        """Should have site, host, is_primary, is_verified fields."""
        from smoothschedule.platform.tenant_sites.models import Domain

        field_names = [f.name for f in Domain._meta.get_fields()]
        assert 'site' in field_names
        assert 'host' in field_names
        assert 'is_primary' in field_names
        assert 'is_verified' in field_names
        assert 'verification_token' in field_names

    def test_unique_primary_domain_constraint(self):
        """Should have constraint for unique primary domain per site."""
        from smoothschedule.platform.tenant_sites.models import Domain

        constraints = [c.name for c in Domain._meta.constraints]
        assert 'unique_primary_domain_per_site' in constraints


class TestSiteSignal:
    """Test Site post_save signal."""

    def test_creates_default_page_on_new_site(self):
        """Should create default page when new site is created."""
        from smoothschedule.platform.tenant_sites.models import (
            create_default_page_for_site, Site
        )

        mock_site = Mock(spec=Site)

        create_default_page_for_site(
            sender=Site,
            instance=mock_site,
            created=True
        )

        mock_site.create_default_page.assert_called_once()

    def test_does_not_create_default_page_on_update(self):
        """Should not create default page when site is updated."""
        from smoothschedule.platform.tenant_sites.models import (
            create_default_page_for_site, Site
        )

        mock_site = Mock(spec=Site)

        create_default_page_for_site(
            sender=Site,
            instance=mock_site,
            created=False
        )

        mock_site.create_default_page.assert_not_called()
