from __future__ import annotations

from igny8_core.ai.functions.generate_site_structure import GenerateSiteStructureFunction
from igny8_core.business.site_building.models import PageBlueprint
from igny8_core.business.site_building.tests.base import SiteBuilderTestBase


class GenerateSiteStructureFunctionTests(SiteBuilderTestBase):
    """Covers parsing + persistence logic for the Site Builder AI function."""

    def setUp(self):
        super().setUp()
        self.function = GenerateSiteStructureFunction()

    def test_parse_response_extracts_json_object(self):
        noisy_response = """
        Thoughts about the request…
        {
            "site": {"name": "Acme Robotics"},
            "pages": [{"slug": "home", "title": "Home"}]
        }
        Extra commentary that should be ignored.
        """
        parsed = self.function.parse_response(noisy_response)
        self.assertEqual(parsed['site']['name'], 'Acme Robotics')
        self.assertEqual(parsed['pages'][0]['slug'], 'home')

    def test_save_output_updates_structure_and_syncs_pages(self):
        # Existing page to prove update/delete flows.
        legacy_page = PageBlueprint.objects.create(
            site_blueprint=self.blueprint,
            slug='legacy',
            title='Legacy Page',
            type='custom',
            blocks_json=[],
            order=5,
        )

        parsed = {
            'site': {'name': 'Future Robotics'},
            'pages': [
                {
                    'slug': 'home',
                    'title': 'Homepage',
                    'type': 'home',
                    'status': 'ready',
                    'blocks': [{'type': 'hero', 'heading': 'Build faster'}],
                },
                {
                    'slug': 'about',
                    'title': 'About Us',
                    'type': 'about',
                    'blocks': [],
                },
            ],
        }

        result = self.function.save_output(parsed, {'blueprint': self.blueprint})

        self.blueprint.refresh_from_db()
        self.assertEqual(self.blueprint.status, 'ready')
        self.assertEqual(self.blueprint.structure_json['site']['name'], 'Future Robotics')
        self.assertEqual(result['pages_created'], 1)
        self.assertEqual(result['pages_updated'], 1)
        self.assertEqual(result['pages_deleted'], 1)

        slugs = set(self.blueprint.pages.values_list('slug', flat=True))
        self.assertIn('home', slugs)
        self.assertIn('about', slugs)
        self.assertNotIn(legacy_page.slug, slugs)

    def test_build_prompt_includes_existing_pages(self):
        # Convert structure to JSON to ensure template rendering stays stable.
        data = self.function.prepare(
            payload={'ids': [self.blueprint.id]},
            account=self.account,
        )
        prompt = self.function.build_prompt(data, account=self.account)
        self.assertIn(self.blueprint.name, prompt)
        self.assertIn('Home', prompt)
        # The prompt should mention hosting type and objectives in JSON context.
        self.assertIn(self.blueprint.hosting_type, prompt)
        for objective in self.blueprint.config_json.get('objectives', []):
            self.assertIn(objective, prompt)


