#!/usr/bin/env python3
"""Cierra la cola de candidatos cuyo contexto no daba una posicion unica.

Tres situaciones distintas, y solo una permite escribir:

  YA APLICADO   la forma del repo ya no esta en el fichero: el cambio se hizo en
                una pasada anterior. Se cierra como APLICADO, sin tocar nada.
  UNICA         la forma del repo aparece EXACTAMENTE una vez en el fichero.
                Aunque el contexto del alineador no casara (suele ser porque el
                texto del repo difiere en puntuacion o cursivas), la posicion es
                inequivoca y el veredicto de imagen la respalda. Se aplica ahi.
  VARIAS        aparece dos o mas veces y no hay forma de saber cual miro el
                agente. Queda ABIERTO con el motivo escrito. No se inventa.

Se mantienen los guardarrailes del aplicador principal: el campo `scan` tiene
que ser UNA palabra alfabetica (no es texto publicable: viene normalizado y a
veces con el titulillo pegado) y no puede quitar diacriticos.

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

HERE = pathlib.Path(__file__).resolve().parent
REPO = pathlib.Path('/Users/jaganat/git_projects/vedabase-original')
FECHA = '2026-08-09'
LIMPIA = re.compile(r"[A-Za-zÀ-ɏḀ-ỿ'-]+")


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_sin_posicion.json', encoding='utf-8'))
    vistos = set(); unicos = []
    for x in casos:
        k = (x['file'], x['repo'].lower(), x['scan'].lower(), x['page'])
        if k in vistos: continue
        vistos.add(k); unicos.append(x)
    print(f'casos: {len(casos)} | sin duplicados: {len(unicos)}')

    res = collections.Counter(); hechas = []; verd = []
    porfich = collections.defaultdict(list)
    for x in unicos: porfich[x['file']].append(x)

    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 in lista:
            ms = [m for m in re.finditer(rf'\b{re.escape(x["repo"])}\b', txt, re.I)]
            if not ms:
                res['YA APLICADO en una pasada anterior'] += 1
                verd.append((x, 'APLICADO', 'la forma del repo ya no esta en el fichero: '
                                            'el cambio se aplico en una pasada anterior'))
                continue
            if len(ms) > 1:
                res['VARIAS ocurrencias: no se puede situar'] += 1
                verd.append((x, 'ABIERTO', f'el veredicto de imagen confirma el impreso, pero la forma '
                                           f'aparece {len(ms)} veces en el fichero y el contexto del '
                                           f'alineador no casa: hace falta situarla a mano'))
                continue
            if not LIMPIA.fullmatch(x['scan']):
                res['el scan no es una palabra limpia'] += 1
                verd.append((x, 'ABIERTO', 'la lectura del OCR no es una palabra limpia (viene '
                                           'normalizada, a veces con el titulillo pegado): no es texto publicable'))
                continue
            real = ms[0].group(0)
            nuevo = x['scan'].capitalize() if real[:1].isupper() else x['scan']
            if dia(nuevo) < dia(real):
                res['quitaria diacriticos'] += 1
                verd.append((x, 'ABIERTO', 'la lectura del OCR viene sin diacriticos y el fichero si '
                                           'los tiene: hace falta la forma acentuada del impreso'))
                continue
            pend.append((ms[0].start(), ms[0].end(), real, nuevo, x))
        for ini, fin, real, nuevo, x in sorted(pend, key=lambda y: -y[0]):
            txt = txt[:ini] + nuevo + txt[fin:]
            hechas.append({'file': fich, 'antes': real, 'despues': nuevo,
                           'page': x['page'], 'nota': x['nota'][:200]})
        if aplicar and pend: p.write_text(txt, encoding='utf-8')

    res['APLICADO en su unica ocurrencia'] = len(hechas)
    for k, v in res.most_common(): print(f'  {v:5}  {k}')
    if aplicar:
        json.dump(hechas, open(HERE / 'aplicadas_sin_posicion.json', 'w'), ensure_ascii=False, indent=1)
        with open(HERE / 'verdicts.jsonl', 'a') as fh:
            for h in hechas:
                fh.write(json.dumps({"repo": h['antes'].lower(), "scan": h['despues'].lower(),
                                     "estado": "VERIFICADO",
                                     "razon": f"adjudicado por IMAGEN (p.{h['page']}) y aplicado en la unica "
                                              f"ocurrencia del fichero: {h['nota']}",
                                     "fecha": FECHA}, ensure_ascii=False) + '\n')
            for x, est, raz in verd:
                fh.write(json.dumps({"repo": x['repo'].lower(), "scan": x['scan'].lower(),
                                     "estado": est, "razon": raz, "fecha": FECHA},
                                    ensure_ascii=False) + '\n')
        print('veredictos escritos:', len(hechas) + len(verd))
    return 0


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