/* Opcional: solo borradores de HOMOLOGACIÓN. No modificar los cuatro archivos base.
 * GmailApp exige permiso amplio de Gmail: no existe aquí una restricción OAuth
 * a solo borradores. Este código únicamente usa createDraft y getId.
 */
var CORREO = Object.freeze({owner:'CORREO_HOMO_OWNER_V1',prefix:'CORREO_HOMO_V1_',
  warning:'PRUEBA SIN VALIDEZ FISCAL'});

function correoError_(message){var e=new Error(message);e.correoSafe=true;throw e;}
function correoUi_(fn){
  var text;
  try{text=fn();}catch(e){text=e.correoSafe?e.message:
    'Operación detenida. Revisá propietario, permisos, selección y diario. Si intentaste preparar un borrador, consultá Estado / ayuda antes de volver a intentar.';}
  // Siempre fuera de setupLocked_: los diálogos suspenden la ejecución.
  SpreadsheetApp.getUi().alert(String(text));
}
function correoOwner_(install){
  var ss=setupOwner_(),effective=Session.getEffectiveUser().getEmail(),
    active=Session.getActiveUser().getEmail(),p=setupProps_(),pinned=p.getProperty(CORREO.owner);
  if(!active||active!==effective)correoError_('Usá directamente la cuenta propietaria. No se pudo verificar quién ejecuta la acción.');
  var binding=ss.getId()+'|'+effective;
  if(pinned&&pinned!==binding)correoError_('Cambió la cuenta propietaria o la planilla. Correo bloqueado: no reinicialices sus registros.');
  if(!pinned){
    if(!install)correoError_('Primero ejecutá correoInstalar manualmente desde Apps Script.');
    p.setProperty(CORREO.owner,binding);
    if(p.getProperty(CORREO.owner)!==binding)correoError_('No se pudo conservar la instalación. No se creó ningún borrador.');
  }
  return ss;
}
function correoMenu_(){SpreadsheetApp.getUi().createMenu('Correo · Pruebas')
  .addItem('Preparar borrador de la fila','correoPrepararSeleccion')
  .addItem('Estado / ayuda de la fila','correoEstadoAyuda').addToUi();}
function correoInstalar(){correoUi_(function(){
  var message=setupLocked_(function(){
    var ss=correoOwner_(true);
    // Solo reemplaza activadores propios de correoAlAbrir, nunca onOpen ni ventasTick.
    ScriptApp.getProjectTriggers().filter(function(t){return t.getHandlerFunction()==='correoAlAbrir';})
      .forEach(function(t){ScriptApp.deleteTrigger(t);});
    ScriptApp.newTrigger('correoAlAbrir').forSpreadsheet(ss).onOpen().create();
    return 'Correo instalado. Seleccioná una sola fila de Ventas. Abrir la planilla solo agrega el menú; no prepara borradores.';
  });
  correoMenu_();return message;
});}
function correoAlAbrir(e){
  // Un activador instalable corre como su creador, incluso si abre otro editor.
  // No ejecutar trabajo de Gmail aquí. Sin diálogos ni datos en registros.
  try{var ss=correoOwner_(false);if(e&&e.source&&e.source.getId()===ss.getId())correoMenu_();}catch(ignore){}
}
function correoSeleccion_(ss){
  var list=ss.getActiveRangeList(),ranges=list?list.getRanges():[];
  if(ranges.length!==1||ranges[0].getNumRows()!==1||ranges[0].getRow()<2||
    ranges[0].getSheet().getName()!==SH.sales)correoError_('Seleccioná una celda o un rango de una única fila de datos en Ventas.');
  var row=ranges[0].getRow(),rows=ventasRows_(),r=rows[row-2];
  if(!r)correoError_('La fila seleccionada no contiene una venta.');
  var uid=String(r[22]||''),id=String(r[0]||'').trim();
  if(!/^[A-Za-z0-9_-]{1,100}$/.test(uid)||!id)correoError_('La venta no tiene identidad conservada. No se creó ningún borrador.');
  if(rows.filter(function(x){return String(x[22])===uid;}).length!==1||
    rows.filter(function(x){return String(x[0]).trim()===id;}).length!==1)
    correoError_('ID o UID duplicado. Revisá la identidad de las filas antes de continuar.');
  return {row:row,uid:uid,id:id,values:r};
}
function correoKey_(uid){return CORREO.prefix+uid;}
function correoRef_(ss,uid){return 'CORREO-HOMO-'+ventasHash_(ss.getId()+'|'+uid).slice(0,24);}
function correoRegistroTexto_(raw,ref){
  var r;try{r=JSON.parse(raw);}catch(ignore){}
  if(r&&r.state==='borrador creado'&&typeof r.draftId==='string'&&r.draftId)
    return 'Borrador creado y registrado. No se recreará aunque lo hayas enviado o eliminado. Buscá en Gmail: '+ref+'.';
  return 'BLOQUEADO: preparación pendiente o resultado incierto. Buscá en Borradores, Enviados y Papelera de Gmail: '+ref+
    '. Resolvé manualmente según la guía. No borres propiedades ni repitas la creación automática.';
}
function correoEmail_(email){
  // Perfil conservador: una dirección ASCII, sin nombres, listas ni cabeceras.
  if(typeof email!=='string'||email.length>180||email!==email.trim())return false;
  var parts=email.split('@');if(parts.length!==2||parts[0].length>64)return false;
  return /^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/.test(parts[0])&&
    /^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z]{2,63}$/.test(parts[1]);
}
function correoDatos_(selected){
  var records=ventasJournalRead_().filter(function(e){return e.uid===selected.uid||e.id===selected.id;}),
    first=null,auth=null,last=null;
  records.forEach(function(e){
    var d=e.data,s=d&&d.snapshot,json=JSON.stringify(s);
    if(['ATTEMPT','UNCERTAIN','REJECTED','AUTHORIZED','PDF'].indexOf(e.type)<0||
      !s||e.uid!==selected.uid||e.id!==selected.id||s.uid!==e.uid||s.id!==e.id||
      (first!==null&&first!==json))correoError_('Identidad o snapshot inconsistente en el diario. Detené la prueba.');
    first=json;
    if(e.type==='AUTHORIZED')auth=JSON.stringify(d.authorization);
    if(e.type==='PDF'&&(!auth||auth!==JSON.stringify(d.authorization)))
      correoError_('El PDF no tiene una autorización previa coincidente en el diario.');
    last=e;
  });
  if(!last||last.type!=='PDF')correoError_('Falta un PDF confirmado en el diario. Un enlace o CAE en la fila no alcanza.');
  var data=JSON.parse(JSON.stringify(last.data)),s=data.snapshot,a=data.authorization;
  if(!s.issuer||!Number.isInteger(s.number)||s.number<1||!a||!/^\d{14}$/.test(String(a.cae))||
    !ventasYmd_(String(a.expires))||!a.confirmedAt||!Number.isFinite(Date.parse(a.confirmedAt))||
    typeof data.fileId!=='string'||!data.fileId||!data.pdf)
    correoError_('El registro de autorización o PDF está incompleto. No se creó ningún borrador.');
  if(!correoEmail_(s.email))correoError_('El correo conservado está vacío o no es válido para esta lección. Cambiar la celda no corrige el snapshot.');
  if(String(selected.values[6]).trim()!==s.email)correoError_('El correo de la fila cambió después de autorizar. Se bloqueó el borrador; el destinatario solo puede provenir del snapshot.');
  var c={cuit:s.issuer.cuit,name:s.issuer.name,address:s.issuer.address,pv:s.pv,ri:true,exclusive:true};
  if(!ventasInputSame_(selected.values,s,c))correoError_('Los datos de entrada cambiaron después de autorizar. Revisalos contra la venta conservada.');
  return data;
}
function correoArchivo_(data){
  try{
    var f=DriveApp.getFileById(data.fileId),owner=f.getOwner();
    if(!owner||owner.getEmail()!==Session.getEffectiveUser().getEmail()||f.isTrashed()||
      f.getMimeType()!=='application/pdf'||f.getSharingAccess()!==DriveApp.Access.PRIVATE||
      f.getEditors().length||f.getViewers().length||
      f.getDescription()!=='ARCA_HOMO:'+ventasHash_(JSON.stringify(data.snapshot)))throw new Error();
    if(f.getSize()<5||f.getSize()>20*1024*1024)throw new Error();
    var blob=f.getBlob(),bytes=blob.getBytes();
    if(bytes.length<5||bytes.length>20*1024*1024||
      String.fromCharCode.apply(null,bytes.slice(0,5))!=='%PDF-')throw new Error();
    return blob.setName('HOMOLOGACION_SIN_VALIDEZ_FISCAL.pdf');
  }catch(ignore){correoError_('PDF no disponible o no verificable: debe ser privado, de tu propiedad, PDF y vinculado al snapshot. Revisá Drive; Correo no cambia permisos ni genera PDFs.');}
}
function correoPrepararSeleccion(){correoUi_(function(){return setupLocked_(function(){
  var ss=correoOwner_(false),selected=correoSeleccion_(ss),p=PropertiesService.getUserProperties(),
    key=correoKey_(selected.uid),ref=correoRef_(ss,selected.uid),old=p.getProperty(key);
  if(old!==null)return correoRegistroTexto_(old,ref);
  var data=correoDatos_(selected),blob=correoArchivo_(data);
  // DocumentLock coordina scripts, no bloquea ediciones humanas. Releer tras Drive.
  var now=correoSeleccion_(ss);
  if(now.uid!==selected.uid||now.id!==selected.id||
    JSON.stringify(now.values.slice(0,10))!==JSON.stringify(selected.values.slice(0,10)))
    correoError_('La selección o los datos cambiaron durante la preparación. No se creó ningún borrador.');
  var record={state:'preparando',draftId:null,at:new Date().toISOString(),ref:ref},raw=JSON.stringify(record);
  try{p.setProperty(key,raw);if(p.getProperty(key)!==raw)throw new Error();}
  catch(ignore){correoError_('No se pudo confirmar la marca de preparación. Gmail no fue llamado. Consultá Estado / ayuda; si hay registro, conservá el bloqueo.');}
  // Desde esta marca, cualquier excepción o interrupción requiere revisión manual.
  try{
    var draft=GmailApp.createDraft(data.snapshot.email,CORREO.warning+' · '+ref,
      CORREO.warning+'\n\nAdjunto: comprobante autorizado únicamente en HOMOLOGACIÓN.\n'+
      'No acredita una operación fiscal real.\n\nRevisá destinatario y PDF antes de decidir si lo enviás manualmente en Gmail.\n'+
      'Este script solo preparó un borrador.\n\nReferencia de control: '+ref,
      {attachments:[blob]});
    var draftId=draft.getId();if(typeof draftId!=='string'||!draftId)throw new Error();
    record.state='borrador creado';record.draftId=draftId;raw=JSON.stringify(record);
    p.setProperty(key,raw);if(p.getProperty(key)!==raw)throw new Error();
  }catch(ignore){correoError_('Resultado incierto: el borrador podría existir. No se repetirá automáticamente. Buscá en Gmail '+ref+
    ' y resolvé manualmente según la guía. Conservá el registro; no borres propiedades.');}
  return correoRegistroTexto_(raw,ref)+' Abrilo, revisá destinatario y adjunto. El script no lo envía.';
});});}
function correoEstadoAyuda(){correoUi_(function(){return setupLocked_(function(){
  var ss=correoOwner_(false),selected=correoSeleccion_(ss),ref=correoRef_(ss,selected.uid),
    raw=PropertiesService.getUserProperties().getProperty(correoKey_(selected.uid));
  return (raw===null?'Sin intento de correo registrado. Esto no confirma que la fila sea apta; se validará al preparar. Referencia: '+ref+'.':
    correoRegistroTexto_(raw,ref))+'\nSolo una fila, solo borradores, solo HOMOLOGACIÓN. '+
    'Gmail: buscá la referencia o in:anywhere seguido de la referencia. Nunca se consulta si fue enviado o eliminado. '+
    'La guía explica permisos y resolución manual. No se muestran emails, CUIT, CAE, claves ni IDs de archivo o borrador.';
});});}
