#!/usr/bin/env python3
"""Resuelve la cola de casos que el guardarrail de diacriticos aparto.

El problema. El campo `scan` de los candidatos es la normalizacion del
alineador: sin diacriticos. Aplicarlo destruiria los del repo ('Gosvāmī' ->
'Gosvamin'). Pero el candidato SI era bueno: el impreso dice «Gosvāmin», con
diacriticos, y la diferencia real es la -n final.

La solucion. El agente que miro la pagina CITO la frase del impreso en su nota,
y ahi la palabra aparece bien acentuada. Se busca en la nota la palabra cuya
version sin diacriticos coincide con la del OCR, y esa es la forma a escribir.

Filtro imprescindible: la forma de la nota no puede tener MENOS diacriticos que
la del fichero. Algunas notas transcriben sin acentos (o el libro no los usa, y
entonces el caso hay que mirarlo aparte). Sin este filtro se volveria a perder
lo que el guardarrail salvo.

Uso: python3 aplicar_diacriticos.py [--aplicar]
"""
import json, re, sys, unicodedata, pathlib, collections

HERE = pathlib.Path(__file__).resolve().parent
REPO = pathlib.Path('/Users/jaganat/git_projects/vedabase-original')
sys.path.insert(0, str(HERE))
from aplicar_posicional import normaliza
FECHA = '2026-08-09'
PAL = re.compile(r"[A-Za-zÀ-ɏḀ-ỿ'’-]+")


def sd(s):
    return ''.join(c for c in unicodedata.normalize('NFD', s)
                   if unicodedata.category(c) != 'Mn').lower()


def dia(s):
    return sum(1 for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) == 'Mn')


def main():
    aplicar = '--aplicar' in sys.argv
    casos = json.load(open(HERE / 'pendientes_diacriticos.json', encoding='utf-8'))
    res = collections.Counter(); hechas = []; quedan = []

    porfich = collections.defaultdict(list)
    for x in casos:
        obj = sd(x['scan_ocr'])
        cand = [w for w in PAL.findall(x['nota']) if sd(w) == obj]
        if not cand:
            res['la nota no cita la forma acentuada'] += 1; quedan.append(x); continue
        forma = cand[0]
        if dia(forma) < dia(x['antes']):
            res['la nota tambien viene sin diacriticos'] += 1; quedan.append(x); continue
        porfich[x['file']].append((x, forma))

    for fich, lista in sorted(porfich.items()):
        p = REPO / fich
        if not p.exists(): res['sin fichero'] += len(lista); continue
        txt = p.read_text(encoding='utf-8')
        pend = []
        for x, forma in lista:
            # se localiza la ocurrencia exacta por el texto del propio fichero
            ms = [m for m in re.finditer(re.escape(x['antes']), txt)]
            if len(ms) != 1:
                res['la palabra no es unica en el fichero'] += 1; quedan.append(x); continue
            nuevo = forma if x['antes'][:1].islower() or forma[:1].isupper() else forma.capitalize()
            pend.append((ms[0].start(), ms[0].end(), x['antes'], nuevo, x))
        for ini, fin, antes, nuevo, x in sorted(pend, key=lambda y: -y[0]):
            txt = txt[:ini] + nuevo + txt[fin:]
            hechas.append({'file': fich, 'antes': antes, 'despues': nuevo,
                           'page': x['page'], 'nota': x['nota'][:200]})
        if aplicar and pend: p.write_text(txt, encoding='utf-8')

    res['APLICADO con la forma acentuada de la nota'] = len(hechas)
    for k, v in res.most_common(): print(f'  {v:5}  {k}')
    if aplicar:
        json.dump(hechas, open(HERE / 'aplicadas_diacriticos.json', 'w'), ensure_ascii=False, indent=1)
        json.dump(quedan, open(HERE / 'pendientes_diacriticos.json', 'w'), ensure_ascii=False, indent=1)
        with open(HERE / 'verdicts.jsonl', 'a') as fh:
            for h in hechas:
                fh.write(json.dumps({"repo": sd(h['antes']), "scan": sd(h['despues']),
                                     "estado": "VERIFICADO",
                                     "razon": f"adjudicado por IMAGEN (p.{h['page']}) y escrito con la forma "
                                              f"ACENTUADA que cita la nota, no con la del OCR: {h['nota']}",
                                     "fecha": FECHA}, ensure_ascii=False) + '\n')
        print('veredictos escritos:', len(hechas), '| siguen pendientes:', len(quedan))
    return 0


if __name__ == '__main__':
    sys.exit(main())
