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


_current_generator = threading.local()


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


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"""
        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 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"""
        container = {
            'type': container_type,
            'props': props or {},
            '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)
        
        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">
    <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 _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', '')
                html_parts.append(f'<h{level}>{text}</h{level}>')
            
            elif element_type == 'text':
                content = props.get('content', '')
                classes = 'text-muted' if props.get('muted') else ''
                html_parts.append(f'<p class="{classes}">{content}</p>')
            
            elif element_type == 'write':
                content = props.get('content', '')
                html_parts.append(f'<pre>{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 ''
                html_parts.append(f'''
                    <div class="mb-3">
                        <label class="form-label">{label}</label>
                        <input type="{input_type}" name="{name}" class="form-control" placeholder="{placeholder}" {required}>
                    </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 ''
                html_parts.append(f'''
                    <div class="mb-3">
                        <label class="form-label">{label}</label>
                        <textarea name="{name}" class="form-control" rows="{rows}" placeholder="{placeholder}" {required}></textarea>
                    </div>
                ''')
            
            elif element_type == 'checkbox':
                label = props.get('label', '')
                name = props.get('name', '')
                checked = 'checked' if props.get('checked') else ''
                html_parts.append(f'''
                    <div class="form-check mb-3">
                        <input class="form-check-input" type="checkbox" name="{name}" {checked}>
                        <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')
                html_parts.append(f'<button type="{btn_type}" name="{name}" value="{value}" class="btn btn-primary">{label}</button>')
            
            elif element_type == 'alert':
                message = props.get('message', '')
                alert_type = props.get('type', 'info')
                html_parts.append(f'<div class="feather-alert feather-alert-{alert_type}">{message}</div>')
            
            elif element_type == 'table':
                headers = props.get('headers', [])
                data = props.get('data', [])
                
                table_html = '<table class="table table-striped feather-table"><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)
                html_parts.append(f'<div class="feather-card">{children_html}</div>')
            
            elif element_type == 'form':
                children_html = self._render_elements(children)
                method = props.get('method', 'POST')
                html_parts.append(f'<form method="{method}" class="feather-form">{children_html}</form>')
            
            elif element_type == 'columns':
                html_parts.append('<div class="row">')
                html_parts.append(self._render_elements(children))
                html_parts.append('</div>')
            
            elif element_type == 'column':
                children_html = self._render_elements(children)
                html_parts.append(f'<div class="col">{children_html}</div>')
            
            elif element_type == 'header':
                text = props.get('text', '')
                level = props.get('level', 2)
                html_parts.append(f'<h{level}>{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 ''
                html_parts.append(f'''
                    <div class="feather-card">
                        <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')
                html_parts.append(f'<pre><code class="language-{language}">{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)
