from typing import List, Dict, Any, Optional
import threading


_current_generator = threading.local()
_featherui_enabled = False
_featherui_css = ""


def get_current_generator():
    """Get the current thread's HTML generator"""
    if not hasattr(_current_generator, 'generator'):
        _current_generator.generator = HTMLGenerator()
    return _current_generator.generator


def enable_featherui(css_content=""):
    """Enable FeatherUI styling support"""
    global _featherui_enabled, _featherui_css
    _featherui_enabled = True
    _featherui_css = css_content


def is_featherui_enabled():
    """Check if FeatherUI is enabled"""
    return _featherui_enabled


def get_featherui_css():
    """Get FeatherUI CSS content"""
    return _featherui_css


class HTMLGenerator:
    def __init__(self):
        self.elements: List[Dict[str, Any]] = []
        self.container_stack: List[Dict] = []
        self.element_id_counter = 0
    
    def reset(self):
        """Reset the generator for a new render"""
        self.elements = []
        self.container_stack = []
        self.element_id_counter = 0
    
    def get_next_id(self):
        """Get next unique element ID"""
        self.element_id_counter += 1
        return self.element_id_counter
    
    def add_element(self, element_type: str, props: Dict[str, Any]):
        """Add an element to be rendered"""
        # Separate styling props from functional props if FeatherUI is enabled
        if is_featherui_enabled():
            props = self._separate_styling_props(props)
        
        element = {'type': element_type, 'props': props}
        
        if self.container_stack:
            if 'children' not in self.container_stack[-1]:
                self.container_stack[-1]['children'] = []
            self.container_stack[-1]['children'].append(element)
        else:
            self.elements.append(element)
    
    def _separate_styling_props(self, props):
        """Separate styling kwargs from functional props"""
        # These are styling kwargs that should be parsed
        styling_keys = {
            'color', 'bg', 'background', 'padding', 'margin', 'size', 'weight', 
            'font', 'border_radius', 'shadow', 'width', 'height', 'display',
            'flex', 'justify', 'align', 'gap', 'hover_lift', 'opacity',
            'margin_top', 'margin_bottom', 'margin_left', 'margin_right',
            'padding_top', 'padding_bottom', 'padding_left', 'padding_right',
            'border', 'border_color', 'border_width', 'rounded', 'max_width',
            'min_width', 'max_height', 'min_height', 'text_align', 'cursor',
            'position', 'top', 'right', 'bottom', 'left', 'z_index', 'overflow',
            'object_fit', 'transition', 'line_height', 'font_size', 'font_weight',
            'font_family', 'text_transform', 'letter_spacing', 'border_style',
            'box_shadow', 'flex_direction', 'justify_content', 'align_items',
            'grid_columns', 'grid_rows'
        }
        
        style_props = {}
        functional_props = {}
        
        for key, value in props.items():
            if key in styling_keys:
                style_props[key] = value
            else:
                functional_props[key] = value
        
        # Store styling props separately for later parsing
        if style_props:
            functional_props['_featherui_styles'] = style_props
        
        return functional_props
    
    def add_raw_html(self, html: str):
        """Add raw HTML directly"""
        element = {'type': 'raw_html', 'props': {'html': html}}
        
        if self.container_stack:
            if 'children' not in self.container_stack[-1]:
                self.container_stack[-1]['children'] = []
            self.container_stack[-1]['children'].append(element)
        else:
            self.elements.append(element)
    
    def start_container(self, container_type: str, props: Optional[Dict[str, Any]] = None):
        """Start a container element"""
        # Process styling props if FeatherUI is enabled
        processed_props = props or {}
        if is_featherui_enabled() and processed_props:
            processed_props = self._separate_styling_props(processed_props)
        
        container = {
            'type': container_type,
            'props': processed_props,
            'children': []
        }
        self.container_stack.append(container)
    
    def end_container(self):
        """End the current container and add it to parent or root"""
        if not self.container_stack:
            return
        
        container = self.container_stack.pop()
        
        if self.container_stack:
            if 'children' not in self.container_stack[-1]:
                self.container_stack[-1]['children'] = []
            self.container_stack[-1]['children'].append(container)
        else:
            self.elements.append(container)
    
    def generate_html(self, title: str = "FeatherOS App") -> str:
        """Generate complete HTML from elements"""
        body_html = self._render_elements(self.elements)
        
        # Include FeatherUI CSS if enabled
        featherui_css_block = get_featherui_css() if is_featherui_enabled() else ""
        
        html = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    {featherui_css_block}
    <style>
        body {{
            padding: 20px;
            background-color: #f8f9fa;
        }}
        .feather-card {{
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }}
        .feather-alert {{
            padding: 12px 20px;
            border-radius: 6px;
            margin-bottom: 15px;
        }}
        .feather-alert-success {{
            background-color: #d1e7dd;
            border: 1px solid #a3cfbb;
            color: #0a3622;
        }}
        .feather-alert-error {{
            background-color: #f8d7da;
            border: 1px solid #f1aeb5;
            color: #58151c;
        }}
        .feather-alert-warning {{
            background-color: #fff3cd;
            border: 1px solid #ffe69c;
            color: #664d03;
        }}
        .feather-alert-info {{
            background-color: #cff4fc;
            border: 1px solid #9eeaf9;
            color: #055160;
        }}
        .feather-form {{
            max-width: 600px;
        }}
        .feather-table {{
            width: 100%;
            margin-top: 20px;
        }}
    </style>
</head>
<body>
    <div class="container">
        {body_html}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>"""
        return html
    
    def _get_style_attrs(self, props):
        """Extract and parse FeatherUI styles from props"""
        if not is_featherui_enabled() or '_featherui_styles' not in props:
            return '', ''
        
        try:
            # Import here to avoid circular dependency
            import sys
            import os
            plugin_path = os.path.join(os.getcwd(), 'plugins', 'featherui')
            if plugin_path not in sys.path:
                sys.path.insert(0, plugin_path)
            
            from plugins.featherui import parse_component_styles
            
            style_kwargs = props.get('_featherui_styles', {})
            parsed = parse_component_styles(**style_kwargs)
            
            style_attr = f'style="{parsed["style"]}"' if parsed['style'] else ''
            class_attr = f'class="{parsed["class"]}"' if parsed['class'] else ''
            
            return style_attr, class_attr
        except Exception as e:
            # If featherui parsing fails, just skip it
            return '', ''
    
    def _render_elements(self, elements: List[Dict]) -> str:
        """Recursively render elements to HTML"""
        html_parts = []
        
        for element in elements:
            element_type = element['type']
            props = element.get('props', {})
            children = element.get('children', [])
            
            if element_type == 'title':
                level = props.get('level', 1)
                text = props.get('text', '')
                style_attr, class_attr = self._get_style_attrs(props)
                attrs = f'{style_attr} {class_attr}'.strip()
                attrs_str = f' {attrs}' if attrs else ''
                html_parts.append(f'<h{level}{attrs_str}>{text}</h{level}>')
            
            elif element_type == 'text':
                content = props.get('content', '')
                base_classes = 'text-muted' if props.get('muted') else ''
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes properly
                classes_list = []
                if base_classes:
                    classes_list.append(base_classes)
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                
                combined_class = ' '.join(classes_list)
                class_str = f'class="{combined_class}"' if combined_class else ''
                attrs = f'{class_str} {style_attr}'.strip()
                attrs_str = f' {attrs}' if attrs else ''
                html_parts.append(f'<p{attrs_str}>{content}</p>')
            
            elif element_type == 'write':
                content = props.get('content', '')
                style_attr, class_attr = self._get_style_attrs(props)
                attrs = f'{style_attr} {class_attr}'.strip()
                attrs_str = f' {attrs}' if attrs else ''
                html_parts.append(f'<pre{attrs_str}>{content}</pre>')
            
            elif element_type == 'input':
                label = props.get('label', '')
                name = props.get('name', '')
                placeholder = props.get('placeholder', '')
                input_type = props.get('type', 'text')
                required = 'required' if props.get('required') else ''
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['form-control']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr} {required}'.strip()
                html_parts.append(f'''
                    <div class="mb-3">
                        <label class="form-label">{label}</label>
                        <input type="{input_type}" name="{name}" {attrs} placeholder="{placeholder}">
                    </div>
                ''')
            
            elif element_type == 'textarea':
                label = props.get('label', '')
                name = props.get('name', '')
                placeholder = props.get('placeholder', '')
                rows = props.get('rows', 4)
                required = 'required' if props.get('required') else ''
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['form-control']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr} rows="{rows}" {required}'.strip()
                html_parts.append(f'''
                    <div class="mb-3">
                        <label class="form-label">{label}</label>
                        <textarea name="{name}" {attrs} placeholder="{placeholder}"></textarea>
                    </div>
                ''')
            
            elif element_type == 'checkbox':
                label = props.get('label', '')
                name = props.get('name', '')
                checked = 'checked' if props.get('checked') else ''
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['form-check-input']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr} type="checkbox" name="{name}" {checked}'.strip()
                html_parts.append(f'''
                    <div class="form-check mb-3">
                        <input {attrs}>
                        <label class="form-check-label">{label}</label>
                    </div>
                ''')
            
            elif element_type == 'button':
                label = props.get('label', '')
                name = props.get('name', '')
                value = props.get('value', '1')
                btn_type = props.get('type', 'submit')
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['btn', 'btn-primary']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<button type="{btn_type}" name="{name}" value="{value}" {attrs}>{label}</button>')
            
            elif element_type == 'alert':
                message = props.get('message', '')
                alert_type = props.get('type', 'info')
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['feather-alert', f'feather-alert-{alert_type}']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<div {attrs}>{message}</div>')
            
            elif element_type == 'table':
                headers = props.get('headers', [])
                data = props.get('data', [])
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['table', 'table-striped', 'feather-table']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                table_html = f'<table {attrs}><thead><tr>'
                for header in headers:
                    table_html += f'<th>{header}</th>'
                table_html += '</tr></thead><tbody>'
                
                for row in data:
                    table_html += '<tr>'
                    if isinstance(row, dict):
                        for header in headers:
                            table_html += f'<td>{row.get(header, "")}</td>'
                    else:
                        table_html += f'<td>{row}</td>'
                    table_html += '</tr>'
                
                table_html += '</tbody></table>'
                html_parts.append(table_html)
            
            elif element_type == 'card':
                children_html = self._render_elements(children)
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['feather-card']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<div {attrs}>{children_html}</div>')
            
            elif element_type == 'form':
                children_html = self._render_elements(children)
                method = props.get('method', 'POST')
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['feather-form']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'method="{method}" class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<form {attrs}>{children_html}</form>')
            
            elif element_type == 'columns':
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['row']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<div {attrs}>')
                html_parts.append(self._render_elements(children))
                html_parts.append('</div>')
            
            elif element_type == 'column':
                children_html = self._render_elements(children)
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['col']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'<div {attrs}>{children_html}</div>')
            
            elif element_type == 'header':
                text = props.get('text', '')
                level = props.get('level', 2)
                style_attr, class_attr = self._get_style_attrs(props)
                attrs = f'{style_attr} {class_attr}'.strip()
                attrs_str = f' {attrs}' if attrs else ''
                html_parts.append(f'<h{level}{attrs_str}>{text}</h{level}>')
            
            elif element_type == 'metric':
                label = props.get('label', '')
                value = props.get('value', '')
                delta = props.get('delta')
                delta_html = f'<small class="text-muted ms-2">{delta}</small>' if delta else ''
                style_attr, class_attr = self._get_style_attrs(props)
                
                # Combine classes
                classes_list = ['feather-card']
                if class_attr and 'class="' in class_attr:
                    classes_list.append(class_attr.split('"')[1])
                combined_class = ' '.join(classes_list)
                
                attrs = f'class="{combined_class}" {style_attr}'.strip()
                html_parts.append(f'''
                    <div {attrs}>
                        <h6 class="text-muted">{label}</h6>
                        <h2>{value}{delta_html}</h2>
                    </div>
                ''')
            
            elif element_type == 'code':
                content = props.get('content', '')
                language = props.get('language', 'python')
                style_attr, class_attr = self._get_style_attrs(props)
                pre_attrs = f' {style_attr}' if style_attr else ''
                
                # Extract class string from class_attr if it exists
                extra_classes = ''
                if class_attr and 'class="' in class_attr:
                    extra_classes = ' ' + class_attr.split('"')[1]
                code_class = f'language-{language}{extra_classes}'
                html_parts.append(f'<pre{pre_attrs}><code class="{code_class}">{content}</code></pre>')
            
            elif element_type == 'raw_html':
                html_parts.append(props.get('html', ''))
            
            else:
                children_html = self._render_elements(children)
                html_parts.append(f'<div>{children_html}</div>')
        
        return '\n'.join(html_parts)
