'use strict';

// ============================================================
// SiteSight V1.99.5 — Mobile Experience
// A focused phone workspace for fast day-to-day Site use.
// ============================================================

function v1995IsMobile(){
  return !!(window.matchMedia&&window.matchMedia('(max-width:720px)').matches)
}
function v1995Esc(value){
  return String(value??'').replace(/[&<>"']/g,char=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[char]))
}
function v1995ScrollTop(){
  if(!v1995IsMobile())return;
  requestAnimationFrame(()=>{
    document.scrollingElement?.scrollTo({top:0,left:0,behavior:'instant'});
    document.querySelector('.main')?.scrollTo?.({top:0,left:0,behavior:'instant'})
  })
}

// ---- Every newly opened phone page starts at the top ---------------
let v1995LastPageKey='';
const v1995BaseRender=render;
render=function(){
  let key=currentUser()?`${view}|${selected||''}|${selectedGang||''}`:'';
  let changed=!!key&&key!==v1995LastPageKey;
  let result=v1995BaseRender();
  v1995LastPageKey=key;
  if(changed)v1995ScrollTop();
  return result
};
const v1995BaseGoNav=goNav;
goNav=function(target){let before=`${view}|${site}|${selected||''}|${selectedGang||''}`,result=v1995BaseGoNav(target),after=`${view}|${site}|${selected||''}|${selectedGang||''}`;if(after!==before)v1995ScrollTop();return result};
if(typeof v1994GoBack==='function'){
  const v1995BaseGoBack=v1994GoBack;
  v1994GoBack=function(){let before=`${view}|${site}|${selected||''}|${selectedGang||''}`,result=v1995BaseGoBack(),after=`${view}|${site}|${selected||''}|${selectedGang||''}`;if(after!==before)v1995ScrollTop();return result}
}
if(typeof v199OpenNotification==='function'){
  const v1995BaseOpenNotification=v199OpenNotification;
  v199OpenNotification=function(id){let result=v1995BaseOpenNotification(id);v1995ScrollTop();return result}
}
if(typeof openItem==='function'){
  const v1995BaseOpenItem=openItem;
  openItem=function(id){let result=v1995BaseOpenItem(id);v1995ScrollTop();return result}
}
if(typeof openGang==='function'){
  const v1995BaseOpenGang=openGang;
  openGang=function(id){let result=v1995BaseOpenGang(id);v1995ScrollTop();return result}
}

// ---- Short, recognisable phone navigation --------------------------
const V1995_MOBILE_LABELS={
  dashboard:'Overview','work-items':'Plots',issues:'Issues',attendance:'Time',commercial:'Money',
  gangs:'People',diary:'Diary','site-drawings':'Drawings',documents:'Docs',calendar:'Dates',
  'my-work':'My Work',clock:'Clock',more:'More'
};
function v1995MobileNavActive(id){
  if(id==='dashboard')return view==='dashboard'||view==='needs-attention';
  if(id==='more'){
    let primary=new Set(v173RoleNavItems(currentUser()).slice(0,4).map(row=>row.id));
    return view==='more'||(!primary.has(view)&&!selected)
  }
  return view===id
}
function v1995MobileNavButton(item){
  let id=item.id,label=V1995_MOBILE_LABELS[id]||(typeof item.label==='function'?item.label(currentUser()):item.label),count=id==='issues'?scopeItems().reduce((sum,row)=>sum+issues(row),0):0;
  return `<button type="button" data-nav="${v1995Esc(id)}" class="${v1995MobileNavActive(id)?'active':''}" onclick="goNav('${id}')" aria-label="Open ${v1995Esc(label)}"><span class="v1995-nav-tile" aria-hidden="true">${item.icon}</span><b>${v1995Esc(label)}</b>${count?`<em class="count">${count}</em>`:''}</button>`
}
mobileNav=function(){
  let user=currentUser();if(!user)return'';
  let rows=v173RoleNavItems(user).slice(0,4),html=rows.map(v1995MobileNavButton).join('');
  if(v1992HasMore(user))html+=v1995MobileNavButton({id:'more',icon:'•••',label:'More'});
  return html
};

// Company setup and detailed reporting remain desktop/tablet jobs.
const V1995_PHONE_OFFICE_ONLY=new Set(['weekly-report','analytics','data-quality','audit','admin','functionality']);
const v1995BaseMoreToolIds=v1992MoreToolIds;
v1992MoreToolIds=function(user=currentUser()){
  let ids=v1995BaseMoreToolIds(user);
  return v1995IsMobile()?ids.filter(id=>!V1995_PHONE_OFFICE_ONLY.has(id)):ids
};
v173MoreToolIds=v1992MoreToolIds;
const v1995BaseMorePage=morePage;
morePage=function(){
  if(!v1995IsMobile())return v1995BaseMorePage();
  let ids=v1992MoreToolIds(),groups=[
    ['On-site tools',['attendance','commercial','gangs','site-drawings','documents','calendar','diary','dayworks']],
    ['Help and testing',['test-route','about']]
  ];
  let sections=groups.map(([title,tools])=>{let visible=tools.filter(id=>ids.includes(id));if(!visible.length)return'';return `<section class="panel v1995-more-section"><h2>${title}</h2><div>${visible.map(v1992MoreCard).join('')}</div></section>`}).join('');
  return `<div class="topbar"><div><span class="att-kicker">PHONE WORKSPACE</span><h1>More</h1><div class="sub">Useful tools for work away from your desk</div></div></div><div class="v1995-phone-scope"><span>Fast on site</span><div><b>Phone view stays focused on daily work.</b><small>Company setup, audit, detailed analytics and full reports remain available on desktop or tablet.</small></div></div><div class="v1992-more-groups">${sections}<section class="panel v1992-more-help"><h2>Need help?</h2><p>Get a short explanation, highlight the next useful control or start your guided route.</p><button class="btn light" onclick="v1992OpenHelp()">Open help</button></section></div>`
};

// ---- Search sites, plots, issues, people and daily records ----------
const v1995BaseGlobalSearchResults=globalSearchResults;
function v1995TextMatch(query,values){return values.some(value=>String(value||'').toLowerCase().includes(query))}
function v1995MemberVisible(member){
  let siteIds=member?.clockSiteIds||member?.siteIds||[];
  if(siteIds.length)return siteIds.some(id=>canAccessSite(id));
  if((db.items||[]).some(item=>canAccessSite(item.site)&&[item.gang,item.assignedTo,item.assignedId].includes(member?.id)))return true;
  if((db.attendanceShifts||[]).some(shift=>shift.workerId===member?.id&&canAccessSite(shift.siteId)))return true;
  return (db.users||[]).some(user=>user.linkedMemberId===member?.id&&(user.allSitesAccess===true||(user.allowedSites||[]).some(id=>canAccessSite(id))))
}
function v1995SearchHome(){
  let user=currentUser(),target=v173CanOpenView('dashboard',user)?'dashboard':v173CanOpenView('work-items',user)?'work-items':v173HomeView(user);
  selected=null;selectedGang=null;view=target;modal=null;render();v1995ScrollTop()
}
function v1995OpenSearchSite(id){if(!canAccessSite(id))return toast('This Site is outside your access');site=id;v1995SearchHome()}
function v1995OpenSearchPerson(memberId){
  let group=(db.gangs||[]).find(row=>(row.members||[]).some(member=>member.id===memberId));
  if(!group)return toast('This person is no longer available');modal=null;openTeamMember(group.id,memberId);v1995ScrollTop()
}
function v1995OpenSearchDiary(id){
  let row=(db.siteDiary||[]).find(entry=>entry.id===id);if(!row||!canAccessSite(row.siteId))return toast('This diary entry is unavailable');
  site=row.siteId;view='diary';selected=null;modal=null;render();v1995ScrollTop();setTimeout(()=>openDiaryEntry(id),30)
}
function v1995OpenSearchCalendar(id){
  let row=(db.calendarNotes||[]).find(entry=>entry.id===id);if(!row||!canAccessSite(row.siteId))return toast('This calendar entry is unavailable');
  site=row.siteId;calendarMonth=String(row.date||iso()).slice(0,7)+'-01';view='calendar';selected=null;modal=null;render();v1995ScrollTop();setTimeout(()=>openCalendarNote(id),30)
}
function v1995OpenSearchDocument(id){
  let row=(db.documents||[]).find(entry=>entry.id===id);if(!row||!v191DocumentVisible(row))return toast('This document is unavailable');
  modal=null;if(typeof v191DocumentFolder!=='undefined')v191DocumentFolder=row.parentId||'';if(typeof v191DocumentQuery!=='undefined')v191DocumentQuery=row.name||row.originalName||'';if(typeof v191DocumentSite!=='undefined')v191DocumentSite=row.siteId||'all';goNav('documents')
}
globalSearchResults=function(query){
  let q=String(query||'').trim().toLowerCase();if(q.length<2)return[];
  let additions=[];
  (db.sites||[]).filter(row=>!row.archived&&canAccessSite(row.id)&&v1995TextMatch(q,[row.name,row.address,row.client,row.code]))
    .slice(0,5).forEach(row=>additions.push({kind:'Site',icon:'⌖',title:row.name,meta:`${(db.items||[]).filter(item=>item.site===row.id).length} plots / work items · Active Site`,action:`closeGlobalSearch();v1995OpenSearchSite('${row.id}')`}));
  if(hasPerm('gangs'))for(const group of db.gangs||[]){
    for(const member of group.members||[]){
      if(additions.filter(row=>row.kind==='Person').length>=7)break;
      if(v1995MemberVisible(member)&&v1995TextMatch(q,[member.name,member.role,group.name]))additions.push({kind:'Person',icon:'♙',title:member.name,meta:`${member.role||'Site person'} · ${group.name}`,action:`closeGlobalSearch();v1995OpenSearchPerson('${member.id}')`})
    }
  }
  if(hasPerm('view_site_diary'))(db.siteDiary||[]).filter(row=>canAccessSite(row.siteId)&&v1995TextMatch(q,[row.date,row.people,row.teams,row.work,row.deliveries,row.delays,row.notes,siteName(row.siteId)]))
    .slice(0,6).forEach(row=>additions.push({kind:'Diary',icon:'✎',title:`${row.date} · ${siteName(row.siteId)}`,meta:(row.work||row.notes||row.delays||'Site Diary record').replace(/\s+/g,' ').slice(0,105),action:`closeGlobalSearch();v1995OpenSearchDiary('${row.id}')`}));
  if(hasPerm('view_calendar'))(db.calendarNotes||[]).filter(row=>canAccessSite(row.siteId)&&v1995TextMatch(q,[row.title,row.notes,row.category,row.date,siteName(row.siteId)]))
    .slice(0,6).forEach(row=>additions.push({kind:'Calendar',icon:'□',title:row.title||'Calendar entry',meta:`${row.date||''} · ${siteName(row.siteId)} · ${row.category||'Site event'}`,action:`closeGlobalSearch();v1995OpenSearchCalendar('${row.id}')`}));
  if(typeof v191DocumentVisible==='function'&&v173CanOpenView('documents'))(db.documents||[]).filter(row=>row.type==='file'&&v191DocumentVisible(row)&&v1995TextMatch(q,[row.name,row.originalName,row.notes,siteName(row.siteId)]))
    .slice(0,6).forEach(row=>additions.push({kind:'Document',icon:'▥',title:row.name||row.originalName,meta:`${row.siteId?siteName(row.siteId):'Company'} · Revision ${Number(row.versionNumber||1)}`,action:`closeGlobalSearch();v1995OpenSearchDocument('${row.id}')`}));
  let rows=[...v1995BaseGlobalSearchResults(query),...additions],seen=new Set(),unique=rows.filter(row=>{let key=`${row.kind}|${row.action}`;if(seen.has(key))return false;seen.add(key);return true}),kinds=['Work Item','Issue','Site','Person','Team','Diary','Drawing','Document','Calendar'],balanced=[];
  for(const kind of kinds)balanced.push(...unique.filter(row=>row.kind===kind).slice(0,3));
  let chosen=new Set(balanced.map(row=>`${row.kind}|${row.action}`));for(const row of unique)if(balanced.length<30&&!chosen.has(`${row.kind}|${row.action}`)){balanced.push(row);chosen.add(`${row.kind}|${row.action}`)}
  return balanced.slice(0,30)
};
globalSearchResultsHtml=function(query){
  let q=String(query||'').trim(),rows=globalSearchResults(q);
  if(q.length<2){
    let recent=recentViewedItems();
    return `<div class="global-search-start"><span class="att-kicker">FIND IT FAST</span><b>Search all your permitted Site information</b><p>Type a plot number, Site, issue, person, diary note, drawing, document or date.</p><div class="v1995-search-examples"><button onclick="document.getElementById('global-search-input').value='Plot';updateGlobalSearch('Plot')">Plots</button><button onclick="document.getElementById('global-search-input').value='bricklayer';updateGlobalSearch('bricklayer')">Bricklayers</button><button onclick="let q=iso();document.getElementById('global-search-input').value=q;updateGlobalSearch(q)">Today's records</button></div>${recent.length?`<div class="global-search-recent"><span>RECENT PLOTS / WORK</span>${recent.map(row=>`<button onclick="closeGlobalSearch();openItem('${row.id}')"><b>${v1995Esc(row.ref)}</b><small>${v1995Esc(row.type)} · ${v1995Esc(siteName(row.site))}</small></button>`).join('')}</div>`:''}</div>`
  }
  if(!rows.length)return smartEmpty('Nothing found','Try a plot number, Site name, issue, person, diary word or date.','','','⌕');
  let order=['Site','Work Item','Issue','Person','Team','Diary','Drawing','Document','Calendar'],labels={'Site':'Sites','Work Item':'Plots & work','Issue':'Issues','Person':'People','Team':'People & teams','Diary':'Site Diary','Drawing':'Drawings','Document':'Documents','Calendar':'Calendar'};
  return order.map(kind=>{let group=rows.filter(row=>row.kind===kind);if(!group.length)return'';return `<div class="global-result-group">${labels[kind]||kind}</div>${group.map(row=>`<button class="global-result-row" onclick="${row.action}"><i>${row.icon}</i><span><b>${v1995Esc(row.title)}</b><small>${v1995Esc(row.meta)}</small></span><strong>›</strong></button>`).join('')}`}).join('')
};
openGlobalSearch=function(){
  if(typeof dirty!=='undefined'&&dirty&&typeof confirmLeave==='function'&&!confirmLeave())return;if(typeof clearDirty==='function')clearDirty();
  globalSearchQuery='';
  modal=`<div class="modal global-search-modal" onclick="if(event.target===this)closeGlobalSearch()"><div class="global-search-box"><div class="global-search-head"><span aria-hidden="true">⌕</span><input id="global-search-input" autocomplete="off" enterkeyhint="search" aria-label="Search SiteSight" placeholder="Plot, issue, person, Site…" oninput="updateGlobalSearch(this.value)" onkeydown="if(event.key==='Escape')closeGlobalSearch()"><button type="button" onclick="closeGlobalSearch()" aria-label="Close search">×</button></div><div id="global-search-results" class="global-search-results">${globalSearchResultsHtml('')}</div><div class="global-search-foot"><span>Only information you are allowed to view is searched.</span><button type="button" onclick="closeGlobalSearch()">Close</button></div></div></div>`;
  render();requestAnimationFrame(()=>document.getElementById('global-search-input')?.focus())
};

// ---- A visible phone account menu, including Sign out --------------
function v1995OpenMobileAccount(){
  let user=currentUser();if(!user)return;if(typeof dirty!=='undefined'&&dirty&&typeof confirmLeave==='function'&&!confirmLeave())return;if(typeof clearDirty==='function')clearDirty();
  let unread=unreadNotifications(user).length,sites=activeSites().filter(row=>canAccessSite(row.id)),siteText=user.role==='Director'?`${sites.length} active Sites`:sites.map(row=>row.name).slice(0,3).join(', ')||'No active Site';
  modal=`<div class="modal v1995-account-modal" onclick="if(event.target===this){modal=null;render()}"><div class="modalbox v1995-account-menu"><button type="button" class="v1991-modal-close" onclick="modal=null;render()" aria-label="Close account menu">×</button><div class="v1995-account-identity"><span>${v1995Esc((user.name||'?')[0].toUpperCase())}</span><div><h2>${v1995Esc(user.name||user.username)}</h2><p>${v1995Esc(user.role||'SiteSight user')} · ${v1995Esc(siteText)}</p></div></div><div class="v1995-account-actions"><button type="button" onclick="notificationSettings()"><i class="blue">●</i><span><b>Notifications${unread?` <em>${unread}</em>`:''}</b><small>Open updates and reminders</small></span><strong>›</strong></button><button type="button" onclick="v1992OpenHelp()"><i class="orange">?</i><span><b>Help</b><small>Explain this screen or show where to click</small></span><strong>›</strong></button><button type="button" onclick="toggleTrainingMode(!trainingMode)"><i class="green">✓</i><span><b>Hints are ${trainingMode?'on':'off'}</b><small>Tap to turn simple screen tips ${trainingMode?'off':'on'}</small></span><strong>›</strong></button><button type="button" onclick="changeOwnPassword()"><i class="purple">◆</i><span><b>Change password</b><small>Update this account's sign-in password</small></span><strong>›</strong></button></div><button type="button" class="v1995-sign-out" onclick="v1995ConfirmLogout()"><span>↪</span><b>Sign out</b></button><button type="button" class="btn light v1995-account-close" onclick="modal=null;render()">Close menu</button></div></div>`;
  render()
}
function v1995ConfirmLogout(){if(confirm('Sign out of SiteSight on this device?'))logout()}

// ---- Site Diary: manual editing retained, Save always visible -------
let v1995DiaryTouched=new Set();
function v1995DiaryChanged(id){v1995DiaryTouched.add(id);if(typeof markDirty==='function')markDirty()}
function v1995RefreshDiaryPrefill(){
  let siteId=document.getElementById('sd-site')?.value||'',date=document.getElementById('sd-date')?.value||iso(),prefill=typeof v169DiaryPrefill==='function'?v169DiaryPrefill(siteId,date):{teams:'',work:'',deliveries:'',delays:'',notes:''};
  for(const [id,value] of [['sd-teams',prefill.teams],['sd-work',prefill.work],['sd-del',prefill.deliveries],['sd-delay',prefill.delays],['sd-notes',prefill.notes]]){let field=document.getElementById(id);if(field&&!v1995DiaryTouched.has(id))field.value=value||''}if(typeof markDirty==='function')markDirty()
}
function v1995CancelDiary(){if(typeof dirty!=='undefined'&&dirty&&typeof confirmLeave==='function'&&!confirmLeave())return;if(typeof clearDirty==='function')clearDirty();v1995DiaryTouched.clear();modal=null;render()}
addDiaryEntry=function(){
  if(!hasPerm('manage_site_diary'))return toast('You do not have permission to manage the Site Diary');
  if(typeof dirty!=='undefined'&&dirty&&typeof confirmLeave==='function'&&!confirmLeave())return;if(typeof clearDirty==='function')clearDirty();v1995DiaryTouched.clear();
  let available=activeSites().filter(row=>canAccessSite(row.id)),defaultSite=site==='all'?(available[0]?.id||''):site,date=iso(),prefill=typeof v169DiaryPrefill==='function'?v169DiaryPrefill(defaultSite,date):{teams:'',work:'',deliveries:'',delays:'',notes:''};
  modal=`<div class="modal v1995-diary-modal"><div class="modalbox v1995-diary-editor"><button type="button" class="v1991-modal-close" onclick="v1995CancelDiary()" aria-label="Close Site Diary without saving">×</button><div class="v1995-diary-heading"><div><span class="att-kicker">DAILY SITE RECORD</span><h2>Add Site Diary Entry</h2><p>SiteSight has prepared today's known details. Everything remains editable—add, remove or rewrite anything before saving.</p></div></div><div class="v169-autofill-note"><b>Review before saving</b><span>This permanent record is only saved when you press the button below.</span></div><div class="two"><div class="field"><label for="sd-date">Date</label><input id="sd-date" class="input" type="date" value="${date}" onchange="v1995RefreshDiaryPrefill()"></div><div class="field"><label for="sd-site">Site</label><select id="sd-site" class="select" onchange="v1995RefreshDiaryPrefill()">${available.map(row=>`<option value="${row.id}" ${row.id===defaultSite?'selected':''}>${v1995Esc(row.name)}</option>`).join('')}</select></div></div><div class="field"><label for="sd-teams">People on site</label><input id="sd-teams" class="input" value="${v1995Esc(prefill.teams)}" placeholder="Names or Teams" oninput="v1995DiaryChanged('sd-teams')"></div><div class="field"><label for="sd-work">Work completed or progressed</label><textarea id="sd-work" class="textarea" rows="3" placeholder="What was completed today?" oninput="v1995DiaryChanged('sd-work')">${v1995Esc(prefill.work)}</textarea></div><div class="field"><label for="sd-del">Deliveries or scaffold</label><textarea id="sd-del" class="textarea" rows="3" placeholder="Materials, plant, scaffold or other deliveries" oninput="v1995DiaryChanged('sd-del')">${v1995Esc(prefill.deliveries)}</textarea></div><div class="field"><label for="sd-delay">Problems or delays</label><textarea id="sd-delay" class="textarea" rows="3" placeholder="What affected progress?" oninput="v1995DiaryChanged('sd-delay')">${v1995Esc(prefill.delays)}</textarea></div><div class="field"><label for="sd-notes">General notes</label><textarea id="sd-notes" class="textarea" rows="3" placeholder="Anything else that should form part of today's record" oninput="v1995DiaryChanged('sd-notes')">${v1995Esc(prefill.notes)}</textarea></div><div class="field"><label for="sd-photos">Photos <span class="muted">(optional)</span></label><input id="sd-photos" class="input" type="file" accept="image/*" multiple onchange="v1995DiaryChanged('sd-photos')"></div>${cameraPicker('sd-photos','Take site photo')}<div class="v1995-diary-actions"><button type="button" class="btn light" onclick="v1995CancelDiary()">Cancel</button><button id="v1995-save-diary" type="button" class="btn orange" onclick="saveDiaryEntry()">✓ Save Site Diary</button></div></div></div>`;
  render()
};
const v1995BaseSaveDiaryEntry=saveDiaryEntry;
saveDiaryEntry=function(){
  let date=document.getElementById('sd-date')?.value||'',siteId=document.getElementById('sd-site')?.value||'',details=['sd-teams','sd-work','sd-del','sd-delay','sd-notes'].some(id=>(document.getElementById(id)?.value||'').trim()),photos=document.getElementById('sd-photos')?.files?.length||0;
  if(!date)return toast('Choose the diary date');
  if(!siteId)return toast('Choose the Site');
  if(!details&&!photos)return toast('Add at least one diary detail or photo');
  let button=document.getElementById('v1995-save-diary');if(button){button.disabled=true;button.textContent='Saving Site Diary…'}
  if(typeof clearDirty==='function')clearDirty();v1995DiaryTouched.clear();
  return v1995BaseSaveDiaryEntry()
};
if(typeof v1991CloseModal==='function'){
  const v1995BaseCloseModal=v1991CloseModal;
  v1991CloseModal=function(){if(document.querySelector?.('.v1995-diary-editor'))return v1995CancelDiary();return v1995BaseCloseModal()}
}

// ---- Persistent phone header ---------------------------------------
const v1995BaseShell=shell;
shell=function(content){
  v1995BaseShell(content);
  let root=document.getElementById('root'),user=currentUser();if(!root||!user)return;
  root.querySelector('.mobile-global-search')?.remove();
  let unread=unreadNotifications(user).length;
  root.insertAdjacentHTML('afterbegin',`<header class="v1995-mobile-header"><div class="v1995-mobile-mark" aria-label="SiteSight">S</div><button type="button" class="v1995-header-search" onclick="openGlobalSearch()"><span aria-hidden="true">⌕</span><b>Search anything</b><small>plot, issue, person…</small></button><button type="button" class="v1995-header-account" onclick="v1995OpenMobileAccount()" aria-label="Open account menu and sign out"><span>${v1995Esc((user.name||'?')[0].toUpperCase())}</span><b>Menu</b>${unread?`<em>${unread>9?'9+':unread}</em>`:''}</button></header>`);
  let version=root.querySelector('.company > div');if(version)version.textContent=`v1.99.5 · MOBILE EXPERIENCE${db.demoProfile?' DEMO':''}`
};

// file:// testing can finish its first render before this enhancement
// file is loaded. Refresh that one local screen after all wrappers exist.
if(!sharedMode&&!window.SITESIGHT_HOSTED_DEMO&&currentUser())render();
