"""
代码格式化工具类，支持多种语言的代码美化功能
"""

import re
import json
from typing import Any, Optional, Dict
from xml.dom import minidom
from lxml import html, etree


class CodeFormatter:
    """代码格式化器，支持多种编程语言和标记语言的格式化"""

    @staticmethod
    def format_code(content: str, language: str = "text", beautify: bool = True) -> str:
        """格式化代码内容"""
        if not content or not isinstance(content, str):
            return str(content) if content else ""

        if not beautify:
            return content

        try:
            if language.lower() in ['json']:
                return CodeFormatter._format_json(content)
            elif language.lower() in ['html', 'xml']:
                return CodeFormatter._format_html(content)
            elif language.lower() in ['css']:
                return CodeFormatter._format_css(content)
            elif language.lower() in ['javascript', 'js']:
                return CodeFormatter._format_javascript(content)
            elif language.lower() in ['python', 'py']:
                return CodeFormatter._format_python(content)
            else:
                return content
        except Exception:
            return content

    @staticmethod
    def _format_json(content: str) -> str:
        """格式化JSON内容"""
        try:
            parsed = json.loads(content)
            return json.dumps(parsed, ensure_ascii=False, indent=2, separators=(',', ': '))
        except (json.JSONDecodeError, TypeError):
            return content

    @staticmethod
    def _format_html(content: str) -> str:
        """格式化HTML内容"""
        try:
            if content.strip().startswith('<!DOCTYPE') or '<html' in content.lower():
                doc = html.fromstring(content)
                return etree.tostring(doc, pretty_print=True, encoding='unicode')
            else:
                doc = html.fragment_fromstring(content, create_parent=True)
                result = etree.tostring(doc, pretty_print=True, encoding='unicode')
                if result.startswith('<div>') and result.endswith('</div>'):
                    result = result[5:-6]
                return result
        except Exception:
            try:
                dom = minidom.parseString(f"<root>{content}</root>")
                pretty = dom.documentElement.toprettyxml(indent="  ")
                lines = pretty.split('\n')
                return '\n'.join(line for line in lines[2:-2] if line.strip())
            except Exception:
                return content

    @staticmethod
    def _format_css(content: str) -> str:
        """简单的CSS格式化"""
        try:
            content = re.sub(r'\s*{\s*', ' {\n  ', content)
            content = re.sub(r';\s*', ';\n  ', content)
            content = re.sub(r'\s*}\s*', '\n}\n\n', content)
            content = re.sub(r'\n\s*\n\s*\n', '\n\n', content)
            return content.strip()
        except Exception:
            return content

    @staticmethod
    def _format_javascript(content: str) -> str:
        """简单的JavaScript格式化"""
        try:
            content = re.sub(r'\s*{\s*', ' {\n  ', content)
            content = re.sub(r';\s*', ';\n  ', content)
            content = re.sub(r'\s*}\s*', '\n}\n', content)
            content = re.sub(r'function\s+(\w+)\s*\(', r'function \1(', content)
            return content.strip()
        except Exception:
            return content

    @staticmethod
    def _format_python(content: str) -> str:
        """Python代码基本格式化"""
        try:
            lines = content.split('\n')
            formatted_lines = []
            indent_level = 0

            for line in lines:
                stripped = line.strip()
                if not stripped:
                    formatted_lines.append('')
                    continue

                if stripped.endswith(':'):
                    formatted_lines.append('    ' * indent_level + stripped)
                    indent_level += 1
                elif stripped in ['pass', 'break', 'continue'] or stripped.startswith('return'):
                    formatted_lines.append('    ' * indent_level + stripped)
                elif stripped.startswith(('elif', 'else', 'except', 'finally')):
                    formatted_lines.append('    ' * (indent_level - 1) + stripped)
                    if stripped.endswith(':'):
                        pass
                else:
                    if indent_level > 0 and not line.startswith('    ' * indent_level):
                        indent_level = max(0, indent_level - 1)
                    formatted_lines.append('    ' * indent_level + stripped)

            return '\n'.join(formatted_lines)
        except Exception:
            return content

    @staticmethod
    def get_supported_languages() -> Dict[str, str]:
        """获取支持的语言列表"""
        return {
            'text': 'Plain Text', 'json': 'JSON', 'html': 'HTML', 'xml': 'XML',
            'css': 'CSS', 'javascript': 'JavaScript', 'js': 'JavaScript',
            'python': 'Python', 'py': 'Python', 'sql': 'SQL',
            'yaml': 'YAML', 'yml': 'YAML', 'markdown': 'Markdown', 'md': 'Markdown',
            'bash': 'Shell Script', 'sh': 'Shell Script', 'dockerfile': 'Dockerfile',
            'go': 'Go', 'java': 'Java', 'cpp': 'C++', 'c': 'C', 'rust': 'Rust',
            'php': 'PHP', 'ruby': 'Ruby', 'swift': 'Swift', 'kotlin': 'Kotlin',
            'typescript': 'TypeScript', 'ts': 'TypeScript'
        }

    @staticmethod
    def auto_detect_language(content: str) -> str:
        """自动检测代码语言类型"""
        if not content or not isinstance(content, str):
            return 'text'

        content = content.strip()

        if (content.startswith('{') and content.endswith('}')) or \
           (content.startswith('[') and content.endswith(']')):
            try:
                json.loads(content)
                return 'json'
            except:
                pass

        if ('<html' in content.lower() or
            content.startswith('<!DOCTYPE') or
            re.search(r'<[a-zA-Z][^>]*>', content)):
            return 'html'

        if re.search(r'[a-zA-Z-]+\s*:\s*[^;]+;', content) and '{' in content:
            return 'css'

        if any(keyword in content for keyword in ['function', 'var ', 'let ', 'const ', '=>']):
            return 'javascript'

        if any(keyword in content for keyword in ['def ', 'import ', 'from ', 'if __name__']):
            return 'python'

        if any(keyword.upper() in content.upper() for keyword in ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'CREATE TABLE']):
            return 'sql'

        return 'text'


def format_code(content: str, language: str = "text", beautify: bool = True) -> str:
    """便捷函数：格式化代码内容"""
    return CodeFormatter.format_code(content, language, beautify)
