const API='/api/data';
const $=id=>document.getElementById(id);let projects=[],contractors=[],selectedProjectId=null;
async function get(type,extra=''){try{const r=await fetch(API+'?type='+type+extra);return r.ok?await r.json():[]}catch(e){return[]}}
async function send(data,method='POST'){const r=await fetch(API,{method,headers:{'Content-Type':'application/json'},body:JSON.stringify(data)});return await r.json()}
async function refresh(){projects=await get('projects');contractors=await get('contractors');if(projects.length&&!selectedProjectId)selectedProjectId=projects[0].id;const pc=$('projectCount'),cc=$('contractorCount'),wc=$('workCount');if(pc)pc.textContent=projects.length;if(cc)cc.textContent=contractors.length;let n=0;for(const p of projects)n+=(await get('works','&project_id='+p.id)).length;if(wc)wc.textContent=n}
function openSection(s){if(s==='projects')projectsView();else if(s==='contractors')contractorsView();else if(s==='works')worksView();else if(s==='floors')floorsView();else if(s==='calendar')entriesView();else if(s==='history')historyView();else if(s==='prints')printsView();else simpleView(s==='progress'?'ΠΡΟΟΔΟΣ & ΚΟΣΤΟΣ':s==='documents'?'ΕΓΓΡΑΦΑ':'ΙΣΤΟΡΙΚΟ')}
function simpleView(t){$('content').innerHTML='
'+t+' Η ενότητα είναι διαθέσιμη.
'}
async function historyView(){const p=projects.find(x=>x.id===selectedProjectId)||projects[0];const ph=p?await get('project_history','&project_id='+p.id):[];const audit=await get('history');const projectHtml=ph.length?ph.map(e=>''+e.entry_date+' · '+(e.contractor_name||'Χωρίς συνεργείο')+' '+ (e.work_description||'Χωρίς περιγραφή εργασίας') +'
'+(e.floor_name||'Χωρίς όροφο')+' · '+(e.people_count||0)+' άτομα'+(e.machines?' · '+e.machines:'')+(e.comments?' · '+e.comments:'')+' ').join(''):'Δεν υπάρχουν ακόμη ημερήσιες καταχωρήσεις για το έργο.
';const auditHtml=audit.length?audit.map(h=>''+h.created_at.replace('T',' ').slice(0,16)+' · '+(h.project_name||'Γενικό')+' '+h.description+'
'+h.action+(h.details?' · '+h.details:'')+' ').join(''):'Δεν υπάρχουν ακόμη αλλαγές συστήματος.
';$('content').innerHTML='
Ιστορικό έργου '+(p?.name||'')+' '+projectHtml+'
Ιστορικό αλλαγών συστήματος '+auditHtml+'
'}
async function printsView(){const p=projects.find(x=>x.id===selectedProjectId)||projects[0];if(!p){simpleView('ΕΚΤΥΠΩΣΕΙΣ');return}const es=(await get('entries')).filter(e=>e.project_id===p.id).sort((a,b)=>String(a.entry_date).localeCompare(String(b.entry_date)));const ws=await get('works','&project_id='+p.id);$('content').innerHTML='
Εκτυπώσεις '+p.name+' Ημερολόγιο Έργου Ημερήσιες εργασίες · συνεργεία · άτομα · μηχανήματα · όροφοι · σχόλια Πρόοδος Έργου Εργασίες · ποσοστά ολοκλήρωσης · κατάσταση Ιστορικό Έργου Χρονολογική εικόνα των εργασιών του εργοταξίου Πιστοποίηση Εργασιών Προετοιμασία μορφής πιστοποίησης — θα συνδεθεί με τις συμβάσεις και τις αξίες
'}async function printPreview(kind){const p=projects.find(x=>x.id===selectedProjectId)||projects[0];if(!p)return;const es=(await get('entries')).filter(e=>e.project_id===p.id).sort((a,b)=>String(a.entry_date).localeCompare(String(b.entry_date)));const ws=await get('works','&project_id='+p.id);let title='';let html='';if(kind==='calendar'||kind==='history'){title=kind==='calendar'?'Ημερολόγιο Έργου':'Ιστορικό Έργου';html=es.length?es.map(e=>''+e.entry_date+' '+ (e.contractor_name||'—')+' '+ (e.work_description||'—')+' '+ (e.floor_name||'—')+' '+ (e.people_count||0)+' '+ (e.machines||'—')+' '+ (e.comments||'')+' ').join(''):'Δεν υπάρχουν καταχωρήσεις. '}else if(kind==='progress'){title='Πρόοδος Έργου';html=ws.length?ws.map(w=>''+w.name+' '+w.status+' '+ (w.progress||0)+'% ').join(''):'Δεν υπάρχουν εργασίες. '}else{title='Πιστοποίηση Εργασιών';html='Η αναλυτική πιστοποίηση θα συνδεθεί με συμβάσεις, αξίες και πιστοποιημένες ποσότητες. '}const cols=kind==='progress'?'Εργασία Κατάσταση Πρόοδος ':'Ημερομηνία Συνεργείο Εργασία Όροφος Άτομα Μηχανήματα Σχόλια ';const box=document.createElement('div');box.className='printPreview';box.innerHTML='Κλείσιμο Εκτύπωση / PDF
CONSTRUCTION MANAGER
'+title+' '+p.name+' '+(p.address||'')+' · Ημερομηνία έκδοσης '+new Date().toLocaleDateString('el-GR')+'
';document.body.appendChild(box)}
async function openQuickPopup(type,anchor){const p=projects.find(x=>x.id===selectedProjectId)||projects[0];if(!p&&type!=='projects')return;document.querySelector('.quickBackdrop')?.remove();document.querySelector('.quickPopup')?.remove();const titles={projects:'Έργα',works:'Εργασίες',contractors:'Εργολάβοι & Συνεργεία',floors:'Όροφοι',machines:'Μηχανήματα',calendar:'Ημερολόγιο',progress:'Πρόοδος & Κόστος',documents:'Έγγραφα',history:'Ιστορικό',prints:'Εκτυπώσεις'};let body='Επιλέξτε τι θέλετε να κάνετε.
';if(type==='works'){const ws=await get('works','&project_id='+p.id);body=ws.length?ws.map(w=>''+w.name+' '+w.progress+'% · '+w.status+'
').join(''):'Δεν υπάρχουν εργασίες.
';body+='+ Νέα εργασία '}else if(type==='contractors'){const cs=contractors||[];body=cs.length?cs.map(c=>''+c.company_name+' '+((c.specialty||c.relationship||'').trim())+'
Διόρθωση ').join(''):'Δεν υπάρχουν καταχωρημένα συνεργεία.
';body+='+ Νέο συνεργείο '}else if(type==='projects'){const ps=projects||[];body=ps.length?ps.map(x=>''+x.name+' '+((x.address||'').trim())+'
').join(''):'Δεν υπάρχουν καταχωρημένα έργα.
';body+='+ Νέο έργο '}else if(type==='floors'){const fs=await get('floors','&project_id='+p.id);body=fs.length?fs.map(f=>''+f.name+'
').join(''):'Δεν υπάρχουν καταχωρημένοι όροφοι στο έργο.
';body+='+ Νέος όροφος '}else if(type==='calendar'){const es=(await get('entries')).filter(e=>e.project_id===p.id);body=es.length?es.map(e=>''+e.entry_date+' · '+(e.contractor_name||'—')+' '+(e.work_description||'Χωρίς εργασία')+' · '+(e.floor_name||'Χωρίς όροφο')+' · '+(e.people_count||0)+' άτομα'+(e.machines?' · '+e.machines:'')+'
Διόρθωση × ').join(''):'Δεν υπάρχουν ημερήσιες καταχωρήσεις.
';body+='+ Νέα ημερήσια καταχώρηση '}else if(type==='machines'){const es=(await get('entries')).filter(e=>e.project_id===p.id);const machines=[...new Set(es.flatMap(e=>String(e.machines||'').split(/[,;\n]+/).map(x=>x.trim()).filter(Boolean)))];body=machines.length?machines.map(m=>''+m+'
').join(''):'Δεν έχουν καταχωρηθεί ακόμη μηχανήματα στο έργο.
';body+='+ Καταχώρηση μηχανήματος '}else if(type==='history'){const hs=await get('project_history','&project_id='+p.id);body=hs.length?hs.slice(-20).reverse().map(h=>''+h.entry_date+' · '+(h.contractor_name||'Χωρίς συνεργείο')+' '+ (h.work_description||'Χωρίς περιγραφή') +' · '+(h.floor_name||'Χωρίς όροφο')+' · '+(h.people_count||0)+' άτομα'+(h.machines?' · '+h.machines:'')+'
').join(''):'Δεν υπάρχουν ακόμη ημερήσιες καταχωρήσεις για το έργο.
'}const back=document.createElement('div');back.className='quickBackdrop';back.onclick=closeQuickPopup;document.body.appendChild(back);const pop=document.createElement('div');pop.className='quickPopup';pop.innerHTML='× ΕΡΓΟ
'+titles[type]+' · '+(p?.name||'Construction Manager')+' '+body+'
Άνοιγμα πλήρους ενότητας ';document.body.appendChild(pop)}
function closeQuickPopup(){document.querySelector('.quickBackdrop')?.remove();document.querySelector('.quickPopup')?.remove()}
function projectSelect(name='project_id'){return 'Έργο'+projects.map(p=>''+p.name+' ').join('')+' '}
function projectsView(){$('content').innerHTML='
Έργα + Νέο έργο '+projects.map(p=>'
'+p.name+' '+ (p.address||'')+'
Άνοιγμα ').join('')+'
'}
function contractorsView(){$('content').innerHTML='
Εργολάβοι & Συνεργεία + Νέο συνεργείο '+contractors.map(c=>'
'+c.company_name+' '+ (c.specialty||'')+'
Διόρθωση Εργασίες & αξίες Αφαίρεση ').join('')+'
'}
async function worksView(){if(!projects.length)return simpleView('ΕΡΓΑΣΙΕΣ');let p=projects.find(x=>x.id===selectedProjectId)||projects[0];selectedProjectId=p.id;let ws=await get('works','&project_id='+p.id),as=await get('assignments','&project_id='+p.id);$('content').innerHTML='
Εργασίες + Νέα εργασία '+projectSelect('work_project')+''+ws.map(w=>'
'+w.name+' '+w.status+' · '+w.progress+'%'+((as.filter(a=>a.work_id===w.id).map(a=>a.contractor_name).join(', '))?' · '+as.filter(a=>a.work_id===w.id).map(a=>a.contractor_name).join(', '):' · Χωρίς συνεργείο')+'
Διόρθωση Σύνδεση συνεργείου Διαγραφή ').join('')+'
';$('selProject').onchange=e=>{selectedProjectId=e.target.value;worksView()}}
async function floorsView(){if(!projects.length)return simpleView('ΟΡΟΦΟΙ');let p=projects.find(x=>x.id===selectedProjectId)||projects[0],fs=await get('floors','&project_id='+p.id);$('content').innerHTML='
Όροφοι + Νέος όροφος '+projectSelect('floor_project')+''+fs.map(f=>'
'+f.name+'
').join('')+'
';$('selProject').onchange=e=>{selectedProjectId=e.target.value;floorsView()}}
async function entriesView(){let es=await get('entries');const groups={};es.forEach(e=>{const k=e.entry_date+'|'+e.project_name;(groups[k]??=[]).push(e)});const html=Object.entries(groups).map(([k,rows])=>{const [date,project]=k.split('|');return ''+date+' · '+project+'
'+rows.map(e=>'
'+ (e.contractor_name||'—')+' '+ (e.work_description||'—')+' · '+(e.floor_name||'—')+'
'+ (e.people_count||0)+' άτομα'+(e.machines?' · '+e.machines:'')+' Διόρθωση Αφαίρεση
').join('')+'
'}).join('');$('content').innerHTML='
Ημερολόγιο + Καταχώρηση '+html+'
'}
async function openModal(type,id){$('modal').classList.remove('hidden');let h='';let item=null;if(id){if(type==='editWork'||type==='workAssignment')item=(await get('works','&project_id='+selectedProjectId)).find(x=>x.id===id);if(type==='editContractor')item=contractors.find(x=>x.id===id)}
if(type==='project')h='Νέο έργο ';
if(type==='contractor'||type==='editContractor'){let c=item||{};h=''+ (item?'Διόρθωση συνεργείου':'Νέο συνεργείο')+' '}
if(type==='assignment'){let c=contractors.find(x=>x.id===id)||{};h='Εργασίες · '+(c.company_name||'')+' ';$('modalBody').innerHTML=h;const ap=$('selProject');const load=async()=>{const ws=await get('works','&project_id='+ap.value),as=await get('assignments','&project_id='+ap.value);const linked=new Set(as.filter(a=>a.contractor_id===c.id).map(a=>a.work_id));$('assignmentWorks').innerHTML=ws.length?ws.map(w=>''+w.name+' '+w.status+' · '+(w.progress||0)+'% ').join(''):'Δεν υπάρχουν εργασίες στο έργο.
'};ap.onchange=load;load()}
if(type==='workAssignment'){const w=item||{};h='Σύνδεση συνεργείου · '+(w.name||'')+' ';$('modalBody').innerHTML=h}
if(type==='floor')h='Νέος όροφος '+projectSelect()+'Προσθήκη ';
if(type==='work'||type==='editWork'){let w=item||{};h=''+ (item?'Διόρθωση εργασίας':'Νέα εργασία')+' '+projectSelect('project_id')+'Προγραμματισμένη Σε εξέλιξη Ολοκληρωμένη Αποθήκευση '}
if(type==='editEntry'){const es=await get('entries');const e=es.find(x=>x.id===id)||{};selectedProjectId=e.project_id||selectedProjectId;const dayEntries=es.filter(x=>x.project_id===e.project_id&&x.entry_date===e.entry_date&&x.contractor_id===e.contractor_id);const ws=await get('works','&project_id='+e.project_id),fs=await get('floors','&project_id='+e.project_id);const workOptions=ws;h='Διόρθωση ημερήσιας καταχώρησης '+(e.contractor_name||e.company_name||'Εργολάβος / συνεργείο')+'
Όλες οι εργασίες του ίδιου εργολάβου για την ίδια ημέρα
'+dayEntries.map(x=>'
Εργασία '+workOptions.map(w=>''+w.name+' ').join('')+'Όροφος '+fs.map(f=>''+f.name+' ').join('')+'Ποσοστό ολοκλήρωσης %
').join('')+'
'+(e.comments||'')+' Αποθήκευση διόρθωσης ';$('modalBody').innerHTML=h}
if(type==='entry')h='Ημερήσια καταχώρηση '+projectSelect()+'Εργολάβος / συνεργείο '+contractors.map(c=>''+c.company_name+' ').join('')+'+ Άλλη εργασία + Άλλος εργολάβος / συνεργείο Αποθήκευση ημερήσιας καταχώρησης ';$('modalBody').innerHTML=h;const ep=$('selProject');if(type==='entry'){const loadGroups=async()=>{const as=await get('assignments','&project_id='+ep.value),ws=await get('works','&project_id='+ep.value),fs=await get('floors','&project_id='+ep.value);document.querySelectorAll('.contractorGroup').forEach(group=>{const contractor=group.querySelector('.entryContractor').value;const linked=new Set(as.filter(a=>a.contractor_id===contractor).map(a=>a.work_id));const allowed=contractor?ws.filter(w=>linked.has(w.id)):[];group.querySelectorAll('.entryWorkRow').forEach(row=>{const current=row.querySelector('.entryWork').value;row._entryWorks=allowed;row.querySelector('.entryWork').innerHTML='Εργασία '+allowed.map(w=>''+w.name+' ').join('');row.querySelector('.entryFloor').innerHTML='Όροφος '+fs.map(f=>''+f.name+' ').join('')})})};document.querySelectorAll('.entryContractor').forEach(s=>s.onchange=loadGroups);window.addWorkRow=btn=>{const group=btn.closest('.contractorGroup'),box=group.querySelector('.entryWorks'),source=box.querySelector('.entryWorkRow:last-child'),row=source.cloneNode(true);row.querySelector('.entryWork').selectedIndex=0;row.querySelector('.entryFloor').selectedIndex=0;row.querySelector('[name="progress"]').value='';row._entryWorks=source._entryWorks||[];box.appendChild(row);loadGroups()};window.addContractorGroup=()=>{const box=$('contractorGroups'),source=box.querySelector('.contractorGroup:last-child'),group=source.cloneNode(true);group.querySelector('.entryContractor').selectedIndex=0;group.querySelectorAll('.entryWorkRow').forEach((row,i)=>{if(i>0)row.remove();row.querySelector('.entryWork').selectedIndex=0;row.querySelector('.entryFloor').selectedIndex=0;row.querySelector('[name="progress"]').value=''});group.querySelector('[name="people_count"]').value='';group.querySelector('[name="machines"]').value='';group.querySelector('[name="comments"]').value='';box.appendChild(group);group.querySelector('.entryContractor').onchange=loadGroups;loadGroups()};ep.onchange=()=>{selectedProjectId=ep.value;loadGroups()};loadGroups()}}
async function newDailyWork(btn){const row=btn.closest('.entryWorkRow'),group=btn.closest('.contractorGroup'),contractor_id=group?.querySelector('.entryContractor')?.value;if(!contractor_id){alert('Πρώτα επίλεξε εργολάβο / συνεργείο.');return}const name=prompt('Όνομα νέας εργασίας');if(!name||!name.trim())return;const pid=$('selProject').value;const r=await send({type:'work',project_id:pid,name:name.trim(),status:'active',progress:0},'POST');if(r.error){alert(r.error);return}const w=r;const a=await send({type:'assignment',project_id:pid,contractor_id,work_id:w.id,contract_value:0},'POST');if(a.error){alert(a.error);return}const box=group.querySelector('.entryWorks'),newRow=row.cloneNode(true);newRow.querySelector('.entryWork').innerHTML='Εργασία '+w.name+' ';newRow.querySelector('.entryWork').value=w.id;newRow.querySelector('.entryFloor').value=row.querySelector('.entryFloor').value||'';newRow.querySelector('[name="progress"]').value='';newRow._entryWorks=[...(row._entryWorks||[]),w];row.insertAdjacentElement('afterend',newRow);alert('Η νέα εργασία δημιουργήθηκε, συνδέθηκε με τον εργολάβο και προστέθηκε ως ξεχωριστή εργασία της ίδιας ημέρας.');}
function openMachinePicker(btn){const input=btn.closest('.contractorGroup')?.querySelector('[name="machines"]')||btn.closest('.machinePicker')?.querySelector('[name="machines"]');if(!input)return;document.querySelector('.machinePickerPopup')?.remove();const current=(input.value||'').split(',').map(x=>x.trim()).filter(Boolean);const options=['Τσαπάκι','Bobcat','Φορτηγό','Κάδος / Skip','Γερανός','Ανυψωτικό','Άλλο'];const box=document.createElement('div');box.className='machinePickerPopup';box.innerHTML='';document.body.appendChild(box);box._target=input}function saveMachinePicker(btn){const pop=btn.closest('.machinePickerPopup'),input=pop._target,vals=[...pop.querySelectorAll('input[type="checkbox"]:checked')].map(x=>x.value);const custom=pop.querySelector('#customMachine').value.trim();if(custom)vals.push(custom);input.value=[...new Set(vals)].join(', ');const summary=input.closest('.machinePicker')?.querySelector('.machineSummary');if(summary)summary.textContent=input.value||'Επιλογή μηχανημάτων';pop.remove()}async function save(ev,type){ev.preventDefault();if(type==='editEntry'){const f=ev.target;const pid=f.querySelector('[name="project_id"]').value,date=f.querySelector('[name="entry_date"]').value,cid=f.querySelector('[name="contractor_id"]').value;const ws=await get('works','&project_id='+pid);for(const row of [...f.querySelectorAll('.editWorkRow')]){const work_id=row.querySelector('[name="work_id"]').value||null;if(!work_id)continue;const work=ws.find(w=>w.id===work_id);const d={type:'entry',id:row.dataset.id,project_id:pid,entry_date:date,contractor_id:cid,floor_id:row.querySelector('[name="floor_id"]').value||null,work_id,work_description:work?work.name:null,progress:row.querySelector('[name="progress"]').value||'',people_count:f.querySelector('[name="people_count"]').value||0,machines:f.querySelector('[name="machines"]').value||null,comments:f.querySelector('[name="comments"]').value||null};const r=await send(d,'PUT');if(r.error){alert(r.error);return}}closeModal();await refresh();openSection('calendar');return}if(type==='entry'){const f=ev.target,pid=f.querySelector('[name="project_id"]').value,date=f.querySelector('[name="entry_date"]').value;for(const group of [...f.querySelectorAll('.contractorGroup')]){const contractor_id=group.querySelector('[name="contractor_id"]').value;if(!contractor_id)continue;const people_count=group.querySelector('[name="people_count"]').value||0,machines=group.querySelector('[name="machines"]').value||null,comments=group.querySelector('[name="comments"]').value||null;for(const row of [...group.querySelectorAll('.entryWorkRow')]){const work_id=row.querySelector('[name="work_id"]').value||null;if(!work_id)continue;const work=(row._entryWorks||[]).find(w=>w.id===work_id);if(work)await send({type:'assignment',project_id:pid,contractor_id,work_id,contract_value:0},'POST');const r=await send({type:'entry',project_id:pid,entry_date:date,contractor_id,floor_id:row.querySelector('[name="floor_id"]').value||null,work_description:work?work.name:null,work_id,progress:row.querySelector('[name="progress"]').value,people_count,machines,comments},'POST');if(r.error){alert(r.error);return}}}closeModal();await refresh();openSection('calendar');return}if(type==='contractorWorks'){const f=ev.target;const work_ids=[...f.querySelectorAll('input[name="work_ids"]:checked')].map(x=>x.value);const d={type:'contractor_work_links',project_id:f.querySelector('[name="project_id"]').value,contractor_id:f.querySelector('[name="contractor_id"]').value,work_ids};const r=await send(d,'PUT');if(r.error){alert(r.error);return}closeModal();await refresh();openSection('contractors');return}const d={type:type==='editWork'?'work':type==='editContractor'?'contractor':type};new FormData(ev.target).forEach((v,k)=>d[k]=v);if(type==='work'||type==='editWork'||type==='floor'||type==='assignment')d.project_id=d.project_id||selectedProjectId;const r=await send(d,type==='editWork'||type==='editContractor'?'PUT':'POST');if(r.error){alert(r.error);return}closeModal();await refresh();openSection(type.includes('contractor')||type==='assignment'?'contractors':type.includes('work')?'works':type==='floor'?'floors':type==='project'?'projects':'calendar')}
async function deleteWork(id){if(!confirm('Να διαγραφεί αυτή η εργασία;'))return;await send({type:'work',id},'DELETE');worksView()}
async function removeContractor(id){if(!confirm('Να διαγραφεί αυτός ο εργολάβος / συνεργείο;'))return;const r=await send({type:'contractor',id},'DELETE');if(r.error){alert(r.error);return}await refresh();contractorsView()}
async function deleteEntry(id){if(!confirm('Να αφαιρεθεί αυτή η ημερήσια καταχώρηση;'))return;const r=await send({type:'entry',id},'DELETE');if(r.error){alert(r.error);return}closeQuickPopup();await refresh();openSection('calendar')}
function closeModal(){$('modal').classList.add('hidden')}
window.openSection=openSection;window.openModal=openModal;window.closeModal=closeModal;window.save=save;window.deleteWork=deleteWork;window.openQuickPopup=openQuickPopup;window.openMachinePicker=openMachinePicker;window.saveMachinePicker=saveMachinePicker;refresh();