#!/usr/bin/env python3
"""Escribe la forma TRANSCRITA en la ocurrencia que senala el alineador.

Combina las dos tecnicas que hicieron falta hoy, cada una aportando lo que la
otra no tiene:

  - del CONTEXTO del alineador ('... conocido como [[venkatacala]] en el sur'),
    la POSICION exacta dentro del fichero;
  - de la TRANSCRIPCION por imagen, la FORMA con sus diacriticos
    ('Vyeṅkaṭācala'), que el OCR no puede dar porque los pierde.

Por separado ninguna basta: el aplicador por contexto escribiria la lectura del
OCR y borraria los diacriticos; el aplicador por transcripcion solo puede actuar
cuando la palabra aparece una unica vez en el fichero, y 94 casos aparecen entre
2 y 48 veces.

Si el contexto no da una posicion unica, no se escribe nada y queda anotado.

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

HERE = pathlib.Path(__file__).resolve().parent
REPO = pathlib.Path('/Users/jaganat/git_projects/vedabase-original')
LOTES = HERE / 'lotes_imagen'
FECHA = '2026-08-09'
sys.path.insert(0, str(HERE))
from aplicar_posicional import normaliza


def main():
    aplicar = '--aplicar' in sys.argv
    filas = []
    for f in sorted(LOTES.glob('resultado*.json')):
        n = int(re.search(r'(\d+)', f.name).group(1))
        if n < 60: continue
        for x in json.load(open(f, encoding='utf-8')):
            if x.get('veredicto') == 'TRANSCRITO' and x.get('impreso') \
               and x['impreso'] != x['palabra_repo']:
                filas.append(x)

    # solo interesan las que siguen sin aplicar: la palabra aun esta en el fichero
    quedan = []
    for x in filas:
        p = REPO / x['file']
        if not p.exists(): continue
        t = p.read_text(encoding='utf-8')
        if len(re.findall(re.escape(x['palabra_repo']), t)) > 1:
            quedan.append(x)
    print('pendientes con varias ocurrencias:', len(quedan))

    # contexto del alineador para cada (fichero, lectura del OCR)
    quiero = {(x['file'], x['lectura_ocr'].lower()) for x in quedan}
    ctxs = collections.defaultdict(list)
    for cf in sorted((HERE / 'out_surya').glob('*.candidates.jsonl')):
        for l in open(cf, encoding='utf-8'):
            d = json.loads(l)
            k = (d['file'], (d.get('scan') or '').strip().lower())
            if k in quiero and d.get('context'):
                ctxs[k].append(d['context'])

    # DEDUPLICAR. Sin esto, varios resultados del mismo (fichero, palabra) casan
    # con el MISMO contexto y se escriben uno encima de otro: 'semen'->'semina'
    # aplicado cinco veces dejo 'seminaaaaa' (2026-08-09).
    vistos = set(); unicos = []
    for x in quedan:
        k = (x['file'], x['palabra_repo'], x['impreso'])
        if k in vistos: continue
        vistos.add(k); unicos.append(x)
    if len(unicos) != len(quedan):
        print(f'  duplicados descartados: {len(quedan) - len(unicos)}')
    quedan = unicos

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

    for fich, lista in sorted(porfich.items()):
        p = REPO / fich
        txt = p.read_text(encoding='utf-8')
        pend = []
        for x in lista:
            hecho = False
            for ctx in ctxs.get((fich, x['lectura_ocr'].lower()), []):
                m = re.search(r'\[\[(.+?)\]\]', ctx)
                if not m: continue
                izq = ctx[:m.start()].strip(); der = ctx[m.end():].strip()
                pal = m.group(1).strip()
                buscado = ' '.join(y for y in (izq, pal, der) if y)
                norm, mapa = normaliza(txt)
                pos = [y.start() for y in re.finditer(re.escape(buscado), norm)]
                if len(pos) != 1: continue
                ini_n = pos[0] + (len(izq) + 1 if izq else 0)
                ini, fin = mapa[ini_n], mapa[ini_n + len(pal) - 1] + 1
                real = txt[ini:fin]
                if normaliza(real)[0] != pal: continue
                pend.append((ini, fin, real, x['impreso'], x))
                hecho = True
                break
            if not hecho:
                res['el contexto tampoco situa la palabra'] += 1
                verd.append((x, 'ABIERTO', f"el impreso dice {x['impreso']!r} (p.{x['pagina']}), pero ni la "
                                           f"unicidad ni el contexto del alineador permiten situar cual de "
                                           f"las apariciones es: hace falta hacerlo a mano"))
        ocupados = []
        for ini, fin, real, nuevo, x in sorted(pend, key=lambda y: -y[0]):
            if any(not (fin <= a or ini >= b) for a, b in ocupados):
                res['posicion ya ocupada por otro cambio'] += 1; continue
            ocupados.append((ini, fin))
            txt = txt[:ini] + nuevo + txt[fin:]
            hechas.append({'file': fich, 'antes': real, 'despues': nuevo,
                           'page': x['pagina'], 'nota': x.get('nota', '')[:200]})
        if aplicar and pend: p.write_text(txt, encoding='utf-8')

    res['APLICADO en la posicion del contexto'] = len(hechas)
    for k, v in res.most_common(): print(f'  {v:5}  {k}')
    if aplicar:
        json.dump(hechas, open(HERE / 'aplicadas_transcripcion_pos.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"forma TRANSCRITA de la imagen (p.{h['page']}) escrita en la "
                                              f"ocurrencia que senala el contexto del alineador: {h['nota']}",
                                     "fecha": FECHA}, ensure_ascii=False) + '\n')
            for x, est, raz in verd:
                fh.write(json.dumps({"repo": x['palabra_repo'].lower(), "scan": x['impreso'].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())
