# Flyto2 Core - Source Available License
# Copyright (c) 2025 Flyto2. All Rights Reserved.
#
# This source code is licensed under the Flyto2 Source Available License v1.0.
# Commercial use requires a license. See LICENSE for details.

"""
Web Scrape to JSON Composite Module

Scrapes a webpage and outputs structured JSON data.
Auto-derives connection types from steps.
"""
from ..base import CompositeModule, register_composite


@register_composite(
    module_id='composite.browser.scrape_to_json',
    label='Scrape Web to JSON',
    label_key='modules.composite.browser.scrape_to_json.label',
    description='Scrape a webpage and output structured JSON data',
    description_key='modules.composite.browser.scrape_to_json.description',
    icon='FileJson',
    color='#10B981',

    steps=[
        {
            'id': 'launch',
            'module': 'browser.launch',
            'params': {'headless': True}
        },
        {
            'id': 'goto',
            'module': 'browser.goto',
            'params': {'url': '${params.url}'}
        },
        {
            'id': 'wait',
            'module': 'browser.wait',
            'params': {
                'selector': '${params.wait_selector}',
                'timeout': 10000
            },
            'on_error': 'continue'
        },
        {
            'id': 'extract_titles',
            'module': 'browser.extract',
            'params': {
                'selector': '${params.title_selector}',
                'attribute': 'textContent',
                'multiple': True
            }
        },
        {
            'id': 'extract_links',
            'module': 'browser.extract',
            'params': {
                'selector': '${params.link_selector}',
                'attribute': 'href',
                'multiple': True
            },
            'on_error': 'continue'
        },
        {
            'id': 'extract_content',
            'module': 'browser.extract',
            'params': {
                'selector': '${params.content_selector}',
                'attribute': 'textContent',
                'multiple': True
            },
            'on_error': 'continue'
        },
        {
            'id': 'close',
            'module': 'browser.close',
            'params': {}
        }
    ],

    params_schema={
        'url': {
            'type': 'string',
            'label': 'URL',
            'required': True,
            'placeholder': 'https://example.com'
        },
        'title_selector': {
            'type': 'string',
            'label': 'Title Selector',
            'required': True,
            'placeholder': 'h1, h2, .title'
        },
        'link_selector': {
            'type': 'string',
            'label': 'Link Selector',
            'default': 'a',
            'placeholder': 'a.item-link'
        },
        'content_selector': {
            'type': 'string',
            'label': 'Content Selector',
            'default': 'p',
            'placeholder': '.content, p'
        },
        'wait_selector': {
            'type': 'string',
            'label': 'Wait Selector',
            'default': 'body',
            'placeholder': 'body'
        }
    },

    output_schema={
        'status': {'type': 'string', 'description': 'Operation status (success/error)'},
        'url': {'type': 'string', 'description': 'URL address'},
        'data': {
            'type': 'object',
            'properties': {
                'titles': {'type': 'array', 'description': 'The titles'},
                'links': {'type': 'array', 'description': 'The links'},
                'content': {'type': 'array', 'description': 'Content returned by the operation'}
            }
        }
    },

    timeout=60,
    retryable=True,
    max_retries=2,
)
class WebScrapeToJson(CompositeModule):
    """Web Scrape to JSON - extracts titles, links, and content from a webpage"""

    def _build_output(self, metadata):
        """Build structured JSON output from step results"""
        return {
            'status': 'success',
            'url': self.params.get('url', ''),
            'data': {
                'titles': self.step_results.get('extract_titles', {}).get('data', []),
                'links': self.step_results.get('extract_links', {}).get('data', []),
                'content': self.step_results.get('extract_content', {}).get('data', [])
            }
        }
