"""
JavaScript/TypeScript chunker using Tree-sitter.
"""
from pathlib import Path
from typing import List, Optional, Union
from tree_sitter import Language, Parser

from .schema import CodeChunk, ChunkAST, ChunkSpan, ChunkHierarchy

# JavaScript support flag
HAS_JAVASCRIPT = False

# Try to import JavaScript support
try:
    import tree_sitter_javascript
    HAS_JAVASCRIPT = True
    # Store the module reference
    _TS_JAVASCRIPT = tree_sitter_javascript
except ImportError:
    HAS_JAVASCRIPT = False
    _TS_JAVASCRIPT = None


class JavaScriptChunker:
    """Tree-sitter based chunker for JavaScript/TypeScript"""
    
    def __init__(self):
        self.has_support = False
        self.parser: Optional[Parser] = None
        
        if HAS_JAVASCRIPT and _TS_JAVASCRIPT is not None:
            try:
                # Get the language object from the module
                language = Language(_TS_JAVASCRIPT.language())
                self.parser = Parser()
                self.parser.language = language
                self.has_support = True
            except Exception as e:
                print(f"⚠️ Failed to initialize JavaScript parser: {e}")
                self.has_support = False
        else:
            self.has_support = False
    
    def chunk_file(self, file_path: Union[str, Path]) -> List[CodeChunk]:
        if not self.has_support or self.parser is None:
            raise ImportError(
                "JavaScript support requires tree-sitter-javascript.\n"
                "Install with: pip install 'codeatlas[javascript]' or pip install tree-sitter-javascript"
            )
        
        path_obj = Path(file_path) if not isinstance(file_path, Path) else file_path
        source = path_obj.read_bytes()
        tree = self.parser.parse(source)
        
        chunks: List[CodeChunk] = []
        
        def extract_node(node, depth: int = 0, parent_id: Optional[str] = None):
            # Extract functions and classes
            if node.type in ['function_declaration', 'class_declaration', 'method_definition']:
                code = source[node.start_byte:node.end_byte].decode('utf-8', errors='ignore')
                
                # Get name if available
                name: Optional[str] = None
                for child in node.children:
                    if child.type in ['identifier', 'property_identifier']:
                        try:
                            name = child.text.decode('utf-8', errors='ignore')
                        except:
                            name = str(child.text)
                        break
                
                # Determine chunk type
                if 'function' in node.type:
                    chunk_type = 'function'
                elif 'class' in node.type:
                    chunk_type = 'class'
                else:
                    chunk_type = 'method'
                
                chunk = CodeChunk(
                    chunk_id=f"js_{node.start_byte:08x}",
                    file_path=str(path_obj),
                    language="javascript",
                    chunk_type=chunk_type,
                    code=code,
                    ast=ChunkAST(
                        symbol_type=chunk_type,
                        name=name,
                        parent=parent_id
                    ),
                    span=ChunkSpan(
                        start_byte=node.start_byte,
                        end_byte=node.end_byte,
                        start_line=node.start_point[0] + 1,
                        end_line=node.end_point[0] + 1
                    ),
                    hierarchy=ChunkHierarchy(
                        parent_id=parent_id,
                        depth=depth,
                        is_primary=True
                    )
                )
                chunks.append(chunk)
                
                # New parent for children
                new_parent = chunk.chunk_id
                parent_id = new_parent
            
            # Recurse into children
            for child in node.children:
                extract_node(child, depth + 1, parent_id)
        
        if tree and tree.root_node:
            extract_node(tree.root_node)
        return chunks


def chunk_javascript_file(file_path: Union[str, Path]) -> List[CodeChunk]:
    """Public API for JavaScript chunking"""
    chunker = JavaScriptChunker()
    if chunker.has_support:
        return chunker.chunk_file(file_path)
    return []