(function(){
'use strict';
const STYLE=`<style id="capacity-calendar-style">
.capacity-launch{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 16px;padding:14px 16px;background:linear-gradient(135deg,#eaf6ff,#f7fbff);border:1px solid #b9dcf5;border-radius:14px}.capacity-launch span{font-size:12px;color:var(--muted);flex:1;min-width:220px}.capacity-modal-card{width:min(920px,100%);max-height:92vh;overflow:auto}.capacity-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.capacity-legend{display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:var(--muted);margin:10px 0}.capacity-legend i{width:11px;height:11px;border-radius:3px;display:inline-block;margin-left:4px}.capacity-calendar{display:grid;grid-template-columns:repeat(7,minmax(58px,1fr));gap:7px;direction:rtl}.capacity-weekday{text-align:center;padding:8px 2px;font-size:11px;font-weight:bold;color:var(--navy)}.capacity-day{min-height:82px;border:1px solid var(--line);border-radius:11px;background:#fff;padding:7px 3px;display:grid;place-items:center;align-content:center;gap:4px}.capacity-day strong{font-size:18px}.capacity-day small{font-size:10px}.capacity-day.open{background:#e9f8f1;border-color:#82d6b7;color:#126b50}.capacity-day.low{background:#fff8df;border-color:#e7c85e;color:#7b5b00}.capacity-day.full{background:#fff0f0;border-color:#efa2a2;color:#a82828}.capacity-day.off,.capacity-day.past{background:#f3f4f6;color:#9aa1ad}.capacity-empty{min-height:82px}.capacity-slots{display:grid;grid-template-columns:repeat(auto-fit,minmax(125px,1fr));gap:9px;margin:14px 0}.capacity-slot{border:1px solid #8dcfb9;background:#effaf6;color:#126b50;border-radius:10px;padding:11px 8px}.capacity-slot.full{border-color:#e3a0a0;background:#fff3f3;color:#a82828;cursor:not-allowed}.capacity-slot strong,.capacity-slot small{display:block}.capacity-slot small{margin-top:4px;font-size:10px}.work-hours-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.work-hours-grid input{width:100%;padding:10px;border:1px solid var(--line);border-radius:9px}@media(max-width:600px){.capacity-calendar{gap:3px}.capacity-day,.capacity-empty{min-height:64px}.capacity-day strong{font-size:15px}.capacity-day small{font-size:8px}.capacity-modal-card{padding:14px}.work-hours-grid{grid-template-columns:1fr}}
</style>`;
document.head.insertAdjacentHTML('beforeend',STYLE);
function normalize(){db.workStart=/^\d{2}:\d{2}$/.test(db.workStart||'')?db.workStart:'06:00';db.workEnd=/^\d{2}:\d{2}$/.test(db.workEnd||'')?db.workEnd:'22:00';db.capacity=Math.max(1,Number(db.capacity)||1)}
normalize();
const treatmentPage=document.querySelector('#page-treatment .page-head');
treatmentPage.insertAdjacentHTML('afterend',`<div class="capacity-launch"><span><b>اولین نوبت خالی را سریع پیدا کنید.</b><br>روز دارای ظرفیت را انتخاب کنید، سپس ساعت خالی را بزنید.</span><button id="openCapacityCalendar" type="button" class="btn primary">تقویم شماتیک ظرفیت</button></div>`);
document.querySelector('#toast').insertAdjacentHTML('beforebegin',`<div id="capacityCalendarModal" class="modal hidden" style="z-index:550"><div class="modal-card capacity-modal-card"><div class="capacity-head"><div><h3 style="margin:0">تقویم ظرفیت نوبت‌دهی</h3><p id="capacityMonthTitle" style="margin:6px 0 0;color:var(--muted);font-size:12px"></p></div><div class="actions"><button id="capacityToday" type="button" class="btn secondary">ماه جاری</button><button id="capacityNext" type="button" class="btn secondary">ماه بعد</button><button id="capacityNextTwo" type="button" class="btn secondary">۲ ماه بعد</button></div></div><div id="capacityFirstAvailable" class="notice" style="margin:14px 0 8px"></div><div class="capacity-legend"><span><i style="background:#82d6b7"></i>ظرفیت مناسب</span><span><i style="background:#e7c85e"></i>ظرفیت محدود</span><span><i style="background:#efa2a2"></i>تکمیل</span><span><i style="background:#cdd1d8"></i>تعطیل یا گذشته</span></div><div id="capacityCalendar" class="capacity-calendar"></div><div id="capacitySlotPanel" class="hidden"><hr style="border:0;border-top:1px solid var(--line);margin:18px 0"><h3 id="capacitySlotTitle"></h3><p style="font-size:12px;color:var(--muted)">با انتخاب ساعت، تاریخ و ساعت شروع جلسه در فرم نوبت‌دهی قرار می‌گیرد.</p><div id="capacitySlots" class="capacity-slots"></div></div><div class="actions"><button id="closeCapacityCalendar" type="button" class="btn secondary">بستن</button></div></div></div>`);
const settingsGrid=document.querySelector('#page-settings .settings');
settingsGrid.insertAdjacentHTML('afterbegin',`<div class="setting" id="workHoursSetting"><h3>ساعت کاری مجموعه</h3><p>بازه ساخت نوبت‌های یک‌ساعته را تعیین کنید. ساعت پایان، انتهای آخرین نوبت است.</p><div class="work-hours-grid"><label class="field"><span>شروع کار</span><input id="workStart" type="time"></label><label class="field"><span>پایان کار</span><input id="workEnd" type="time"></label></div><button id="saveWorkHours" type="button" class="btn primary">ذخیره ساعت کاری</button></div>`);
const capacityTitle=document.querySelector('#capacity').closest('.setting');capacityTitle.querySelector('h3').textContent='تعداد کابین‌های فعال';capacityTitle.querySelector('p').textContent='تعداد بیمار قابل پذیرش در هر بازه یک‌ساعته؛ در آینده قابل افزایش یا کاهش است.';
let viewYear=0,viewMonth=0;
function minutes(t){const [h,m]=String(t).split(':').map(Number);return h*60+m}
function slots(){const out=[],start=minutes(db.workStart),end=minutes(db.workEnd);for(let n=start;n+60<=end;n+=60)out.push(`${String(Math.floor(n/60)).padStart(2,'0')}:${String(n%60).padStart(2,'0')}`);return out}
function slotIsPast(date,time){return new Date(`${date}T${time}:00`).getTime()<=Date.now()}
function dayCapacity(date){const times=slots().filter(t=>!slotIsPast(date,t)),total=times.length*db.capacity,free=times.reduce((sum,t)=>sum+Math.max(0,db.capacity-treatmentCapacityUsed(date,t)),0);return{total,free}}
function firstAvailable(){let d=new Date(localDate()+'T12:00:00');for(let day=0;day<366;day++,d.setDate(d.getDate()+1)){const date=localDate(d);if(db.holidays.includes(date))continue;for(const time of slots())if(!slotIsPast(date,time)&&treatmentCapacityUsed(date,time)<db.capacity)return{date,time,free:db.capacity-treatmentCapacityUsed(date,time)}}return null}
function openCalendar(){const p=persianParts(new Date());viewYear=p.year;viewMonth=p.month;document.querySelector('#capacitySlotPanel').classList.add('hidden');renderCalendar();document.querySelector('#capacityCalendarModal').classList.remove('hidden')}
function renderCalendar(){const days=[];for(let d=1;d<=31;d++){const iso=jalaliToIso(`${viewYear}/${viewMonth}/${d}`);if(iso)days.push({d,iso})}const first=days[0]?new Date(days[0].iso+'T12:00:00'):null,offset=first?(first.getDay()+1)%7:0,names=['شنبه','یکشنبه','دوشنبه','سه‌شنبه','چهارشنبه','پنجشنبه','جمعه'],firstSlot=firstAvailable();document.querySelector('#capacityMonthTitle').textContent=`${monthNames[viewMonth-1]} ${faDigits(viewYear)} — ${faDigits(db.capacity)} کابین، ${faDigits(db.workStart)} تا ${faDigits(db.workEnd)}`;document.querySelector('#capacityFirstAvailable').innerHTML=firstSlot?`<b>اولین نوبت خالی:</b> ${fmtDate(firstSlot.date)} ساعت ${firstSlot.time} — ${fa(firstSlot.free)} کابین خالی`:'در یک سال آینده نوبت خالی پیدا نشد.';let html=names.map(n=>`<div class="capacity-weekday">${n}</div>`).join('')+Array.from({length:offset},()=>'<div class="capacity-empty"></div>').join('');html+=days.map(x=>{const past=x.iso<localDate(),off=db.holidays.includes(x.iso),c=dayCapacity(x.iso),ratio=c.total?c.free/c.total:0,cls=past?'past':off?'off':c.free===0?'full':ratio<=.25?'low':'open',text=past?'گذشته':off?'تعطیل':c.free===0?'تکمیل':`${fa(c.free)} جای خالی`;return `<button type="button" class="capacity-day ${cls}" ${(past||off||!c.free)?'disabled':''} onclick="showCapacitySlots('${x.iso}')"><strong>${faDigits(x.d)}</strong><small>${text}</small></button>`}).join('');document.querySelector('#capacityCalendar').innerHTML=html}
window.showCapacitySlots=function(date){const usable=slots(),panel=document.querySelector('#capacitySlotPanel');document.querySelector('#capacitySlotTitle').textContent=`ساعت‌های ${fmtDate(date)}`;document.querySelector('#capacitySlots').innerHTML=usable.map(t=>{const past=slotIsPast(date,t),free=past?0:Math.max(0,db.capacity-treatmentCapacityUsed(date,t));return `<button type="button" class="capacity-slot ${free?'':'full'}" ${free?'':'disabled'} onclick="chooseCapacitySlot('${date}','${t}')"><strong>${t}</strong><small>${past?'زمان گذشته':free?`${fa(free)} کابین خالی`:'ظرفیت تکمیل'}</small></button>`}).join('')||'<div class="notice">بازه ساعت کاری معتبر نیست.</div>';panel.classList.remove('hidden');panel.scrollIntoView({behavior:'smooth',block:'nearest'})};
window.chooseCapacitySlot=function(date,time){document.querySelector('#tStart').value=new Date(date+'T12:00:00').toLocaleDateString('fa-IR');document.querySelector('#tTime').value=time;document.querySelector('#capacityCalendarModal').classList.add('hidden');toast(`نوبت ${fmtDate(date)} ساعت ${time} انتخاب شد.`)};
function changeMonth(step){viewMonth+=step;if(viewMonth<1){viewMonth=12;viewYear--}if(viewMonth>12){viewMonth=1;viewYear++}document.querySelector('#capacitySlotPanel').classList.add('hidden');renderCalendar()}
document.querySelector('#openCapacityCalendar').onclick=openCalendar;document.querySelector('#closeCapacityCalendar').onclick=()=>document.querySelector('#capacityCalendarModal').classList.add('hidden');document.querySelector('#capacityNext').onclick=()=>changeMonth(1);document.querySelector('#capacityNextTwo').onclick=()=>changeMonth(2);document.querySelector('#capacityToday').onclick=openCalendar;
document.querySelector('#saveWorkHours').onclick=()=>{const start=document.querySelector('#workStart').value,end=document.querySelector('#workEnd').value;if(!start||!end||minutes(end)-minutes(start)<60)return toast('ساعت پایان باید حداقل یک ساعت بعد از شروع باشد.');db.workStart=start;db.workEnd=end;save();renderAll();toast('ساعت کاری مجموعه ذخیره شد.')};
const oldRenderSettings=renderSettings;renderSettings=function(){normalize();oldRenderSettings();document.querySelector('#workStart').value=db.workStart;document.querySelector('#workEnd').value=db.workEnd};
nextAvailableTreatmentSlot=function(pid,date,time,reserved=[]){const requested=minutes(time),workSlots=slots().sort((a,b)=>Math.abs(minutes(a)-requested)-Math.abs(minutes(b)-requested)||minutes(a)-minutes(b));let d=new Date(date+'T12:00:00');for(let day=0;day<366;day++,d.setDate(d.getDate()+1)){const candidateDate=localDate(d),patientAlreadyBooked=db.appointments.some(a=>a.patientId===pid&&a.date===candidateDate&&a.status!=='لغو شده')||reserved.some(x=>x.date===candidateDate);if(db.holidays.includes(candidateDate)||patientAlreadyBooked)continue;for(const candidateTime of workSlots){if(slotIsPast(candidateDate,candidateTime))continue;const planned=reserved.filter(x=>x.date===candidateDate&&x.time===candidateTime).length;if(treatmentCapacityUsed(candidateDate,candidateTime)+planned<db.capacity)return{date:candidateDate,time:candidateTime}}}return null};
renderSettings();
})();
