from __future__ import annotations

from pathlib import Path
from typing import Iterable

import bibtexparser
from bibtexparser.bparser import BibTexParser
from bibtexparser.bwriter import BibTexWriter

from .types import EntryResult


def apply_bibtex_patches(
    source_path: str,
    results: Iterable[EntryResult],
    out_path: str,
    apply_fixes: bool,
    overwrite_threshold: float,
) -> None:
    content = Path(source_path).read_text(encoding="utf-8")
    parser = BibTexParser(common_strings=True)
    bib_db = bibtexparser.loads(content, parser=parser)

    result_map = {result.ref_id: result for result in results}
    for entry in bib_db.entries:
        entry_id = entry.get("ID")
        if not entry_id:
            continue
        result = result_map.get(entry_id)
        if not result or not result.patch:
            continue
        allow_overwrite = apply_fixes and result.score >= overwrite_threshold and result.verdict == "VERIFIED"
        for key, value in result.patch.items():
            if key not in entry or not entry.get(key):
                entry[key] = value
            elif allow_overwrite:
                entry[key] = value

    writer = BibTexWriter()
    writer.indent = "  "
    writer.order_entries_by = None
    updated = writer.write(bib_db)
    Path(out_path).write_text(updated, encoding="utf-8")
