from pathlib import Path

from c2m_by_nery.core.git_metadata import GitMetadata

DOCLING_EXTENSIONS = {
    ".pdf": "pdf",
    ".docx": "docx",
    ".pptx": "pptx",
    ".html": "html",
    ".htm": "html",
    ".md": "md",
    ".csv": "csv",
    ".xlsx": "xlsx",
    ".asciidoc": "asciidoc",
    ".adoc": "asciidoc",
}

CODE_LANGUAGES = {
    ".py": "python",
    ".js": "javascript",
    ".ts": "typescript",
    ".tsx": "tsx",
    ".jsx": "jsx",
    ".java": "java",
    ".kt": "kotlin",
    ".rs": "rust",
    ".go": "go",
    ".rb": "ruby",
    ".php": "php",
    ".c": "c",
    ".cpp": "cpp",
    ".h": "c",
    ".hpp": "cpp",
    ".cs": "csharp",
    ".swift": "swift",
    ".sh": "bash",
    ".bash": "bash",
    ".zsh": "bash",
    ".yaml": "yaml",
    ".yml": "yaml",
    ".json": "json",
    ".toml": "toml",
    ".xml": "xml",
    ".sql": "sql",
    ".r": "r",
    ".R": "r",
    ".scala": "scala",
    ".lua": "lua",
    ".vue": "vue",
    ".svelte": "svelte",
}


def generate_frontmatter(
    rel_path: str,
    file_path: Path,
    git_meta: GitMetadata,
    part: int | None = None,
    total_parts: int | None = None,
    include_frontmatter: bool = True,
) -> str:
    if not include_frontmatter:
        return ""
    link = file_path.as_uri()
    path_field = rel_path
    if part is not None:
        if total_parts is not None and total_parts > 1:
            path_field = f"{rel_path} (part {part + 1}/{total_parts})"
        else:
            path_field = f"{rel_path} (part {part + 1})"
    lines = [
        "---",
        f"Project: {git_meta.get('project', 'unknown')}",
        f"Branch: {git_meta.get('branch', 'unknown')}",
        f"Commit: {git_meta.get('commit', 'unknown')}",
        f"Path: {path_field}",
        f"Link: {link}",
        "---",
        "",
    ]
    return "\n".join(lines)


def _convert_with_docling(filepath: Path) -> str:
    from docling.document_converter import DocumentConverter
    from docling.document_converter import ConversionError as DoclingConversionError

    try:
        converter = DocumentConverter()
        result = converter.convert(str(filepath))
        return result.document.export_to_markdown()
    except DoclingConversionError:
        raise
    except Exception as e:
        raise RuntimeError(f"Docling conversion failed: {e}") from e


def _convert_plain_text(filepath: Path) -> str:
    content = filepath.read_text(encoding="utf-8", errors="replace")
    ext = filepath.suffix.lower()
    lang = CODE_LANGUAGES.get(ext, "text")
    return f"```{lang}\n{content}\n```"


def convert_file_to_markdown(filepath: Path) -> str:
    ext = filepath.suffix.lower()
    if ext in DOCLING_EXTENSIONS:
        return _convert_with_docling(filepath)
    return _convert_plain_text(filepath)
