(function(){
function esc(s){return String(s||'').replace(/[&<>'"]/g,c=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[c]));}
function moneyText(s){return s || '$ 0,00';}
function buildUrl(base, params){ const u = new URL(base, window.location.origin); Object.entries(params||{}).forEach(([k,v])=>{ if(v!==undefined && v!==null && String(v)!=='') u.searchParams.set(k,v); }); return u.toString(); }
function tomorrowISO(){ const d = new Date(Date.now()+86400000); return d.toISOString().slice(0,10); }
function byId(arr,id){ return (arr||[]).find(x=>String(x.id)===String(id)); }
const DEFAULT_STEPS = [
['mode','Inicio'], ['location','Ubicación'], ['main','Institución / especialidad'], ['place','Sede / profesional'], ['service','Servicio'], ['schedule','Fecha y hora'], ['patient','Tus datos'], ['confirm','Confirmación']
];
function createBookingWizard(root, cfg, opts){
opts = opts || {};
const content = root.querySelector('#bwContent') || root;
const title = root.querySelector('#bwTitle');
const subtitle = root.querySelector('#bwSubtitle');
const badge = root.querySelector('#bwStepBadge');
const prev = root.querySelector('#bwPrev');
const next = root.querySelector('#bwNext');
const fill = root.querySelector('#bwProgressFill');
const label = root.querySelector('#bwProgressLabel');
const stepList = root.querySelector('#bwStepList');
const summary = root.querySelector('#bwSummary');
const state = {
step: 0, mode: opts.defaultMode || '', province:'', city:'', institution_id: cfg.initialInstitutionId || '', branch_id:'', service_id: cfg.initialServiceId || '', professional_id:'', booking_type:'first_available', date: tomorrowISO(), time:'',
client_name: cfg.linkedPatient?.name || '', client_email: cfg.linkedPatient?.email || '', client_phone: cfg.linkedPatient?.phone || '', notes:'', options:{}, slots:[], source: opts.source || 'website'
};
if(opts.prefill) Object.assign(state, opts.prefill);
async function loadOptions(extra){
const params = Object.assign({mode: state.mode, province: state.province, city: state.city, institution_id: state.institution_id, branch_id: state.branch_id, service_id: state.service_id}, extra||{});
const resp = await fetch(buildUrl(cfg.optionsUrl, params));
const data = await resp.json();
if(data.ok) state.options = data;
return data;
}
async function loadSlots(){
if(!state.service_id || !state.date) return {ok:false, items:[]};
const params = {service_id:state.service_id, date:state.date, institution_id:state.institution_id, branch_id:state.branch_id, professional_id:state.professional_id, province:state.province, city:state.city, booking_type:state.booking_type};
const resp = await fetch(buildUrl(cfg.slotsUrl, params));
const data = await resp.json();
state.slots = data.items || [];
return data;
}
function setChoice(key,val){ state[key]=val; state.time=''; if(key==='institution_id'){ state.branch_id=''; state.service_id=''; state.professional_id=''; } if(key==='branch_id'){ state.service_id=''; state.professional_id=''; } if(key==='service_id'){ state.professional_id=''; } render(); }
function stepMeta(){
const m = {
mode:['¿Cómo querés buscar tu turno?','Elegí si ya conocés la institución o si preferís que te mostremos opciones disponibles.'],
location:['Elegí tu ubicación','Esto permite filtrar sedes, instituciones y profesionales por provincia y ciudad.'],
main:[state.mode==='known'?'Elegí la institución':'Elegí especialidad o servicio', state.mode==='known'?'Buscá la clínica, sanatorio, consultorio o institución donde querés atenderte.':'Te mostramos servicios y especialidades disponibles en tu zona.'],
place:[state.mode==='known'?'Elegí la sede':'Elegí profesional o institución sugerida', state.mode==='known'?'Si la institución tiene varias sedes, seleccioná la más conveniente.':'Podés elegir un profesional concreto o dejar que el sistema asigne el primero disponible.'],
service:['Elegí el tipo de atención','Seleccioná el servicio, modalidad o tipo de consulta.'],
schedule:['Elegí fecha y horario','Seleccioná un día y luego uno de los horarios disponibles.'],
patient:['Completá tus datos','Usaremos esta información para confirmar y administrar tu turno.'],
confirm:['Revisá y confirmá','Verificá los datos antes de finalizar la solicitud.']
};
return m[DEFAULT_STEPS[state.step][0]];
}
function updateChrome(){
const pct = Math.round(((state.step+1)/DEFAULT_STEPS.length)*100);
if(fill) fill.style.width = pct+'%';
if(label) label.textContent = `Paso ${state.step+1} de ${DEFAULT_STEPS.length}`;
if(badge) badge.textContent = `Paso ${state.step+1}`;
const [t,st] = stepMeta(); if(title) title.textContent=t; if(subtitle) subtitle.textContent=st;
if(stepList){ stepList.innerHTML = DEFAULT_STEPS.map((s,i)=>`