const {store,calc,fmt,timer}=window.EG;
const {useNow,useStore,Pill,PageHead,SectionTitle,Kpi,KpiRow,Table,Tr,Td,EmptyState,Search,FilterRow,Toggle,Modal,SidePanel,FormGroup,Source,DataRow,TimerCell,label12}=window;
const {Icon,Button,IconButton,Card,Amount,ProgressBar,Tabs,Badge,Alert,FormField,Input,Select,Textarea,Checkbox}=window;

/* ============ PROJECTFORMULIER ============ */
function ProjectForm({project,customerId,onClose}){
  const [f,setF]=React.useState(project||{ref:window.EG.nextProjectRef(),name:'',customerId:customerId||store.customers[0].id,contact:'',status:'nieuw',
    description:'',rate:store.settings.defaultRate,costRate:52,budgetHours:'',km:'',notes:''});
  const set=(k)=>e=>setF({...f,[k]:e.target?e.target.value:e});
  React.useEffect(()=>{if(!f.contact){const c=calc.customer(f.customerId);if(c)setF(s=>({...s,contact:c.contact}))}},[f.customerId]);
  const save=()=>{
    if(!f.name.trim()){window.EG_TOAST({tone:'danger',title:'Projectnaam is verplicht'});return}
    const item={...f,id:f.id||('p-'+f.ref.slice(5)+'-'+Math.floor(Math.random()*99)),rate:Number(f.rate)||0,costRate:Number(f.costRate)||0,
      budgetHours:Number(f.budgetHours)||0,km:Number(f.km)||0};
    store.upsert('projects',item);
    window.EG_TOAST({title:project?'Project bijgewerkt':'Project aangemaakt',detail:item.ref+' · '+item.name});
    onClose();if(!project)window.EG_NAV('project',{id:item.id});
  };
  return <SidePanel title={project?'Project bewerken':'Nieuw project'} sub={project?project.ref:'Werknummer is automatisch voorgesteld en aanpasbaar.'} onClose={onClose}
    footer={<><Button variant="secondary" onClick={onClose}>Annuleren</Button><Button onClick={save}>{project?'Wijzigingen opslaan':'Project aanmaken'}</Button></>}>
    <FormGroup title="Projectgegevens">
      <FormField label="Werknummer"><Input value={f.ref} onChange={set('ref')} style={{fontFamily:'var(--font-mono)'}}/></FormField>
      <FormField label="Status"><Select value={f.status} onChange={set('status')} options={window.EG.PROJECT_STATUS.map(s=>({value:s.v,label:s.label}))}/></FormField>
      <FormField label="Projectnaam" required style={{gridColumn:'span 2'}}><Input value={f.name} onChange={set('name')} placeholder="Nieuwbouw bedrijfspand Almelo"/></FormField>
      <FormField label="Klant"><Select value={f.customerId} onChange={set('customerId')} options={store.customers.map(c=>({value:c.id,label:c.name}))}/></FormField>
      <FormField label="Contactpersoon"><Input value={f.contact} onChange={set('contact')}/></FormField>
      <FormField label="Omschrijving" style={{gridColumn:'span 2'}}><Textarea rows={3} value={f.description} onChange={set('description')}/></FormField>
    </FormGroup>
    <FormGroup title="Financieel">
      <FormField label="Facturatietarief per uur"><Input value={f.rate} onChange={set('rate')} type="number"/></FormField>
      <FormField label="Intern kostentarief"><Input value={f.costRate} onChange={set('costRate')} type="number"/></FormField>
      <FormField label="Begrote uren"><Input value={f.budgetHours} onChange={set('budgetHours')} type="number"/></FormField>
      <FormField label="Kilometers naar bouwplaats"><Input value={f.km} onChange={set('km')} type="number"/></FormField>
    </FormGroup>
    <FormGroup title="Aanvullend" cols={1}>
      <FormField label="Bijzonderheden"><Textarea rows={3} value={f.notes} onChange={set('notes')}/></FormField>
    </FormGroup></SidePanel>;
}

/* ============ PROJECTENOVERZICHT ============ */
const FILTERS=['Alle','Actief','Wachten','Gereed','Gefactureerd','Afgesloten'];
function Projecten({params}){
  useStore();const [q,setQ]=React.useState('');const [fil,setFil]=React.useState('Alle');
  const [nieuw,setNieuw]=React.useState(!!(params&&params.nieuw));
  const rows=store.projects.filter(p=>{
    const c=calc.customer(p.customerId);
    const okQ=[p.ref,p.name,c?c.name:''].join(' ').toLowerCase().includes(q.toLowerCase());
    const okF=fil==='Alle'||window.EG.projectStatus(p.status).label.toLowerCase().startsWith(fil.toLowerCase());
    return okQ&&okF;});
  return <div>
    <PageHead title="Projecten" sub="Alle werknummers met geschreven uren, begroting en te factureren waarde."
      actions={<Button icon="plus" onClick={()=>setNieuw(true)} style={{whiteSpace:'nowrap'}}>Nieuw project</Button>}/>
    <div style={{display:'flex',justifyContent:'space-between',gap:20,marginBottom:18,flexWrap:'wrap'}}>
      <FilterRow items={FILTERS} value={fil} onChange={setFil}/>
      <Search value={q} onChange={setQ} placeholder="Zoek op werknummer, project of klant..."/></div>
    <Card padding="0">
      {rows.length?<Table cols={[{label:'Werknr.'},{label:'Project'},{label:'Klant'},{label:'Uren',right:true},{label:'Begroot',right:true},
        {label:'Nog te factureren',right:true},{label:'Gefactureerd',right:true},{label:'Status'},{label:'Timer'}]}>
        {rows.map(p=>{const c=calc.customer(p.customerId);const h=calc.hours(p.id);const over=p.budgetHours>0&&h>p.budgetHours;
          return <Tr key={p.id} onClick={()=>window.EG_NAV('project',{id:p.id})}>
            <Td mono muted>{p.ref}</Td>
            <Td style={{fontWeight:500,color:'var(--ink-900)'}}>{p.name}</Td>
            <Td muted>{c?c.name:''}</Td>
            <Td right><Amount value={h} unit="uur" size={13.5} tone={over?'danger':'strong'}/></Td>
            <Td right muted mono>{fmt.h(p.budgetHours)}</Td>
            <Td right><Amount value={calc.unbilled(p.id).total} size={13.5}/></Td>
            <Td right><Amount value={calc.invoicedOf(p.id)} size={13.5} tone="muted"/></Td>
            <Td><Pill kind="project" value={p.status}/></Td>
            <Td>{['afgesloten','gefactureerd'].includes(p.status)?<span style={{fontSize:12.5,color:'var(--text-faint)'}}>—</span>:<TimerCell project={p} onStop={()=>window.EG_STOP()}/>}</Td></Tr>})}
      </Table>:<EmptyState icon="folder" title="Geen projecten gevonden" action={<Button variant="secondary" onClick={()=>{setQ('');setFil('Alle')}}>Filters wissen</Button>}/>}
    </Card>
    {nieuw?<ProjectForm onClose={()=>setNieuw(false)}/>:null}</div>;
}

/* ============ UREN-FORMULIER (handmatig / bewerken) ============ */
function EntryForm({entry,projectId,onClose}){
  const first=projectId?calc.project(projectId):null;
  const [cid,setCid]=React.useState(entry?calc.project(entry.projectId).customerId:(first?first.customerId:store.customers[0].id));
  const [f,setF]=React.useState(entry||{date:window.EG.iso(new Date()),projectId:projectId||'',description:'',hours:'',billable:store.settings.defaultBillable,note:'',source:'manual',start:'',stop:''});
  const projects=store.projects.filter(p=>p.customerId===cid);
  React.useEffect(()=>{if(!projects.find(p=>p.id===f.projectId))setF(s=>({...s,projectId:projects[0]?projects[0].id:''}))},[cid]);
  const set=(k)=>e=>setF({...f,[k]:e.target?e.target.value:e});
  const save=()=>{
    const h=parseFloat(String(f.hours).replace(',','.'));
    if(!f.projectId||!h){window.EG_TOAST({tone:'danger',title:'Project en aantal uren zijn verplicht'});return}
    const item={...f,id:f.id||window.EG.uid('t'),hours:Math.round(h*100)/100,invoiceId:f.invoiceId||null};
    store.upsert('timeEntries',item);
    window.EG_TOAST({title:entry?'Urenregel bijgewerkt':'Uren opgeslagen',detail:fmt.h(item.hours)+' op '+calc.project(item.projectId).ref});
    onClose();
  };
  return <Modal title={entry?'Urenregel bewerken':'Handmatig uren toevoegen'} onClose={onClose} width={560}
    footer={<><Button variant="secondary" onClick={onClose}>Annuleren</Button><Button onClick={save}>Uren opslaan</Button></>}>
    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:16}}>
      <FormField label="Datum"><Input type="date" value={f.date} onChange={set('date')}/></FormField>
      <FormField label="Aantal uren" hint="Decimaal, bijvoorbeeld 2,42"><Input value={f.hours} onChange={set('hours')} placeholder="2,42"/></FormField>
      <FormField label="Klant"><Select value={cid} onChange={e=>setCid(e.target.value)} options={store.customers.map(c=>({value:c.id,label:c.name}))}/></FormField>
      <FormField label="Project"><Select value={f.projectId} onChange={set('projectId')} options={projects.map(p=>({value:p.id,label:p.ref+' · '+p.name}))}/></FormField>
      <FormField label="Omschrijving werkzaamheden" style={{gridColumn:'span 2'}}><Input value={f.description} onChange={set('description')} placeholder="Calculatie bouwkundig"/></FormField>
      <FormField label="Facturabel"><Toggle checked={!!f.billable} onChange={v=>setF({...f,billable:v})}/></FormField>
      <FormField label="Notitie" style={{gridColumn:'span 2'}}><Textarea rows={2} value={f.note} onChange={set('note')}/></FormField>
    </div></Modal>;
}

/* ============ STOP-TIMER MODAL ============ */
function StopTimerModal({at,onClose,onSaved}){
  const p=calc.project(at.projectId);const startedAt=new Date(at.startedAt);
  const elapsed=Math.max(60,(Date.now()-startedAt.getTime())/1000);
  const exact=elapsed/3600;
  const s=store.settings;
  const [hours,setHours]=React.useState(String(fmt.h(calc.round(exact))).replace('.',','));
  const [desc,setDesc]=React.useState('');const [billable,setBillable]=React.useState(s.defaultBillable);const [note,setNote]=React.useState('');
  const [date,setDate]=React.useState(window.EG.iso(startedAt));
  const stopAt=new Date();
  const save=()=>{
    const h=parseFloat(String(hours).replace(',','.'))||calc.round(exact);
    store.upsert('timeEntries',{id:window.EG.uid('t'),projectId:p.id,date,description:desc||'Werkzaamheden',source:'timer',
      start:fmt.time(startedAt),stop:fmt.time(stopAt),hours:Math.round(h*100)/100,billable,note,invoiceId:null});
    timer.clear();
    window.EG_TOAST({title:'Urenregistratie opgeslagen',detail:fmt.h(h)+' op '+p.ref+' · '+p.name});
    onSaved&&onSaved();onClose();
  };
  return <Modal title="Urenregistratie opslaan" sub={p.ref+' · '+p.name} onClose={onClose} tone
    footer={<><Button variant="secondary" onClick={onClose}>Annuleren</Button><Button onClick={save}>Uren opslaan</Button></>}>
    <div style={{textAlign:'center',padding:'6px 0 22px',borderBottom:'1px solid var(--border-hairline)',marginBottom:22}}>
      <div style={{fontFamily:'var(--font-mono)',fontSize:40,fontWeight:500,letterSpacing:'-.02em',color:'var(--ink-900)',fontVariantNumeric:'tabular-nums'}}>{fmt.clock(elapsed)}</div>
      <div style={{display:'flex',justifyContent:'center',gap:32,marginTop:16}}>
        {[['Start',fmt.time(startedAt)],['Stop',fmt.time(stopAt)],['Duur',fmt.h(calc.round(exact))+' uur']].map(([l,v])=>
          <div key={l}><div style={{...label12,fontSize:10}}>{l}</div>
            <div style={{marginTop:5,fontFamily:'var(--font-mono)',fontSize:15,color:'var(--ink-900)'}}>{v}</div></div>)}</div>
      {s.rounding!=='none'?<div style={{marginTop:14,fontSize:12.5,color:'var(--text-faint)'}}>Werkelijke tijd {fmt.clock(elapsed)} · geregistreerd {fmt.h(calc.round(exact))} uur (afronding op {s.rounding} minuten)</div>:null}
    </div>
    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:16}}>
      <FormField label="Omschrijving" style={{gridColumn:'span 2'}}><Input autoFocus value={desc} onChange={e=>setDesc(e.target.value)} placeholder="Waar heb je aan gewerkt?"/></FormField>
      <FormField label="Duur" hint="Aanpasbaar vóór opslaan"><Input value={hours} onChange={e=>setHours(e.target.value)}/></FormField>
      <FormField label="Datum"><Input type="date" value={date} onChange={e=>setDate(e.target.value)}/></FormField>
      <FormField label="Facturabel"><Toggle checked={billable} onChange={setBillable}/></FormField>
      <FormField label="Notitie" hint="Optioneel"><Input value={note} onChange={e=>setNote(e.target.value)}/></FormField>
    </div></Modal>;
}

/* ============ CONFLICT: TWEEDE TIMER ============ */
function ConflictModal({at,nextProjectId,onClose,onSwitch}){
  useNow(1000);const cur=calc.project(at.projectId);const nxt=calc.project(nextProjectId);
  return <Modal title="Er loopt al een timer" onClose={onClose} width={500}
    footer={<><Button variant="secondary" onClick={onClose}>Huidige timer behouden</Button><Button onClick={onSwitch}>Huidige stoppen en nieuwe starten</Button></>}>
    <p style={{margin:'0 0 18px',fontSize:14.5,color:'var(--text-body)',lineHeight:1.62}}>Je registreert momenteel tijd op:</p>
    <div style={{border:'1px solid var(--border-hairline)',borderLeft:'3px solid var(--teal-600)',borderRadius:'var(--radius-sm)',padding:'16px 18px',
      display:'flex',justifyContent:'space-between',alignItems:'center',gap:20}}>
      <div><div style={{fontFamily:'var(--font-mono)',fontSize:12,color:'var(--text-faint)'}}>{cur.ref}</div>
        <div style={{fontFamily:'var(--font-display)',fontSize:15.5,fontWeight:600,marginTop:3}}>{cur.name}</div></div>
      <div style={{fontFamily:'var(--font-mono)',fontSize:21,color:'var(--teal-700)',fontVariantNumeric:'tabular-nums'}}>{fmt.clock(timer.elapsed(at))}</div></div>
    <p style={{margin:'18px 0 0',fontSize:13.5,color:'var(--text-muted)',lineHeight:1.62}}>Als je de nieuwe timer start, wordt de huidige registratie eerst gestopt. Je legt dan de gewerkte tijd op {cur.ref} vast voordat de timer op {nxt?nxt.ref:''} begint.</p>
  </Modal>;
}

/* ============ PROJECTKOSTEN ============ */
function CostForm({cost,projectId,onClose}){
  const [f,setF]=React.useState(cost||{date:window.EG.iso(new Date()),type:'Kilometers',description:'',qty:'',unitPrice:'',rechargeable:true});
  const set=(k)=>e=>setF({...f,[k]:e.target?e.target.value:e});
  const qty=parseFloat(String(f.qty).replace(',','.'))||0,price=parseFloat(String(f.unitPrice).replace(',','.'))||0;
  const save=()=>{
    if(!qty||!price){window.EG_TOAST({tone:'danger',title:'Aantal en prijs per eenheid zijn verplicht'});return}
    store.upsert('projectCosts',{...f,id:f.id||window.EG.uid('k'),projectId:f.projectId||projectId,qty,unitPrice:price,invoiceId:f.invoiceId||null});
    window.EG_TOAST({title:'Kostenregel opgeslagen',detail:f.type+' · '+fmt.eur(qty*price)});onClose();
  };
  return <Modal title={cost?'Kostenregel bewerken':'Kosten toevoegen'} onClose={onClose} width={540}
    footer={<><Button variant="secondary" onClick={onClose}>Annuleren</Button><Button onClick={save}>Kosten opslaan</Button></>}>
    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:16}}>
      <FormField label="Datum"><Input type="date" value={f.date} onChange={set('date')}/></FormField>
      <FormField label="Kostensoort"><Select value={f.type} onChange={set('type')} options={window.EG.COST_TYPES}/></FormField>
      <FormField label="Omschrijving" style={{gridColumn:'span 2'}}><Input value={f.description} onChange={set('description')}/></FormField>
      <FormField label="Aantal"><Input value={f.qty} onChange={set('qty')} placeholder="36"/></FormField>
      <FormField label="Prijs per eenheid"><Input value={f.unitPrice} onChange={set('unitPrice')} placeholder="0,29"/></FormField>
      <FormField label="Doorbelasten"><Toggle checked={!!f.rechargeable} onChange={v=>setF({...f,rechargeable:v})}/></FormField>
      <div style={{alignSelf:'end',textAlign:'right',paddingBottom:12}}>
        <div style={{...label12,fontSize:10}}>Totaal</div><div style={{marginTop:6}}><Amount value={qty*price} size={19} weight={600}/></div></div>
    </div></Modal>;
}

/* ============ PROJECTDETAIL ============ */
function Projectdetail({params}){
  useStore();const p=calc.project(params.id);useNow(1000);
  const [tab,setTab]=React.useState((params&&params.tab)||'Overzicht');
  const [edit,setEdit]=React.useState(false);const [addUren,setAddUren]=React.useState(false);const [addKosten,setAddKosten]=React.useState(false);
  const [editEntry,setEditEntry]=React.useState(null);const [editCost,setEditCost]=React.useState(null);const [more,setMore]=React.useState(false);
  if(!p)return <EmptyState title="Project niet gevonden"/>;
  const c=calc.customer(p.customerId);const at=store.activeTimer;const running=at&&at.projectId===p.id;
  const entries=calc.entriesOf(p.id);const costs=calc.costsOf(p.id);const invs=calc.invoicesOf(p.id);
  const h=calc.hours(p.id);const u=calc.unbilled(p.id);
  const pct=p.budgetHours?Math.round(h/p.budgetHours*100):0;
  return <div>
    <PageHead back={{label:'Projecten',onClick:()=>window.EG_NAV('projecten')}} eyebrow={p.ref} title={p.name}
      sub={<span style={{display:'inline-flex',alignItems:'center',gap:12}}><a onClick={()=>window.EG_NAV('klant',{id:c.id})} style={{cursor:'pointer'}}>{c?c.name:''}</a><Pill kind="project" value={p.status}/></span>}
      actions={<>
        {running?<button onClick={()=>window.EG_STOP()} style={{appearance:'none',cursor:'pointer',border:0,background:'var(--teal-600)',color:'#fff',borderRadius:'var(--radius-sm)',
          padding:'11px 18px',fontFamily:'var(--font-display)',fontSize:14,fontWeight:600,display:'inline-flex',alignItems:'center',gap:10}}>
          <span style={{width:9,height:9,background:'#fff'}}/>Stop · <span style={{fontFamily:'var(--font-mono)',fontVariantNumeric:'tabular-nums'}}>{fmt.clock(timer.elapsed(at))}</span></button>
        :<Button icon="play" onClick={()=>window.EG_START(p.id)}>Start timer</Button>}
        <Button variant="secondary" onClick={()=>setAddUren(true)}>Uren toevoegen</Button>
        <Button variant="secondary" onClick={()=>setAddKosten(true)}>Kosten toevoegen</Button>
        <Button variant="secondary" onClick={()=>window.EG_NAV('factuur-nieuw',{projectId:p.id})}>Factuur voorbereiden</Button>
        <div style={{position:'relative'}}>
          <IconButton icon="more-horizontal" label="Meer" onClick={()=>setMore(!more)}/>
          {more?<div style={{position:'absolute',right:0,top:46,background:'#fff',border:'1px solid var(--border-hairline)',borderRadius:'var(--radius-md)',
            boxShadow:'var(--shadow-overlay)',padding:6,zIndex:20,minWidth:190}}>
            {[['Bewerken',()=>setEdit(true)],['Klant openen',()=>window.EG_NAV('klant',{id:c.id})],['Facturen bekijken',()=>setTab('Facturatie')]].map(([l,fn])=>
              <button key={l} onClick={()=>{setMore(false);fn()}} style={{display:'block',width:'100%',textAlign:'left',appearance:'none',border:0,background:'none',
                padding:'9px 12px',fontSize:13.5,cursor:'pointer',borderRadius:'var(--radius-sm)',fontFamily:'var(--font-body)',color:'var(--text-body)'}}>{l}</button>)}</div>:null}</div></>}/>
    {running?<div style={{display:'flex',alignItems:'center',gap:16,background:'var(--teal-50)',border:'1px solid var(--teal-200)',borderRadius:'var(--radius-md)',
      padding:'14px 20px',marginBottom:22}}>
      <span className="eg-pulse" style={{width:7,height:7,borderRadius:'50%',background:'var(--teal-600)'}}/>
      <span style={{fontFamily:'var(--font-display)',fontSize:13.5,fontWeight:600,color:'var(--teal-800)'}}>Timer actief</span>
      <span style={{fontFamily:'var(--font-mono)',fontSize:16,color:'var(--teal-800)',fontVariantNumeric:'tabular-nums'}}>{fmt.clock(timer.elapsed(at))}</span>
      <span style={{fontSize:13,color:'var(--teal-800)',opacity:.75}}>gestart om {fmt.time(at.startedAt)}</span></div>:null}
    <KpiRow cols={6} style={{marginBottom:28}}>
      <Kpi label="Begroot" value={fmt.h(p.budgetHours)+' uur'}/>
      <Kpi label="Geschreven" value={fmt.h(h)+' uur'}/>
      <Kpi label="Beschikbaar" value={fmt.h(Math.max(0,p.budgetHours-h))+' uur'} tone={h>p.budgetHours?'danger':undefined}/>
      <Kpi label="Nog te factureren" value={fmt.eur0(u.total)} note="Uit Egberink"/>
      <Kpi label="Gefactureerd" value={fmt.eur0(calc.invoicedOf(p.id))} note="Volgens SnelStart"/>
      <Kpi label="Openstaand" value={fmt.eur0(calc.outstandingOf(p.id))} note="Volgens SnelStart"/>
    </KpiRow>
    <Tabs items={['Overzicht','Uren','Kosten','Facturatie','Notities']} value={tab} onChange={setTab} style={{marginBottom:24}}/>
    {tab==='Overzicht'?<div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr',gap:24,alignItems:'start'}}>
      <Card><SectionTitle>Project</SectionTitle>
        <DataRow label="Klant" value={c?c.name:''}/><DataRow label="Contactpersoon" value={p.contact||'—'}/>
        <DataRow label="Status" value={window.EG.projectStatus(p.status).label}/>
        <DataRow label="Facturatietarief" value={fmt.eur(p.rate)+' per uur'}/>
        <DataRow label="Begrote uren" value={fmt.h(p.budgetHours)+' uur'}/>
        <DataRow label="Kilometers" value={p.km+' km'}/></Card>
      <Card><SectionTitle>Uren</SectionTitle>
        <div style={{display:'flex',alignItems:'baseline',gap:8,marginBottom:14}}>
          <span style={{fontFamily:'var(--font-display)',fontSize:30,fontWeight:600,letterSpacing:'-.02em',fontVariantNumeric:'tabular-nums'}}>{fmt.h(h)}</span>
          <span style={{fontSize:14,color:'var(--text-muted)'}}>van {fmt.h(p.budgetHours)} uur</span></div>
        <ProgressBar value={pct} label="Gebruikt"/>
        <div style={{marginTop:18}}>
          <DataRow label="Facturabel" value={fmt.h(entries.filter(e=>e.billable).reduce((a,e)=>a+e.hours,0))+' uur'}/>
          <DataRow label="Niet facturabel" value={fmt.h(entries.filter(e=>!e.billable).reduce((a,e)=>a+e.hours,0))+' uur'}/>
          <DataRow label="Nog beschikbaar" value={fmt.h(Math.max(0,p.budgetHours-h))+' uur'}/></div></Card>
      <Card><SectionTitle right={<Source/>}>Financieel</SectionTitle>
        <DataRow label="Waarde geschreven uren" value={fmt.eur(h*p.rate)} note="Uit Egberink"/>
        <DataRow label="Nog te factureren" value={fmt.eur(u.total)} note="Uit Egberink"/>
        <DataRow label="Gefactureerd" value={fmt.eur(calc.invoicedOf(p.id))}/>
        <DataRow label="Ontvangen" value={fmt.eur(calc.receivedOf(p.id))}/>
        <DataRow label="Openstaand" value={fmt.eur(calc.outstandingOf(p.id))}/></Card></div>:null}
    {tab==='Uren'?<Card padding="0">
      <div style={{padding:'18px 20px',display:'flex',justifyContent:'space-between',alignItems:'center',borderBottom:'1px solid var(--border-hairline)'}}>
        <div style={{fontSize:13.5,color:'var(--text-muted)'}}>{entries.length} registraties · {fmt.h(h)} uur</div>
        <Button variant="secondary" icon="plus" size="sm" onClick={()=>setAddUren(true)} style={{whiteSpace:'nowrap'}}>Handmatig uren toevoegen</Button></div>
      {entries.length?<Table cols={[{label:'Datum'},{label:'Omschrijving'},{label:'Registratie'},{label:'Start'},{label:'Stop'},{label:'Uren',right:true},
        {label:'Tarief',right:true},{label:'Facturabel'},{label:'Factuur'},{label:'',w:80}]}>
        {entries.map(e=><Tr key={e.id}>
          <Td mono>{fmt.date(e.date)}</Td><Td style={{color:'var(--ink-900)'}}>{e.description}</Td>
          <Td><Badge tone={e.source==='timer'?'brand':'neutral'}>{e.source==='timer'?'Timer':'Handmatig'}</Badge></Td>
          <Td mono muted>{e.start||'—'}</Td><Td mono muted>{e.stop||'—'}</Td>
          <Td right><Amount value={e.hours} unit="uur" size={13.5}/></Td>
          <Td right muted><Amount value={p.rate} size={13} tone="muted"/></Td>
          <Td>{e.billable?'Ja':<span style={{color:'var(--text-faint)'}}>Nee</span>}</Td>
          <Td>{e.invoiceId?<a onClick={()=>window.EG_NAV('factuur',{id:e.invoiceId})} style={{cursor:'pointer',fontFamily:'var(--font-mono)',fontSize:12.5}}>{(calc.invoice(e.invoiceId)||{}).number}</a>
            :<span style={{fontSize:12.5,color:'var(--text-faint)'}}>Niet gefactureerd</span>}</Td>
          <Td><div style={{display:'flex',gap:4}}>
            <button onClick={()=>setEditEntry(e)} disabled={!!e.invoiceId} title="Bewerken" style={{appearance:'none',border:0,background:'none',cursor:e.invoiceId?'not-allowed':'pointer',opacity:e.invoiceId?.3:1,padding:4}}><Icon name="pencil" size={14} color="var(--ink-600)"/></button>
            <button onClick={()=>{if(confirm('Urenregel verwijderen?'))store.remove('timeEntries',e.id)}} disabled={!!e.invoiceId} title="Verwijderen" style={{appearance:'none',border:0,background:'none',cursor:e.invoiceId?'not-allowed':'pointer',opacity:e.invoiceId?.3:1,padding:4}}><Icon name="trash-2" size={14} color="var(--ink-600)"/></button></div></Td></Tr>)}
      </Table>:<EmptyState icon="timer" title="Er zijn nog geen uren geregistreerd" action={<Button icon="play" onClick={()=>window.EG_START(p.id)}>Start tijdregistratie</Button>}>
        Start de timer of voeg de uren handmatig toe.</EmptyState>}</Card>:null}
    {tab==='Kosten'?<Card padding="0">
      <div style={{padding:'18px 20px',display:'flex',justifyContent:'space-between',alignItems:'center',borderBottom:'1px solid var(--border-hairline)'}}>
        <div style={{fontSize:13.5,color:'var(--text-muted)'}}>Projectkosten · {fmt.eur(costs.reduce((a,k)=>a+k.qty*k.unitPrice,0))}</div>
        <Button variant="secondary" icon="plus" size="sm" onClick={()=>setAddKosten(true)}>Kosten toevoegen</Button></div>
      {costs.length?<Table cols={[{label:'Datum'},{label:'Kostensoort'},{label:'Omschrijving'},{label:'Aantal',right:true},{label:'Tarief',right:true},
        {label:'Totaal',right:true},{label:'Doorbelasten'},{label:'Factuur'},{label:'',w:60}]}>
        {costs.map(k=><Tr key={k.id}>
          <Td mono>{fmt.date(k.date)}</Td><Td><Badge>{k.type}</Badge></Td><Td style={{color:'var(--ink-900)'}}>{k.description}</Td>
          <Td right mono>{fmt.num(k.qty,k.qty%1?2:0)}</Td><Td right><Amount value={k.unitPrice} size={13} tone="muted"/></Td>
          <Td right><Amount value={k.qty*k.unitPrice} size={13.5}/></Td>
          <Td>{k.rechargeable?'Ja':<span style={{color:'var(--text-faint)'}}>Nee</span>}</Td>
          <Td>{k.invoiceId?<span style={{fontFamily:'var(--font-mono)',fontSize:12.5}}>{(calc.invoice(k.invoiceId)||{}).number}</span>:<span style={{fontSize:12.5,color:'var(--text-faint)'}}>—</span>}</Td>
          <Td><button onClick={()=>setEditCost(k)} disabled={!!k.invoiceId} style={{appearance:'none',border:0,background:'none',cursor:k.invoiceId?'not-allowed':'pointer',opacity:k.invoiceId?.3:1,padding:4}}><Icon name="pencil" size={14} color="var(--ink-600)"/></button></Td></Tr>)}
      </Table>:<EmptyState icon="receipt" title="Nog geen projectkosten" action={<Button variant="secondary" icon="plus" onClick={()=>setAddKosten(true)}>Kosten toevoegen</Button>}/>}</Card>:null}
    {tab==='Facturatie'?<div style={{display:'grid',gridTemplateColumns:'1.4fr 1fr',gap:28,alignItems:'start'}}>
      <Card padding="0">
        <div style={{padding:'18px 20px',borderBottom:'1px solid var(--border-hairline)'}}><SectionTitle style={{marginBottom:0}}>Facturen</SectionTitle></div>
        {invs.length?<Table cols={[{label:'Factuur'},{label:'Datum'},{label:'Bedrag',right:true},{label:'Egberink'},{label:'SnelStart'}]}>
          {invs.map(i=><Tr key={i.id} onClick={()=>window.EG_NAV('factuur',{id:i.id})}>
            <Td mono>{i.number}</Td><Td>{fmt.date(i.date)}</Td>
            <Td right><Amount value={i.snelstart?i.snelstart.total:calc.invoiceTotals(i.lines).total} size={13.5}/></Td>
            <Td><Pill kind="eg" value={i.egStatus}/></Td><Td><Pill kind="ss" value={i.snelstart?i.snelstart.status:'niet_verzonden'}/></Td></Tr>)}
        </Table>:<EmptyState icon="file-text" title="Er zijn nog geen facturen voor dit project"/>}</Card>
      <Card accent><SectionTitle>Nog te factureren</SectionTitle>
        <DataRow label="Niet-gefactureerde uren" value={fmt.h(u.hours)+' uur'}/>
        <DataRow label="Urenbedrag" value={fmt.eur(u.hourValue)}/>
        <DataRow label="Doorbelastbare kosten" value={fmt.eur(u.costs)}/>
        <div style={{display:'flex',justifyContent:'space-between',paddingTop:14,marginTop:4,borderTop:'2px solid var(--ink-900)'}}>
          <span style={{fontFamily:'var(--font-display)',fontSize:14,fontWeight:600}}>Totaal</span><Amount value={u.total} size={16} weight={600}/></div>
        <div style={{marginTop:20}}><Button fullWidth onClick={()=>window.EG_NAV('factuur-nieuw',{projectId:p.id})} disabled={u.total<=0}>Factuur voorbereiden</Button></div></Card></div>:null}
    {tab==='Notities'?<Card>{p.notes||p.description?<div style={{maxWidth:720}}>
      <p style={{fontSize:14.5,lineHeight:1.62,margin:'0 0 16px'}}>{p.description}</p>
      {p.notes?<p style={{fontSize:14.5,lineHeight:1.62,margin:0,color:'var(--text-body)'}}>{p.notes}</p>:null}</div>
      :<EmptyState icon="notebook-pen" title="Geen notities" action={<Button variant="secondary" onClick={()=>setEdit(true)}>Notitie toevoegen</Button>}/>}</Card>:null}
    {edit?<ProjectForm project={p} onClose={()=>setEdit(false)}/>:null}
    {addUren?<EntryForm projectId={p.id} onClose={()=>setAddUren(false)}/>:null}
    {editEntry?<EntryForm entry={editEntry} onClose={()=>setEditEntry(null)}/>:null}
    {addKosten?<CostForm projectId={p.id} onClose={()=>setAddKosten(false)}/>:null}
    {editCost?<CostForm cost={editCost} onClose={()=>setEditCost(null)}/>:null}
  </div>;
}

/* ============ URENPAGINA ============ */
function Uren({params}){
  useStore();useNow(1000);
  const [weekStart,setWeekStart]=React.useState(window.EG.monday(new Date()));
  const [add,setAdd]=React.useState(!!(params&&params.add));const [editEntry,setEditEntry]=React.useState(null);
  const at=store.activeTimer;
  const end=window.EG.addDays(weekStart,6);
  const rows=store.timeEntries.filter(e=>{const d=new Date(e.date);return d>=weekStart&&d<=end}).sort((a,b)=>a.date<b.date?1:a.date>b.date?-1:0);
  const t=calc.totals();
  const wTot=rows.reduce((a,e)=>a+e.hours,0),wBill=rows.filter(e=>e.billable).reduce((a,e)=>a+e.hours,0);
  const shift=(n)=>setWeekStart(window.EG.addDays(weekStart,n*7));
  return <div>
    <PageHead title="Urenregistratie" sub="Registreer tijd met de timer of voeg uren handmatig toe."
      actions={<Button icon="plus" onClick={()=>setAdd(true)} style={{whiteSpace:'nowrap'}}>Handmatig uren toevoegen</Button>}/>
    <div style={{display:'grid',gridTemplateColumns:at?'200px 200px 1fr':'200px 200px',gap:16,marginBottom:28,alignItems:'stretch'}}>
      <Kpi label="Vandaag" value={fmt.h(t.hoursToday)+' uur'} accent/><Kpi label="Deze week" value={fmt.h(t.hoursWeek)+' uur'}/>
      {at?<div style={{display:'flex',alignItems:'center',justifyContent:'space-between',gap:24,padding:'12px 20px',background:'var(--teal-50)',
        border:'1px solid var(--teal-200)',borderRadius:'var(--radius-md)'}}>
        <div style={{display:'flex',alignItems:'center',gap:12,minWidth:0}}>
          <span className="eg-pulse" style={{width:7,height:7,borderRadius:'50%',background:'var(--teal-600)',flex:'none'}}/>
          <div style={{minWidth:0}}><div style={{...label12,fontSize:10,color:'var(--teal-800)'}}>Actieve timer</div>
            <a onClick={()=>window.EG_NAV('project',{id:at.projectId})} style={{cursor:'pointer',fontSize:14,fontWeight:500,display:'block',marginTop:3,color:'var(--teal-900)'}}>
              {calc.project(at.projectId).ref} · {calc.project(at.projectId).name}</a></div></div>
        <div style={{display:'flex',alignItems:'center',gap:16}}>
          <span style={{fontFamily:'var(--font-mono)',fontSize:22,color:'var(--teal-800)',fontVariantNumeric:'tabular-nums'}}>{fmt.clock(timer.elapsed(at))}</span>
          <Button onClick={()=>window.EG_STOP()}>Stop</Button></div></div>:null}</div>
    <Card padding="0">
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',padding:'16px 20px',borderBottom:'1px solid var(--border-hairline)'}}>
        <div style={{display:'flex',alignItems:'center',gap:14}}>
          <IconButton icon="chevron-left" label="Vorige week" onClick={()=>shift(-1)}/>
          <div style={{textAlign:'center',minWidth:280}}>
            <div style={{fontFamily:'var(--font-display)',fontSize:15,fontWeight:600}}>Week {window.EG.weekNo(weekStart)}</div>
            <div style={{fontSize:12.5,color:'var(--text-faint)',marginTop:2}}>{fmt.longDate(window.EG.iso(weekStart))} t/m {fmt.longDate(window.EG.iso(end))}</div></div>
          <IconButton icon="chevron-right" label="Volgende week" onClick={()=>shift(1)}/></div>
        <div style={{display:'flex',gap:28,alignItems:'baseline'}}>
          <div><span style={{...label12,fontSize:10}}>Totaal week</span><div style={{marginTop:4}}><Amount value={wTot} unit="uur" size={16} weight={600}/></div></div>
          <div><span style={{...label12,fontSize:10}}>Facturabel</span><div style={{marginTop:4}}><Amount value={wBill} unit="uur" size={14} tone="muted"/></div></div>
          <div><span style={{...label12,fontSize:10}}>Niet facturabel</span><div style={{marginTop:4}}><Amount value={wTot-wBill} unit="uur" size={14} tone="muted"/></div></div></div></div>
      {rows.length?<Table cols={[{label:'Datum'},{label:'Werknr.'},{label:'Project'},{label:'Klant'},{label:'Omschrijving'},{label:'Van'},{label:'Tot'},
        {label:'Uren',right:true},{label:'Facturabel'},{label:'',w:80}]}>
        {rows.map(e=>{const p=calc.project(e.projectId);const c=p?calc.customer(p.customerId):null;
          return <Tr key={e.id}>
            <Td mono>{fmt.date(e.date)}</Td><Td mono muted>{p?p.ref:'—'}</Td>
            <Td onClick={()=>p&&window.EG_NAV('project',{id:p.id})} style={{color:'var(--ink-900)',fontWeight:500,cursor:'pointer'}}>{p?p.name:'—'}</Td>
            <Td muted>{c?c.name:'—'}</Td>
            <Td>{e.description}{e.source==='timer'?<Badge tone="brand" style={{marginLeft:8,height:19,fontSize:10}}>Timer</Badge>:null}</Td>
            <Td mono muted>{e.start||'—'}</Td><Td mono muted>{e.stop||'—'}</Td>
            <Td right><Amount value={e.hours} unit="uur" size={13.5}/></Td>
            <Td>{e.billable?'Ja':<span style={{color:'var(--text-faint)'}}>Nee</span>}</Td>
            <Td><div style={{display:'flex',gap:4}}>
              <button onClick={()=>setEditEntry(e)} disabled={!!e.invoiceId} style={{appearance:'none',border:0,background:'none',cursor:e.invoiceId?'not-allowed':'pointer',opacity:e.invoiceId?.3:1,padding:4}}><Icon name="pencil" size={14} color="var(--ink-600)"/></button>
              <button onClick={()=>{if(confirm('Urenregel verwijderen?'))store.remove('timeEntries',e.id)}} disabled={!!e.invoiceId} style={{appearance:'none',border:0,background:'none',cursor:e.invoiceId?'not-allowed':'pointer',opacity:e.invoiceId?.3:1,padding:4}}><Icon name="trash-2" size={14} color="var(--ink-600)"/></button></div></Td></Tr>})}
      </Table>:<EmptyState icon="calendar-days" title="Geen uren in deze week" action={<Button variant="secondary" icon="plus" onClick={()=>setAdd(true)}>Handmatig uren toevoegen</Button>}>
        Navigeer naar een andere week of voeg een registratie toe.</EmptyState>}</Card>
    {add?<EntryForm onClose={()=>setAdd(false)}/>:null}
    {editEntry?<EntryForm entry={editEntry} onClose={()=>setEditEntry(null)}/>:null}</div>;
}
Object.assign(window,{ProjectForm,Projecten,Projectdetail,Uren,EntryForm,CostForm,StopTimerModal,ConflictModal});
