import os
from typing import List, Dict, Any

def load_pdf(path: str) -> List[Dict[str, Any]]:
    """
    Stub for loading PDF. If pypdf is installed, use it. Otherwise return a stub text.
    """
    if not os.path.exists(path):
        return [{"content": f"File not found: {path}", "metadata": {"source": path}}]
        
    try:
        import PyPDF2
        docs = []
        with open(path, "rb") as f:
            reader = PyPDF2.PdfReader(f)
            for i, page in enumerate(reader.pages):
                text = page.extract_text()
                if text:
                    docs.append({
                        "content": text,
                        "metadata": {"source": path, "page": i}
                    })
        return docs
    except ImportError:
        return [{"content": f"PDF Stub Content from {path} (PyPDF2 not installed)", "metadata": {"source": path, "note": "PyPDF2 not installed"}}]
    except Exception as e:
        return [{"content": f"Error loading PDF: {str(e)}", "metadata": {"source": path}}]

def load_markdown(path: str) -> List[Dict[str, Any]]:
    """
    Loads markdown and splits by headers (e.g., lines starting with #).
    """
    if not os.path.exists(path):
        return []
        
    with open(path, "r", encoding="utf-8", errors="ignore") as f:
        lines = f.readlines()
        
    chunks = []
    current_header = ""
    current_content = []
    
    for line in lines:
        if line.startswith("#"):
            if current_content:
                chunks.append({
                    "content": "".join(current_content).strip(),
                    "metadata": {"source": path, "header": current_header}
                })
            current_header = line.strip()
            current_content = [line]
        else:
            current_content.append(line)
            
    if current_content:
        chunks.append({
            "content": "".join(current_content).strip(),
            "metadata": {"source": path, "header": current_header}
        })
        
    return chunks

def load_code_dir(path: str) -> List[Dict[str, Any]]:
    """
    Loads code files from a directory recursively.
    """
    docs = []
    if not os.path.isdir(path):
        return []
        
    valid_extensions = {".py", ".js", ".ts", ".md", ".txt", ".json", ".html", ".css"}
    for root, _, files in os.walk(path):
        for file in files:
            ext = os.path.splitext(file)[1].lower()
            if ext in valid_extensions:
                file_path = os.path.join(root, file)
                try:
                    with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                        content = f.read()
                    if content.strip():
                        docs.append({
                            "content": content,
                            "metadata": {"source": file_path, "type": "code"}
                        })
                except Exception:
                    # Skip files that can't be read
                    pass
    return docs
