// ============================================================
//  TimeTrack – app.jsx
//  Zmartwebbreklam – tid.zmartwebbreklam.se
// ============================================================

const { useState, useEffect, useCallback } = React;

// ─── Konfig ───────────────────────────────────────────────────────────────────
const API = '/api.php';

// ─── Team ─────────────────────────────────────────────────────────────────────
const TEAM = ["Fredrik", "Pelle", "Frida", "Buskenström", "Niklas E", "Linn", "Adam"];

// ─── Helpers ──────────────────────────────────────────────────────────────────
const fmtSEK  = n => new Intl.NumberFormat("sv-SE",{style:"currency",currency:"SEK",maximumFractionDigits:0}).format(n);
const fmtDate = d => d ? new Date(d).toLocaleDateString("sv-SE") : "–";
const hoursFor = (entries, pid) => entries.filter(e=>e.project_id===pid).reduce((s,e)=>s+Number(e.hours),0);
const daysLeft  = d => d ? Math.ceil((new Date(d)-new Date())/86400000) : null;
const PALETTE   = ["#B45309","#065F46","#1D4ED8","#7C3AED","#BE185D","#0F766E","#B91C1C","#1E40AF"];

// ─── Token-hantering ──────────────────────────────────────────────────────────
function getToken() { return localStorage.getItem('tt_token') || ''; }
function setToken(user, pass) { localStorage.setItem('tt_token', btoa(user + ':' + pass)); }
function clearToken() { localStorage.removeItem('tt_token'); }

// ─── API-anrop ────────────────────────────────────────────────────────────────
async function apiFetch(resource, method="GET", body=null) {
  const opts = {
    method,
    headers: { "Content-Type": "application/json", "X-Auth-Token": getToken() }
  };
  if (body) opts.body = JSON.stringify(body);
  const r = await fetch(`${API}/${resource}`, opts);
  if (r.status === 401) { clearToken(); throw new Error('__LOGOUT__'); }
  if (!r.ok) { const e = await r.json().catch(()=>({error:r.statusText})); throw new Error(e.error||r.statusText); }
  return r.json();
}

// ─── Inloggningsskärm ─────────────────────────────────────────────────────────
function LoginScreen({ onLogin }) {
  const [user, setUser]     = useState('');
  const [pass, setPass]     = useState('');
  const [error, setError]   = useState('');
  const [loading, setLoading] = useState(false);

  const attempt = async () => {
    if (!user || !pass) return;
    setLoading(true); setError('');
    setToken(user, pass);
    try {
      await apiFetch('clients');
      onLogin();
    } catch(e) {
      clearToken();
      setError('Fel användarnamn eller lösenord');
    } finally { setLoading(false); }
  };

  const onKey = e => { if (e.key === 'Enter') attempt(); };

  return (
    <div style={{display:'flex',height:'100vh',background:'#111827',alignItems:'center',justifyContent:'center'}}>
      <div style={{background:'#1F2937',borderRadius:16,padding:'40px 48px',width:340,boxShadow:'0 20px 60px rgba(0,0,0,.4)'}}>
        <div style={{textAlign:'center',marginBottom:32}}>
          <div style={{fontSize:48,fontWeight:800,color:'#F59E0B',letterSpacing:-2}}>T/</div>
          <div style={{color:'#9CA3AF',fontSize:14,marginTop:4}}>Zmartwebbreklam TimeTrack</div>
        </div>
        <div style={{marginBottom:16}}>
          <label style={{display:'block',fontSize:12,fontWeight:600,color:'#9CA3AF',marginBottom:6,textTransform:'uppercase',letterSpacing:'0.05em'}}>Användarnamn</label>
          <input
            style={{width:'100%',padding:'10px 14px',background:'#374151',border:'1px solid #4B5563',borderRadius:8,color:'#F9FAFB',fontSize:14,outline:'none',boxSizing:'border-box'}}
            value={user} onChange={e=>setUser(e.target.value)} onKeyDown={onKey}
            placeholder='användarnamn' autoFocus autoComplete='username'
          />
        </div>
        <div style={{marginBottom:24}}>
          <label style={{display:'block',fontSize:12,fontWeight:600,color:'#9CA3AF',marginBottom:6,textTransform:'uppercase',letterSpacing:'0.05em'}}>Lösenord</label>
          <input
            type='password'
            style={{width:'100%',padding:'10px 14px',background:'#374151',border:'1px solid #4B5563',borderRadius:8,color:'#F9FAFB',fontSize:14,outline:'none',boxSizing:'border-box'}}
            value={pass} onChange={e=>setPass(e.target.value)} onKeyDown={onKey}
            placeholder='••••••••' autoComplete='current-password'
          />
        </div>
        {error && <div style={{background:'#7F1D1D',color:'#FCA5A5',borderRadius:8,padding:'8px 12px',fontSize:13,marginBottom:16,textAlign:'center'}}>{error}</div>}
        <button
          style={{width:'100%',background:'#F59E0B',color:'#111',border:'none',borderRadius:8,padding:'11px',fontSize:15,fontWeight:700,cursor:'pointer'}}
          onClick={attempt} disabled={loading}
        >{loading ? 'Loggar in…' : 'Logga in'}</button>
      </div>
    </div>
  );
}

// ══════════════════════════════════════════════════════════════════════════════
function App() {
  const [loggedIn,    setLoggedIn]    = useState(() => !!getToken());
  const [view,        setView]        = useState("dashboard");
  const [clients,     setClients]     = useState([]);
  const [projects,    setProjects]    = useState([]);
  const [entries,     setEntries]     = useState([]);
  const [loading,     setLoading]     = useState(true);
  const [error,       setError]       = useState(null);
  const [currentUser, setCurrentUser] = useState(() => localStorage.getItem("tt_user")||TEAM[0]);

  if (!loggedIn) return <LoginScreen onLogin={() => setLoggedIn(true)} />;

  const [showNewClient,  setShowNewClient]  = useState(false);
  const [showNewProject, setShowNewProject] = useState(false);
  const [showNewEntry,   setShowNewEntry]   = useState(false);
  const [editProject,    setEditProject]    = useState(null);
  const [detailProject,  setDetailProject]  = useState(null);

  // ── Ladda all data från API ──
  const loadAll = useCallback(async () => {
    try {
      setLoading(true); setError(null);
      const [c, p, e] = await Promise.all([
        apiFetch('clients'),
        apiFetch('projects'),
        apiFetch('entries'),
      ]);
      setClients(c); setProjects(p); setEntries(e);
    } catch(err) {
      if (err.message === '__LOGOUT__') { clearToken(); setLoggedIn(false); return; }
      setError("Kunde inte ansluta till servern: " + err.message);
    } finally { setLoading(false); }
  }, []);

  useEffect(() => { loadAll(); }, [loadAll]);
  useEffect(() => { localStorage.setItem("tt_user", currentUser); }, [currentUser]);

  // ── CRUD helpers ──
  const addClient = async (data) => {
    await apiFetch('clients','POST', data);
    await loadAll();
    setShowNewClient(false);
  };

  const addProject = async (data) => {
    await apiFetch('projects','POST', data);
    await loadAll();
    setShowNewProject(false);
  };

  const updateProject = async (id, data) => {
    await apiFetch(`projects/${id}`,'PUT', data);
    await loadAll();
    setEditProject(null);
  };

  const addEntry = async (data) => {
    await apiFetch('entries','POST', data);
    await loadAll();
    setShowNewEntry(false);
  };

  const deleteEntry = async (id) => {
    await apiFetch(`entries/${id}`,'DELETE');
    await loadAll();
  };

  const updateEntry = async (id, data) => {
    await apiFetch(`entries/${id}`,'PUT', data);
    await loadAll();
  };

  const deleteProject = async (id) => {
    await apiFetch(`projects/${id}`,'DELETE');
    setDetailProject(null);
    await loadAll();
  };

  const deleteClient = async (id) => {
    await apiFetch(`clients/${id}`,'DELETE');
    await loadAll();
  };

  const toggleInvoiced = async (projectId) => {
    const updated = await apiFetch('toggle-invoiced','POST',{id:projectId});
    setProjects(prev => prev.map(p => p.id===projectId ? {...p,...updated} : p));
    setDetailProject(prev => prev?.id===projectId ? {...prev,...updated} : prev);
  };

  // ── KPI ──
  const totalValue    = projects.reduce((s,p)=>s+Number(p.value||0),0);
  const invoicedValue = projects.filter(p=>p.invoiced).reduce((s,p)=>s+Number(p.value||0),0);
  const totalHours    = entries.reduce((s,e)=>s+Number(e.hours),0);

  if (loading) return (
    <div style={{display:"flex",height:"100vh",alignItems:"center",justifyContent:"center",background:"#111827",flexDirection:"column",gap:16}}>
      <div style={{fontSize:48,fontWeight:800,color:"#F59E0B",letterSpacing:-2}}>T/</div>
      <div style={{color:"#6B7280",fontSize:14}}>Ansluter till databasen…</div>
    </div>
  );

  if (error) return (
    <div style={{display:"flex",height:"100vh",alignItems:"center",justifyContent:"center",background:"#FEF2F2",flexDirection:"column",gap:12,padding:32}}>
      <div style={{fontSize:32}}>⚠️</div>
      <div style={{fontWeight:700,color:"#991B1B",fontSize:18}}>Anslutningsfel</div>
      <div style={{color:"#7F1D1D",maxWidth:400,textAlign:"center",fontSize:14}}>{error}</div>
      <button style={{...S.btnPrimary,background:"#B91C1C",marginTop:8}} onClick={loadAll}>Försök igen</button>
    </div>
  );

  return (
    <div style={S.root}>
      {/* ── Sidebar ── */}
      <aside style={S.sidebar}>
        <div style={S.logo}><span style={S.logoMark}>T/</span><span style={S.logoText}>TimeTrack</span></div>
        <div style={S.userPicker}>
          <div style={S.userLabel}>Inloggad som</div>
          <select value={currentUser} onChange={e=>setCurrentUser(e.target.value)} style={S.userSelect}>
            {TEAM.map(t=><option key={t}>{t}</option>)}
          </select>
        </div>
        <nav style={S.nav}>
          {[
            {id:"dashboard",label:"Översikt",      icon:"◈"},
            {id:"report",   label:"Rapportera tid", icon:"⊕"},
            {id:"projects", label:"Projekt",        icon:"◻"},
            {id:"clients",  label:"Kunder",         icon:"◎"},
            {id:"log",      label:"Tidlogg",        icon:"≡"},
            {id:"reports",  label:"Rapporter",       icon:"▤"},
          ].map(item=>(
            <button key={item.id} style={{...S.navItem,...(view===item.id?S.navItemActive:{})}} onClick={()=>setView(item.id)}>
              <span style={S.navIcon}>{item.icon}</span>{item.label}
            </button>
          ))}
        </nav>
        <div style={S.sidebarBottom}>
          <button style={S.quickBtn}        onClick={()=>setShowNewEntry(true)}>+ Ny tidspost</button>
          <button style={S.quickBtnOutline} onClick={()=>setShowNewProject(true)}>+ Nytt projekt</button>
          <button style={S.refreshBtn}      onClick={loadAll}>↻ Uppdatera</button>
          <button style={S.logoutBtn} onClick={()=>{ clearToken(); setLoggedIn(false); }}>Logga ut</button>
        </div>
      </aside>

      {/* ── Main ── */}
      <main style={S.main}>
        {view==="dashboard" && <Dashboard clients={clients} projects={projects} entries={entries}
          totalHours={totalHours} totalValue={totalValue} invoicedValue={invoicedValue}
          currentUser={currentUser} onOpenProject={setDetailProject} onToggleInvoiced={toggleInvoiced}/>}
        {view==="report"    && <ReportView clients={clients} projects={projects} entries={entries}
          currentUser={currentUser} onAdd={addEntry} onUpdate={updateEntry} onDelete={deleteEntry}/>}
        {view==="projects"  && <ProjectsView clients={clients} projects={projects} entries={entries}
          onNew={()=>setShowNewProject(true)} onEdit={setEditProject}
          onDetail={setDetailProject} onToggleInvoiced={toggleInvoiced} onDelete={deleteProject}/>}
        {view==="clients"   && <ClientsView clients={clients} projects={projects} entries={entries}
          onNew={()=>setShowNewClient(true)} onDelete={deleteClient}/>}
        {view==="log"       && <LogView clients={clients} projects={projects} entries={entries}
          onDelete={deleteEntry} onUpdate={updateEntry}/>}
        {view==="reports"   && <ReportsView clients={clients} projects={projects} entries={entries} onToggleInvoiced={toggleInvoiced}/>}
      </main>

      {showNewClient  && <NewClientModal  onClose={()=>setShowNewClient(false)}  onSave={addClient}/>}
      {showNewProject && <NewProjectModal clients={clients} project={null}
        onClose={()=>setShowNewProject(false)} onSave={addProject}/>}
      {editProject    && <NewProjectModal clients={clients} project={editProject}
        onClose={()=>setEditProject(null)}
        onSave={data=>updateProject(editProject.id, data)}/>}
      {showNewEntry   && <NewEntryModal   clients={clients} projects={projects} currentUser={currentUser}
        onClose={()=>setShowNewEntry(false)} onSave={addEntry}/>}
      {detailProject  && <ProjectDetailModal
        project={detailProject}
        client={clients.find(c=>c.id===detailProject.client_id)}
        entries={entries.filter(e=>e.project_id===detailProject.id)}
        onClose={()=>setDetailProject(null)}
        onToggleInvoiced={toggleInvoiced}
        onDelete={deleteProject}
        onEdit={p=>{setDetailProject(null);setEditProject(p);}}/>}
    </div>
  );
}

// ── Dashboard ─────────────────────────────────────────────────────────────────
function Dashboard({clients,projects,entries,totalHours,totalValue,invoicedValue,currentUser,onOpenProject,onToggleInvoiced}) {
  const myHours = entries.filter(e=>e.person===currentUser).reduce((s,e)=>s+Number(e.hours),0);
  const recent  = [...projects].sort((a,b)=>new Date(b.created_at)-new Date(a.created_at)).slice(0,6);

  return (
    <div style={S.page}>
      <div style={S.pageHeader}>
        <div>
          <h1 style={S.h1}>Välkommen, {currentUser} 👋</h1>
          <p style={S.subtitle}>{new Date().toLocaleDateString("sv-SE",{weekday:"long",year:"numeric",month:"long",day:"numeric"})}</p>
        </div>
      </div>
      <div style={S.kpiRow}>
        <KpiCard label="Totalt offererat"  value={fmtSEK(totalValue)}               sub={`${projects.length} projekt`}                           accent="#B45309"/>
        <KpiCard label="Fakturerat"        value={fmtSEK(invoicedValue)}             sub={`${projects.filter(p=>p.invoiced).length} fakturerade`}  accent="#065F46"/>
        <KpiCard label="Ej fakturerat"     value={fmtSEK(totalValue-invoicedValue)}  sub={`${projects.filter(p=>!p.invoiced).length} projekt`}     accent="#7C3AED"/>
        <KpiCard label="Mina timmar"       value={`${myHours} h`}                   sub={`Totalt ${totalHours} h`}                               accent="#1D4ED8"/>
      </div>
      <h2 style={S.h2}>Senaste projekt</h2>
      <div style={S.projectGrid}>
        {recent.map(p=>{
          const cl=clients.find(c=>c.id===p.client_id);
          const spent=hoursFor(entries,p.id);
          const pct=p.estimated_hours?Math.min(100,Math.round(spent/p.estimated_hours*100)):0;
          const days=daysLeft(p.deadline);
          return (
            <div key={p.id} style={{...S.projectCard,opacity:p.invoiced?0.75:1}} onClick={()=>onOpenProject(p)}>
              <div style={{...S.projectCardAccent,background:p.invoiced?"#9CA3AF":(cl?.color||"#999")}}/>
              <div style={S.projectCardInner}>
                <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:8,gap:6}}>
                  <span style={{...S.clientBadge,background:(cl?.color||"#999")+"22",color:cl?.color||"#999",marginBottom:0}}>{cl?.name||"Okänd"}</span>
                  {p.invoiced
                    ? <span style={S.invoicedBadge}>✓ Fakturerad</span>
                    : <button style={S.invoiceBtn} onClick={e=>{e.stopPropagation();onToggleInvoiced(p.id);}}>Fakturera</button>}
                </div>
                <div style={S.projectName}>{p.name}</div>
                <div style={S.projectValue}>{fmtSEK(p.value||0)}</div>
                <div style={S.progressWrap}>
                  <div style={S.progressBg}><div style={{...S.progressFill,width:pct+"%",background:pct>90?"#DC2626":(cl?.color||"#1D4ED8")}}/></div>
                  <span style={S.progressLabel}>{spent}h / {p.estimated_hours||"?"}h</span>
                </div>
                {days!==null&&<div style={{...S.deadlineBadge,color:days<0?"#DC2626":days<7?"#D97706":"#9CA3AF"}}>
                  {days<0?`Försenad ${Math.abs(days)} dagar`:days===0?"Deadline idag!":`${days} dagar kvar`}
                </div>}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function KpiCard({label,value,sub,accent}) {
  return <div style={{...S.kpiCard,borderTopColor:accent}}>
    <div style={{...S.kpiValue,color:accent}}>{value}</div>
    <div style={S.kpiLabel}>{label}</div>
    <div style={S.kpiSub}>{sub}</div>
  </div>;
}

// ── Report ────────────────────────────────────────────────────────────────────
function ReportView({clients,projects,entries,currentUser,onAdd}) {
  const [form,setForm]=useState({client_id:"",project_id:"",hours:"",date:new Date().toISOString().slice(0,10),note:"",person:currentUser});
  const [saving,setSaving]=useState(false);
  const [saved,setSaved]=useState(false);
  useEffect(()=>setForm(f=>({...f,person:currentUser})),[currentUser]);

  const fp = form.client_id ? projects.filter(p=>p.client_id===form.client_id) : projects;

  const submit = async () => {
    if (!form.project_id||!form.hours||!form.date) return;
    setSaving(true);
    await onAdd({project_id:form.project_id,person:form.person,hours:Number(form.hours),date:form.date,note:form.note});
    setForm(f=>({...f,project_id:"",hours:"",note:""}));
    setSaving(false); setSaved(true); setTimeout(()=>setSaved(false),2500);
  };

  return (
    <div style={S.page}>
      <div style={S.pageHeader}><h1 style={S.h1}>Rapportera tid</h1></div>
      <div style={S.formCard}>
        <div style={S.formGrid}>
          <Fg label="Medarbetare">
            <select style={S.input} value={form.person} onChange={e=>setForm(f=>({...f,person:e.target.value}))}>
              {TEAM.map(t=><option key={t}>{t}</option>)}
            </select>
          </Fg>
          <Fg label="Datum">
            <input type="date" style={S.input} value={form.date} onChange={e=>setForm(f=>({...f,date:e.target.value}))}/>
          </Fg>
          <Fg label="Kund (filter)">
            <select style={S.input} value={form.client_id} onChange={e=>setForm(f=>({...f,client_id:e.target.value,project_id:""}))}>
              <option value="">Alla kunder</option>
              {clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </Fg>
          <Fg label="Projekt *">
            <select style={S.input} value={form.project_id} onChange={e=>setForm(f=>({...f,project_id:e.target.value}))}>
              <option value="">Välj projekt…</option>
              {fp.map(p=>{const c=clients.find(cl=>cl.id===p.client_id);return <option key={p.id} value={p.id}>{c?`${c.name} — `:""}{p.name}{p.invoiced?" ✓":""}</option>;})}
            </select>
          </Fg>
          <Fg label="Timmar *">
            <input type="number" min="0.5" step="0.5" max="24" style={S.input} value={form.hours} onChange={e=>setForm(f=>({...f,hours:e.target.value}))} placeholder="0.0"/>
          </Fg>
          <Fg label="Notat" full>
            <input style={S.input} value={form.note} onChange={e=>setForm(f=>({...f,note:e.target.value}))} placeholder="Vad arbetade du med?"/>
          </Fg>
        </div>
        <div style={{display:"flex",gap:12,alignItems:"center",marginTop:8}}>
          <button style={S.btnPrimary} onClick={submit} disabled={saving}>{saving?"Sparar…":"Spara tidspost"}</button>
          {saved&&<span style={S.savedMsg}>✓ Sparad!</span>}
        </div>
      </div>
      <h2 style={S.h2}>Mina senaste poster</h2>
      <div style={S.tableWrap}>
        <table style={S.table}>
          <thead><tr>{["Datum","Projekt","Kund","Timmar","Notat"].map(h=><th key={h} style={S.th}>{h}</th>)}</tr></thead>
          <tbody>
            {entries.filter(e=>e.person===currentUser).slice(0,15).map(e=>{
              const proj=projects.find(p=>p.id===e.project_id);
              const cl=proj?clients.find(c=>c.id===proj.client_id):null;
              return <tr key={e.id} style={S.tr}>
                <td style={S.td}>{fmtDate(e.date)}</td>
                <td style={S.td}>{proj?.name||"–"}</td>
                <td style={S.td}>{cl&&<span style={{...S.clientBadge,background:cl.color+"22",color:cl.color}}>{cl.name}</span>}</td>
                <td style={{...S.td,fontWeight:600}}>{e.hours} h</td>
                <td style={{...S.td,color:"#6B7280"}}>{e.note||"–"}</td>
              </tr>;
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ── Projects ──────────────────────────────────────────────────────────────────
function ProjectsView({clients,projects,entries,onNew,onEdit,onDetail,onToggleInvoiced,onDelete}) {
  const [fc,setFc]=useState(""); const [fi,setFi]=useState("all"); const [search,setSearch]=useState("");
  const [confirmDelete,setConfirmDelete]=useState(null);
  const filtered=projects.filter(p=>{
    if(fc&&p.client_id!==fc)return false;
    if(fi==="invoiced"&&!p.invoiced)return false;
    if(fi==="not_invoiced"&&p.invoiced)return false;
    if(search&&!p.name.toLowerCase().includes(search.toLowerCase()))return false;
    return true;
  });
  return (
    <div style={S.page}>
      <div style={S.pageHeader}><h1 style={S.h1}>Projekt</h1><button style={S.btnPrimary} onClick={onNew}>+ Nytt projekt</button></div>
      <div style={{display:"flex",gap:12,marginBottom:24,flexWrap:"wrap"}}>
        <input style={{...S.input,maxWidth:240}} placeholder="Sök…" value={search} onChange={e=>setSearch(e.target.value)}/>
        <select style={{...S.input,maxWidth:200}} value={fc} onChange={e=>setFc(e.target.value)}>
          <option value="">Alla kunder</option>{clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
        <select style={{...S.input,maxWidth:180}} value={fi} onChange={e=>setFi(e.target.value)}>
          <option value="all">Alla status</option>
          <option value="not_invoiced">Ej fakturerade</option>
          <option value="invoiced">Fakturerade</option>
        </select>
      </div>
      <div style={S.tableWrap}>
        <table style={S.table}>
          <thead><tr>{["Projekt","Kund","Offererat","Timmar","Deadline","Faktura","",""].map(h=><th key={h} style={S.th}>{h}</th>)}</tr></thead>
          <tbody>
            {filtered.map(p=>{
              const cl=clients.find(c=>c.id===p.client_id);
              const spent=hoursFor(entries,p.id);
              const pct=p.estimated_hours?Math.min(100,Math.round(spent/p.estimated_hours*100)):null;
              const days=daysLeft(p.deadline);
              return <tr key={p.id} style={{...S.tr,cursor:"pointer",opacity:p.invoiced?0.72:1}} onClick={()=>onDetail(p)}>
                <td style={S.td}>
                  <div style={{fontWeight:600}}>{p.name}</div>
                  {p.description&&<div style={{fontSize:12,color:"#9CA3AF",marginTop:2}}>{p.description.slice(0,50)}{p.description.length>50?"…":""}</div>}
                </td>
                <td style={S.td}>{cl&&<span style={{...S.clientBadge,background:cl.color+"22",color:cl.color}}>{cl.name}</span>}</td>
                <td style={S.td}>{fmtSEK(p.value||0)}</td>
                <td style={S.td}>
                  <span style={{fontWeight:600}}>{spent} h {p.estimated_hours?`/ ${p.estimated_hours}h`:""}</span>
                  {pct!==null&&<div style={{...S.progressBg,marginTop:4}}><div style={{...S.progressFill,width:pct+"%",background:pct>90?"#DC2626":(cl?.color||"#1D4ED8")}}/></div>}
                </td>
                <td style={S.td}><span style={{color:days!==null&&days<0?"#DC2626":days!==null&&days<7?"#D97706":"#374151"}}>{fmtDate(p.deadline)}</span></td>
                <td style={S.td} onClick={e=>e.stopPropagation()}>
                  {p.invoiced
                    ?<div><span style={S.invoicedBadge}>✓ Fakturerad</span><div style={{fontSize:11,color:"#9CA3AF",marginTop:2}}>{fmtDate(p.invoiced_at)}</div><button style={{...S.uninvoiceBtn,marginTop:4}} onClick={()=>onToggleInvoiced(p.id)}>Ångra</button></div>
                    :<button style={S.invoiceBtnTable} onClick={()=>onToggleInvoiced(p.id)}>Markera fakturerad</button>}
                </td>
                <td style={S.td} onClick={e=>e.stopPropagation()}><button style={S.editBtn} onClick={()=>onEdit(p)}>✎</button></td>
                <td style={S.td} onClick={e=>e.stopPropagation()}><button style={S.deleteBtn} onClick={()=>setConfirmDelete(p)} title="Radera projekt">🗑</button></td>
              </tr>;
            })}
          </tbody>
        </table>
      </div>
      {confirmDelete && <ConfirmModal
        title="Radera projekt"
        message={`Är du säker på att du vill radera "${confirmDelete.name}"? All rapporterad tid på projektet raderas också.`}
        onConfirm={()=>{ onDelete(confirmDelete.id); setConfirmDelete(null); }}
        onCancel={()=>setConfirmDelete(null)}
      />}
    </div>
  );
}

// ── Clients ───────────────────────────────────────────────────────────────────
function ClientsView({clients,projects,entries,onNew,onDelete}) {
  const [confirmDelete,setConfirmDelete]=useState(null);
  return (
    <div style={S.page}>
      <div style={S.pageHeader}><h1 style={S.h1}>Kunder</h1><button style={S.btnPrimary} onClick={onNew}>+ Ny kund</button></div>
      <div style={S.clientGrid}>
        {clients.map(c=>{
          const cp=projects.filter(p=>p.client_id===c.id);
          const ch=cp.reduce((s,p)=>s+hoursFor(entries,p.id),0);
          const cv=cp.reduce((s,p)=>s+Number(p.value||0),0);
          return <div key={c.id} style={S.clientCard}>
            <div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:12}}>
              <div style={{...S.clientDot,background:c.color,marginBottom:0}}/>
              <button style={S.deleteBtnRed} onClick={()=>setConfirmDelete(c)} title="Radera kund">🗑</button>
            </div>
            <div style={S.clientName}>{c.name}</div>
            <div style={S.clientStats}>
              <div style={S.clientStat}><span style={S.clientStatVal}>{cp.length}</span><span style={S.clientStatLbl}>projekt</span></div>
              <div style={S.clientStat}><span style={S.clientStatVal}>{ch}h</span><span style={S.clientStatLbl}>timmar</span></div>
              <div style={S.clientStat}><span style={{...S.clientStatVal,color:c.color}}>{fmtSEK(cv)}</span><span style={S.clientStatLbl}>offererat</span></div>
            </div>
            <div style={S.clientProjectList}>
              {cp.map(p=><div key={p.id} style={S.clientProjectItem}>
                <span style={{width:6,height:6,borderRadius:"50%",background:p.invoiced?"#9CA3AF":c.color,flexShrink:0}}/>
                <span style={{color:p.invoiced?"#9CA3AF":"#4B5563",flex:1}}>{p.name}</span>
                {p.invoiced&&<span style={{...S.invoicedBadge,fontSize:10,padding:"1px 7px"}}>✓</span>}
              </div>)}
            </div>
          </div>;
        })}
      </div>
      {confirmDelete && <ConfirmModal
        title="Radera kund"
        message={`Är du säker på att du vill radera kunden "${confirmDelete.name}"? Alla tillhörande projekt och tidposter raderas också.`}
        onConfirm={()=>{ onDelete(confirmDelete.id); setConfirmDelete(null); }}
        onCancel={()=>setConfirmDelete(null)}
      />}
    </div>
  );
}

// ── Log ───────────────────────────────────────────────────────────────────────
function LogView({clients,projects,entries,onDelete,onUpdate}) {
  const [fp,setFp]=useState(""); const [fc,setFc]=useState(""); const [fpr,setFpr]=useState("");
  const [editEntry,setEditEntry]=useState(null);
  const fProjects=fc?projects.filter(p=>p.client_id===fc):projects;
  const filtered=[...entries].sort((a,b)=>new Date(b.date)-new Date(a.date)).filter(e=>{
    if(fp&&e.person!==fp)return false;
    if(fpr&&e.project_id!==fpr)return false;
    if(fc){const p=projects.find(p=>p.id===e.project_id);if(!p||p.client_id!==fc)return false;}
    return true;
  });
  const total=filtered.reduce((s,e)=>s+Number(e.hours),0);
  return (
    <div style={S.page}>
      <div style={S.pageHeader}>
        <h1 style={S.h1}>Tidlogg</h1>
        <div style={{...S.kpiCard,borderTopColor:"#B45309",padding:"8px 20px",minWidth:0}}>
          <span style={{...S.kpiValue,color:"#B45309",fontSize:22}}>{total} h</span>
          <span style={S.kpiSub}>{filtered.length} poster</span>
        </div>
      </div>
      <div style={{display:"flex",gap:12,flexWrap:"wrap",marginBottom:24}}>
        <select style={{...S.input,maxWidth:180}} value={fp} onChange={e=>setFp(e.target.value)}>
          <option value="">Alla medarbetare</option>{TEAM.map(t=><option key={t}>{t}</option>)}
        </select>
        <select style={{...S.input,maxWidth:180}} value={fc} onChange={e=>{setFc(e.target.value);setFpr("");}}>
          <option value="">Alla kunder</option>{clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
        <select style={{...S.input,maxWidth:200}} value={fpr} onChange={e=>setFpr(e.target.value)}>
          <option value="">Alla projekt</option>{fProjects.map(p=><option key={p.id} value={p.id}>{p.name}</option>)}
        </select>
      </div>
      <div style={S.tableWrap}>
        <table style={S.table}>
          <thead><tr>{["Datum","Medarbetare","Projekt","Kund","Timmar","Notat","",""].map(h=><th key={h} style={S.th}>{h}</th>)}</tr></thead>
          <tbody>
            {filtered.map(e=>{
              const proj=projects.find(p=>p.id===e.project_id);
              const cl=proj?clients.find(c=>c.id===proj.client_id):null;
              return <tr key={e.id} style={S.tr}>
                <td style={S.td}>{fmtDate(e.date)}</td>
                <td style={S.td}>{e.person}</td>
                <td style={S.td}>{proj?.name||"–"}{proj?.invoiced&&<span style={{...S.invoicedBadge,marginLeft:6,fontSize:10,padding:"1px 7px"}}>✓</span>}</td>
                <td style={S.td}>{cl&&<span style={{...S.clientBadge,background:cl.color+"22",color:cl.color}}>{cl.name}</span>}</td>
                <td style={{...S.td,fontWeight:600}}>{e.hours} h</td>
                <td style={{...S.td,color:"#6B7280"}}>{e.note||"–"}</td>
                <td style={S.td}><button style={S.editBtn} onClick={()=>setEditEntry(e)} title="Redigera">✎</button></td>
                <td style={S.td}><button style={S.deleteBtn} onClick={()=>onDelete(e.id)} title="Radera">✕</button></td>
              </tr>;
            })}
          </tbody>
        </table>
      </div>
      {editEntry && <EditEntryModal
        entry={editEntry}
        clients={clients}
        projects={projects}
        onClose={()=>setEditEntry(null)}
        onSave={async(data)=>{ await onUpdate(editEntry.id, data); setEditEntry(null); }}
      />}
    </div>
  );
}

// ── Modals ────────────────────────────────────────────────────────────────────
function Modal({title,onClose,children,wide}) {
  return <div style={S.overlay}>
    <div style={{...S.modal,...(wide?{maxWidth:680}:{})}}>
      <div style={S.modalHeader}><h2 style={S.modalTitle}>{title}</h2><button style={S.closeBtn} onClick={onClose}>✕</button></div>
      {children}
    </div>
  </div>;
}
function Fg({label,children,full}) {
  return <div style={{...S.formGroup,...(full?{gridColumn:"1 / -1"}:{})}}><label style={S.label}>{label}</label>{children}</div>;
}

function NewClientModal({onClose,onSave}) {
  const [name,setName]=useState("");
  const [color,setColor]=useState(PALETTE[Math.floor(Math.random()*PALETTE.length)]);
  const [saving,setSaving]=useState(false);
  return <Modal title="Ny kund" onClose={onClose}>
    <Fg label="Kundnamn *"><input style={S.input} value={name} onChange={e=>setName(e.target.value)} placeholder="Företagsnamn…" autoFocus/></Fg>
    <Fg label="Färg"><div style={{display:"flex",gap:8}}>{PALETTE.map(c=><div key={c} onClick={()=>setColor(c)} style={{width:28,height:28,borderRadius:"50%",background:c,cursor:"pointer",outline:color===c?"3px solid #111":"none",outlineOffset:2}}/>)}</div></Fg>
    <div style={{display:"flex",gap:12,marginTop:20}}>
      <button style={S.btnPrimary} disabled={saving} onClick={async()=>{if(!name)return;setSaving(true);await onSave({name,color});}}>{saving?"Sparar…":"Spara kund"}</button>
      <button style={S.btnGhost} onClick={onClose}>Avbryt</button>
    </div>
  </Modal>;
}

function NewProjectModal({clients,project,onClose,onSave}) {
  const [form,setForm]=useState({
    client_id:project?.client_id||(clients[0]?.id||""),
    name:project?.name||"",description:project?.description||"",
    value:project?.value||"",estimated_hours:project?.estimated_hours||"",
    deadline:project?.deadline||"",file_name:project?.file_name||null,
  });
  const [saving,setSaving]=useState(false);
  return <Modal title={project?"Redigera projekt":"Nytt projekt"} onClose={onClose} wide>
    <div style={S.formGrid}>
      <Fg label="Kund *"><select style={S.input} value={form.client_id} onChange={e=>setForm(f=>({...f,client_id:e.target.value}))}>{clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}</select></Fg>
      <Fg label="Projektnamn *"><input style={S.input} value={form.name} onChange={e=>setForm(f=>({...f,name:e.target.value}))} placeholder="Kampanjnamn…" autoFocus/></Fg>
      <Fg label="Beskrivning" full><textarea style={{...S.input,minHeight:80,resize:"vertical"}} value={form.description} onChange={e=>setForm(f=>({...f,description:e.target.value}))} placeholder="Projektbeskrivning…"/></Fg>
      <Fg label="Offererat pris (SEK)"><input type="number" style={S.input} value={form.value} onChange={e=>setForm(f=>({...f,value:e.target.value}))} placeholder="0"/></Fg>
      <Fg label="Estimerat timmar"><input type="number" style={S.input} value={form.estimated_hours} onChange={e=>setForm(f=>({...f,estimated_hours:e.target.value}))} placeholder="0"/></Fg>
      <Fg label="Deadline"><input type="date" style={S.input} value={form.deadline} onChange={e=>setForm(f=>({...f,deadline:e.target.value}))}/></Fg>
      <Fg label="Bifogad fil"><div style={S.fileUpload}><label style={S.fileLabel}><input type="file" style={{display:"none"}} onChange={e=>{const fl=e.target.files[0];if(fl)setForm(f=>({...f,file_name:fl.name}));}}/>{form.file_name?`📎 ${form.file_name}`:"Välj fil…"}</label></div></Fg>
    </div>
    <div style={{display:"flex",gap:12,marginTop:20}}>
      <button style={S.btnPrimary} disabled={saving} onClick={async()=>{if(!form.name||!form.client_id)return;setSaving(true);await onSave(form);}}>{saving?"Sparar…":project?"Uppdatera":"Skapa projekt"}</button>
      <button style={S.btnGhost} onClick={onClose}>Avbryt</button>
    </div>
  </Modal>;
}

function NewEntryModal({clients,projects,currentUser,onClose,onSave}) {
  const [form,setForm]=useState({client_id:"",project_id:"",person:currentUser,hours:"",date:new Date().toISOString().slice(0,10),note:""});
  const [saving,setSaving]=useState(false);
  const fp=form.client_id?projects.filter(p=>p.client_id===form.client_id):projects;
  return <Modal title="Rapportera tid" onClose={onClose}>
    <Fg label="Medarbetare"><select style={S.input} value={form.person} onChange={e=>setForm(f=>({...f,person:e.target.value}))}>{TEAM.map(t=><option key={t}>{t}</option>)}</select></Fg>
    <Fg label="Kund (filter)"><select style={S.input} value={form.client_id} onChange={e=>setForm(f=>({...f,client_id:e.target.value,project_id:""}))}><option value="">Alla</option>{clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}</select></Fg>
    <Fg label="Projekt *"><select style={S.input} value={form.project_id} onChange={e=>setForm(f=>({...f,project_id:e.target.value}))}><option value="">Välj…</option>{fp.map(p=>{const c=clients.find(cl=>cl.id===p.client_id);return <option key={p.id} value={p.id}>{c?`${c.name} — `:""}{p.name}{p.invoiced?" ✓":""}</option>;})}</select></Fg>
    <div style={S.formGrid}>
      <Fg label="Datum *"><input type="date" style={S.input} value={form.date} onChange={e=>setForm(f=>({...f,date:e.target.value}))}/></Fg>
      <Fg label="Timmar *"><input type="number" min="0.5" step="0.5" style={S.input} value={form.hours} onChange={e=>setForm(f=>({...f,hours:e.target.value}))}/></Fg>
    </div>
    <Fg label="Notat"><input style={S.input} value={form.note} onChange={e=>setForm(f=>({...f,note:e.target.value}))} placeholder="Vad jobbade du med?"/></Fg>
    <div style={{display:"flex",gap:12,marginTop:20}}>
      <button style={S.btnPrimary} disabled={saving} onClick={async()=>{if(!form.project_id||!form.hours)return;setSaving(true);await onSave({project_id:form.project_id,person:form.person,hours:Number(form.hours),date:form.date,note:form.note});}}>{saving?"Sparar…":"Spara"}</button>
      <button style={S.btnGhost} onClick={onClose}>Avbryt</button>
    </div>
  </Modal>;
}

function ProjectDetailModal({project,client,entries,onClose,onToggleInvoiced,onEdit,onDelete}) {
  const [showConfirm,setShowConfirm]=useState(false);
  const total=entries.reduce((s,e)=>s+Number(e.hours),0);
  const pct=project.estimated_hours?Math.min(100,Math.round(total/project.estimated_hours*100)):null;
  const days=daysLeft(project.deadline);
  const byPerson=TEAM.map(p=>({person:p,hours:entries.filter(e=>e.person===p).reduce((s,e)=>s+Number(e.hours),0)})).filter(x=>x.hours>0).sort((a,b)=>b.hours-a.hours);
  return <Modal title={project.name} onClose={onClose} wide>
    <div style={{display:"flex",gap:10,flexWrap:"wrap",marginBottom:20,alignItems:"center"}}>
      {client&&<span style={{...S.clientBadge,background:client.color+"22",color:client.color,fontSize:14}}>{client.name}</span>}
      {project.deadline&&<span style={{...S.clientBadge,background:"#F3F4F6",color:days!==null&&days<0?"#DC2626":days!==null&&days<7?"#D97706":"#374151"}}>📅 {fmtDate(project.deadline)}{days!==null?` (${days<0?"försenad":days+"d kvar"})`:""}</span>}
      {project.file_name&&<span style={{...S.clientBadge,background:"#EFF6FF",color:"#1D4ED8"}}>📎 {project.file_name}</span>}
      {project.invoiced&&<span style={{...S.invoicedBadge,fontSize:13}}>✓ Fakturerad {fmtDate(project.invoiced_at)}</span>}
    </div>
    {project.description&&<p style={{color:"#4B5563",marginBottom:16,lineHeight:1.6}}>{project.description}</p>}
    <div style={{display:"flex",gap:20,marginBottom:20,flexWrap:"wrap"}}>
      <div style={S.detailStat}><div style={S.detailStatVal}>{fmtSEK(project.value||0)}</div><div style={S.detailStatLbl}>Offererat</div></div>
      <div style={S.detailStat}><div style={S.detailStatVal}>{total} h</div><div style={S.detailStatLbl}>Nedlagd tid</div></div>
      <div style={S.detailStat}><div style={S.detailStatVal}>{project.estimated_hours||"–"} h</div><div style={S.detailStatLbl}>Estimat</div></div>
    </div>
    {pct!==null&&<div style={{marginBottom:20}}>
      <div style={{display:"flex",justifyContent:"space-between",marginBottom:6,fontSize:13}}>
        <span style={{color:"#6B7280"}}>Tidsåtgång vs estimat</span>
        <span style={{fontWeight:600,color:pct>90?"#DC2626":"#111"}}>{pct}%</span>
      </div>
      <div style={{...S.progressBg,height:10}}><div style={{...S.progressFill,width:pct+"%",height:10,background:pct>90?"#DC2626":(client?.color||"#1D4ED8")}}/></div>
    </div>}
    {byPerson.length>0&&<>
      <h3 style={{fontSize:14,fontWeight:600,color:"#374151",marginBottom:10}}>Tid per person</h3>
      <div style={{display:"flex",gap:8,flexWrap:"wrap",marginBottom:20}}>
        {byPerson.map(x=><div key={x.person} style={{background:"#F9FAFB",border:"1px solid #E5E7EB",borderRadius:8,padding:"8px 14px",fontSize:13}}><span style={{fontWeight:600}}>{x.hours}h</span> · {x.person}</div>)}
      </div>
    </>}
    <div style={{display:"flex",gap:10,flexWrap:"wrap"}}>
      {project.invoiced
        ?<button style={S.uninvoiceBtn} onClick={()=>onToggleInvoiced(project.id)}>Markera ej fakturerad</button>
        :<button style={{...S.btnPrimary,background:"#065F46"}} onClick={()=>onToggleInvoiced(project.id)}>✓ Markera som fakturerad</button>}
      <button style={S.btnGhost} onClick={()=>{onClose();onEdit(project);}}>✎ Redigera</button>
      <button style={{...S.btnGhost,color:"#EF4444",borderColor:"#FCA5A5"}} onClick={()=>setShowConfirm(true)}>🗑 Radera projekt</button>
      <button style={S.btnGhost} onClick={onClose}>Stäng</button>
    </div>
    {showConfirm && <ConfirmModal
      title="Radera projekt"
      message={`Är du säker på att du vill radera "${project.name}"? All rapporterad tid raderas också.`}
      onConfirm={()=>onDelete(project.id)}
      onCancel={()=>setShowConfirm(false)}
    />}
  </Modal>;
}

// ── Edit Entry Modal ─────────────────────────────────────────────────────────
function EditEntryModal({entry,clients,projects,onClose,onSave}) {
  const [form,setForm]=useState({
    project_id: entry.project_id,
    person:     entry.person,
    hours:      entry.hours,
    date:       entry.date,
    note:       entry.note||"",
    client_id:  projects.find(p=>p.id===entry.project_id)?.client_id||"",
  });
  const [saving,setSaving]=useState(false);
  const fp=form.client_id?projects.filter(p=>p.client_id===form.client_id):projects;

  return <Modal title="Redigera tidspost" onClose={onClose}>
    <Fg label="Medarbetare">
      <select style={S.input} value={form.person} onChange={e=>setForm(f=>({...f,person:e.target.value}))}>
        {TEAM.map(t=><option key={t}>{t}</option>)}
      </select>
    </Fg>
    <Fg label="Kund (filter)">
      <select style={S.input} value={form.client_id} onChange={e=>setForm(f=>({...f,client_id:e.target.value,project_id:""}))}>
        <option value="">Alla kunder</option>
        {clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
      </select>
    </Fg>
    <Fg label="Projekt *">
      <select style={S.input} value={form.project_id} onChange={e=>setForm(f=>({...f,project_id:e.target.value}))}>
        <option value="">Välj projekt…</option>
        {fp.map(p=>{
          const c=clients.find(cl=>cl.id===p.client_id);
          return <option key={p.id} value={p.id}>{c?`${c.name} — `:""}{p.name}{p.invoiced?" ✓":""}</option>;
        })}
      </select>
    </Fg>
    <div style={S.formGrid}>
      <Fg label="Datum *">
        <input type="date" style={S.input} value={form.date} onChange={e=>setForm(f=>({...f,date:e.target.value}))}/>
      </Fg>
      <Fg label="Timmar *">
        <input type="number" min="0.5" step="0.5" max="24" style={S.input} value={form.hours} onChange={e=>setForm(f=>({...f,hours:e.target.value}))}/>
      </Fg>
    </div>
    <Fg label="Notat">
      <input style={S.input} value={form.note} onChange={e=>setForm(f=>({...f,note:e.target.value}))} placeholder="Vad jobbade du med?"/>
    </Fg>
    <div style={{display:"flex",gap:12,marginTop:20}}>
      <button style={S.btnPrimary} disabled={saving} onClick={async()=>{
        if(!form.project_id||!form.hours||!form.date)return;
        setSaving(true);
        await onSave({project_id:form.project_id,person:form.person,hours:Number(form.hours),date:form.date,note:form.note});
      }}>{saving?"Sparar…":"Spara ändringar"}</button>
      <button style={S.btnGhost} onClick={onClose}>Avbryt</button>
    </div>
  </Modal>;
}

// ── Confirm Dialog ───────────────────────────────────────────────────────────
function ConfirmModal({title,message,onConfirm,onCancel}) {
  return <div style={S.overlay}>
    <div style={{...S.modal,maxWidth:420}}>
      <div style={{fontSize:24,marginBottom:12}}>⚠️</div>
      <h2 style={{...S.modalTitle,marginBottom:12}}>{title}</h2>
      <p style={{color:"#4B5563",fontSize:14,lineHeight:1.6,marginBottom:24}}>{message}</p>
      <div style={{display:"flex",gap:12}}>
        <button style={{...S.btnPrimary,background:"#DC2626"}} onClick={onConfirm}>Ja, radera</button>
        <button style={S.btnGhost} onClick={onCancel}>Avbryt</button>
      </div>
    </div>
  </div>;
}

// ── Styles ────────────────────────────────────────────────────────────────────
const S = {
  root:            {display:"flex",height:"100vh",background:"#F9FAFB",fontFamily:"'DM Sans','Segoe UI',sans-serif",fontSize:14,color:"#111827",overflow:"hidden"},
  sidebar:         {width:220,background:"#111827",display:"flex",flexDirection:"column",flexShrink:0,overflowY:"auto"},
  logo:            {padding:"28px 20px 20px",display:"flex",alignItems:"baseline",gap:6},
  logoMark:        {fontSize:28,fontWeight:800,color:"#F59E0B",letterSpacing:-1},
  logoText:        {fontSize:18,fontWeight:600,color:"#F9FAFB"},
  userPicker:      {padding:"0 16px 20px"},
  userLabel:       {fontSize:11,color:"#6B7280",marginBottom:6,textTransform:"uppercase",letterSpacing:"0.05em"},
  userSelect:      {width:"100%",background:"#1F2937",border:"1px solid #374151",color:"#F9FAFB",borderRadius:8,padding:"7px 10px",fontSize:13,cursor:"pointer"},
  nav:             {flex:1,padding:"4px 10px"},
  navItem:         {display:"flex",alignItems:"center",gap:10,width:"100%",padding:"10px 12px",borderRadius:8,background:"none",border:"none",color:"#9CA3AF",fontSize:14,cursor:"pointer",marginBottom:2,textAlign:"left"},
  navItemActive:   {background:"#1F2937",color:"#F9FAFB"},
  navIcon:         {fontSize:16,width:20,textAlign:"center"},
  sidebarBottom:   {padding:"16px 12px 24px",display:"flex",flexDirection:"column",gap:8},
  quickBtn:        {background:"#F59E0B",color:"#111",border:"none",borderRadius:8,padding:"9px 14px",fontSize:13,fontWeight:600,cursor:"pointer"},
  quickBtnOutline: {background:"none",color:"#9CA3AF",border:"1px solid #374151",borderRadius:8,padding:"8px 14px",fontSize:13,cursor:"pointer"},
  refreshBtn:      {background:"none",color:"#6B7280",border:"1px solid #374151",borderRadius:8,padding:"6px 14px",fontSize:12,cursor:"pointer"},
  logoutBtn:       {background:"none",color:"#EF4444",border:"1px solid #374151",borderRadius:8,padding:"6px 14px",fontSize:12,cursor:"pointer"},
  periodBtn:       {background:"#fff",color:"#374151",border:"1px solid #E5E7EB",borderRadius:8,padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:500},
  main:            {flex:1,overflowY:"auto",padding:"32px 40px"},
  page:            {maxWidth:1100,margin:"0 auto"},
  pageHeader:      {display:"flex",alignItems:"flex-start",justifyContent:"space-between",marginBottom:28,gap:16},
  h1:              {fontSize:26,fontWeight:700,color:"#111827",margin:0,letterSpacing:-0.5},
  h2:              {fontSize:18,fontWeight:600,color:"#111827",margin:"28px 0 16px"},
  subtitle:        {color:"#6B7280",margin:"4px 0 0",fontSize:14},
  kpiRow:          {display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:16,marginBottom:8},
  kpiCard:         {background:"#fff",borderRadius:12,padding:"20px 22px",borderTop:"3px solid",boxShadow:"0 1px 3px rgba(0,0,0,.06)"},
  kpiValue:        {fontSize:26,fontWeight:700,lineHeight:1.2},
  kpiLabel:        {fontSize:13,color:"#374151",fontWeight:500,marginTop:4},
  kpiSub:          {fontSize:12,color:"#9CA3AF",marginTop:2},
  projectGrid:     {display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(230px,1fr))",gap:16},
  projectCard:     {background:"#fff",borderRadius:12,overflow:"hidden",cursor:"pointer",boxShadow:"0 1px 3px rgba(0,0,0,.07)",display:"flex",flexDirection:"column"},
  projectCardAccent:{height:4},
  projectCardInner:{padding:16},
  clientBadge:     {display:"inline-block",borderRadius:20,padding:"2px 10px",fontSize:12,fontWeight:600,marginBottom:8},
  projectName:     {fontWeight:600,fontSize:15,color:"#111827",marginBottom:4},
  projectValue:    {fontSize:13,color:"#6B7280",marginBottom:10},
  progressWrap:    {display:"flex",alignItems:"center",gap:8,marginBottom:6},
  progressBg:      {flex:1,height:6,background:"#F3F4F6",borderRadius:99,overflow:"hidden"},
  progressFill:    {height:"100%",borderRadius:99,transition:"width 0.4s"},
  progressLabel:   {fontSize:11,color:"#9CA3AF",whiteSpace:"nowrap"},
  deadlineBadge:   {fontSize:11,marginTop:4},
  invoicedBadge:   {display:"inline-block",background:"#D1FAE5",color:"#065F46",borderRadius:20,padding:"2px 10px",fontSize:12,fontWeight:700},
  invoiceBtn:      {background:"none",border:"1px solid #D1D5DB",borderRadius:20,padding:"2px 10px",fontSize:11,color:"#374151",cursor:"pointer",fontWeight:600,whiteSpace:"nowrap"},
  invoiceBtnTable: {background:"#ECFDF5",border:"1px solid #A7F3D0",borderRadius:8,padding:"5px 10px",fontSize:12,color:"#065F46",cursor:"pointer",fontWeight:600},
  uninvoiceBtn:    {background:"none",border:"1px solid #E5E7EB",borderRadius:8,padding:"5px 10px",fontSize:12,color:"#6B7280",cursor:"pointer"},
  editBtn:         {background:"none",border:"1px solid #E5E7EB",borderRadius:6,padding:"4px 8px",color:"#6B7280",cursor:"pointer",fontSize:14},
  clientGrid:      {display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(260px,1fr))",gap:16},
  clientCard:      {background:"#fff",borderRadius:12,padding:20,boxShadow:"0 1px 3px rgba(0,0,0,.07)"},
  clientDot:       {width:40,height:40,borderRadius:"50%",marginBottom:12},
  clientName:      {fontSize:18,fontWeight:700,marginBottom:14,color:"#111827"},
  clientStats:     {display:"flex",gap:16,marginBottom:16},
  clientStat:      {display:"flex",flexDirection:"column"},
  clientStatVal:   {fontSize:18,fontWeight:700,color:"#111827"},
  clientStatLbl:   {fontSize:11,color:"#9CA3AF"},
  clientProjectList:{borderTop:"1px solid #F3F4F6",paddingTop:12,display:"flex",flexDirection:"column",gap:6},
  clientProjectItem:{display:"flex",alignItems:"center",gap:8,fontSize:13},
  formCard:        {background:"#fff",borderRadius:12,padding:24,boxShadow:"0 1px 3px rgba(0,0,0,.07)",marginBottom:32},
  formGrid:        {display:"grid",gridTemplateColumns:"1fr 1fr",gap:"0 20px"},
  formGroup:       {marginBottom:16},
  label:           {display:"block",fontSize:12,fontWeight:600,color:"#374151",marginBottom:6,textTransform:"uppercase",letterSpacing:"0.04em"},
  input:           {width:"100%",padding:"9px 12px",border:"1px solid #E5E7EB",borderRadius:8,fontSize:14,color:"#111827",background:"#fff",boxSizing:"border-box",outline:"none",fontFamily:"inherit"},
  fileUpload:      {border:"2px dashed #E5E7EB",borderRadius:8,padding:10,textAlign:"center"},
  fileLabel:       {cursor:"pointer",color:"#6B7280",fontSize:13},
  tableWrap:       {background:"#fff",borderRadius:12,boxShadow:"0 1px 3px rgba(0,0,0,.07)",overflow:"auto"},
  table:           {width:"100%",borderCollapse:"collapse"},
  th:              {textAlign:"left",padding:"12px 16px",fontSize:11,fontWeight:700,color:"#9CA3AF",textTransform:"uppercase",letterSpacing:"0.05em",borderBottom:"1px solid #F3F4F6"},
  tr:              {borderBottom:"1px solid #F9FAFB"},
  td:              {padding:"12px 16px",color:"#374151",verticalAlign:"middle"},
  btnPrimary:      {background:"#111827",color:"#fff",border:"none",borderRadius:8,padding:"10px 20px",fontSize:14,fontWeight:600,cursor:"pointer"},
  btnGhost:        {background:"none",color:"#6B7280",border:"1px solid #E5E7EB",borderRadius:8,padding:"9px 18px",fontSize:14,cursor:"pointer"},
  deleteBtn:       {background:"none",border:"none",color:"#D1D5DB",cursor:"pointer",fontSize:16,padding:"4px 8px",borderRadius:6},
  deleteBtnRed:    {background:"none",border:"none",color:"#FCA5A5",cursor:"pointer",fontSize:16,padding:"4px 8px",borderRadius:6},
  savedMsg:        {color:"#065F46",fontWeight:600,fontSize:14},
  overlay:         {position:"fixed",inset:0,background:"rgba(0,0,0,.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1000,backdropFilter:"blur(4px)"},
  modal:           {background:"#fff",borderRadius:16,padding:28,width:"90%",maxWidth:480,maxHeight:"90vh",overflowY:"auto",boxShadow:"0 20px 60px rgba(0,0,0,.2)"},
  modalHeader:     {display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:24},
  modalTitle:      {fontSize:20,fontWeight:700,margin:0,color:"#111827"},
  closeBtn:        {background:"none",border:"none",fontSize:18,color:"#9CA3AF",cursor:"pointer",padding:"4px 8px",borderRadius:6},
  detailStat:      {background:"#F9FAFB",borderRadius:10,padding:"12px 20px",minWidth:100},
  detailStatVal:   {fontSize:20,fontWeight:700,color:"#111827"},
  detailStatLbl:   {fontSize:12,color:"#9CA3AF",marginTop:2},
};

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);

// ══════════════════════════════════════════════════════════════════════════════
// RAPPORTER
// ══════════════════════════════════════════════════════════════════════════════
function ReportsView({clients, projects, entries, onToggleInvoiced}) {
  const today = new Date();
  const firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1).toISOString().slice(0,10);
  const [dateFrom, setDateFrom] = useState(firstOfMonth);
  const [dateTo,   setDateTo]   = useState(today.toISOString().slice(0,10));
  const [activeTab, setActiveTab] = useState('invoicing');

  // ── Faktureringsunderlag filter/sort ──
  const [invFilterClient,  setInvFilterClient]  = useState('');
  const [invFilterStatus,  setInvFilterStatus]  = useState('not_invoiced');
  const [invSearch,        setInvSearch]         = useState('');
  const [invSort,          setInvSort]           = useState('client');
  const [pendingToggle,    setPendingToggle]      = useState(null);

  // Filter entries by date range
  const periodEntries = entries.filter(e => e.date >= dateFrom && e.date <= dateTo);

  // ── Helpers ──
  const clientOf  = p => clients.find(c => c.id === p?.client_id);
  const projectOf = e => projects.find(p => p.id === e.project_id);

  // ── 1. Faktureringsunderlag – alla projekt ──
  const allInvoicingData = projects
    .map(p => {
      const pEntries = entries.filter(e => e.project_id === p.id);
      const hours    = pEntries.reduce((s,e) => s + Number(e.hours), 0);
      const cl       = clientOf(p);
      return { ...p, hours, client: cl };
    })
    .filter(p => p.hours > 0 || Number(p.value||0) > 0);

  const invoicingData = allInvoicingData
    .filter(p => {
      if (invFilterStatus === 'invoiced'     && !p.invoiced) return false;
      if (invFilterStatus === 'not_invoiced' &&  p.invoiced) return false;
      if (invFilterClient && p.client_id !== invFilterClient) return false;
      if (invSearch && !p.name.toLowerCase().includes(invSearch.toLowerCase()) &&
          !(p.client?.name||'').toLowerCase().includes(invSearch.toLowerCase())) return false;
      return true;
    })
    .sort((a,b) => {
      if (invSort === 'client')   return (a.client?.name||'').localeCompare(b.client?.name||'');
      if (invSort === 'project')  return a.name.localeCompare(b.name);
      if (invSort === 'hours')    return b.hours - a.hours;
      if (invSort === 'value')    return Number(b.value||0) - Number(a.value||0);
      if (invSort === 'deadline') return (a.deadline||'').localeCompare(b.deadline||'');
      return 0;
    });

  const uninvoicedTotal = allInvoicingData.filter(p=>!p.invoiced).reduce((s,p)=>s+Number(p.value||0),0);

  // ── 2. Timmar per medarbetare ──
  const personData = TEAM.map(person => {
    const pEntries  = periodEntries.filter(e => e.person === person);
    const total     = pEntries.reduce((s,e) => s + Number(e.hours), 0);
    const billable  = pEntries.filter(e => {
      const proj = projectOf(e);
      return proj && Number(proj.value||0) > 0;
    }).reduce((s,e) => s + Number(e.hours), 0);
    const rate = total > 0 ? Math.round(billable / total * 100) : 0;
    // breakdown per project
    const byProject = projects
      .map(p => ({
        project: p,
        client: clientOf(p),
        hours: pEntries.filter(e => e.project_id === p.id).reduce((s,e) => s + Number(e.hours), 0)
      }))
      .filter(x => x.hours > 0)
      .sort((a,b) => b.hours - a.hours);
    return { person, total, billable, rate, byProject };
  }).filter(x => x.total > 0).sort((a,b) => b.total - a.total);

  // ── 3. Debiterbar tid per kund & projekt ──
  const billableData = clients.map(cl => {
    const cProjects = projects.filter(p => p.client_id === cl.id && Number(p.value||0) > 0);
    const rows = cProjects.map(p => {
      const pEntries = periodEntries.filter(e => e.project_id === p.id);
      const hours    = pEntries.reduce((s,e) => s + Number(e.hours), 0);
      const pct      = p.estimated_hours ? Math.min(100, Math.round(hours / p.estimated_hours * 100)) : null;
      return { ...p, hours, pct };
    }).filter(p => p.hours > 0);
    const totalHours = rows.reduce((s,p) => s + p.hours, 0);
    return { client: cl, rows, totalHours };
  }).filter(x => x.rows.length > 0);

  // ── 4. Projektlönsamhet ──
  const profitData = projects
    .filter(p => Number(p.value||0) > 0)
    .map(p => {
      const hours   = hoursFor(entries, p.id);
      const cl      = clientOf(p);
      // Rough hourly rate: value / estimated_hours
      const estRate = p.estimated_hours ? Number(p.value) / Number(p.estimated_hours) : 0;
      const overrun = p.estimated_hours ? hours - Number(p.estimated_hours) : 0;
      const overrunValue = estRate * overrun;
      const pct     = p.estimated_hours ? Math.round(hours / p.estimated_hours * 100) : null;
      return { ...p, hours, client: cl, overrun, overrunValue, pct, estRate };
    })
    .sort((a,b) => (b.pct||0) - (a.pct||0));

  // ── Period totals ──
  const periodTotal    = periodEntries.reduce((s,e) => s + Number(e.hours), 0);
  const periodBillable = periodEntries.filter(e => {
    const p = projectOf(e); return p && Number(p.value||0) > 0;
  }).reduce((s,e) => s + Number(e.hours), 0);
  const overallRate = periodTotal > 0 ? Math.round(periodBillable / periodTotal * 100) : 0;

  // ── CSV export ──
  const exportCSV = (rows, headers, filename) => {
    const bom = '\uFEFF';
    const csv = bom + [headers, ...rows].map(r => r.map(v => `"${String(v).replace(/"/g,'""')}"`).join(';')).join('\n');
    const a = document.createElement('a');
    a.href = URL.createObjectURL(new Blob([csv], {type:'text/csv;charset=utf-8'}));
    a.download = filename;
    a.click();
  };

  // ── Print / PDF ──
  const printReport = () => window.print();

  const tabs = [
    { id:'invoicing', label:'Faktureringsunderlag' },
    { id:'persons',   label:'Timmar per person' },
    { id:'billable',  label:'Debiterbar tid' },
    { id:'profit',    label:'Projektlönsamhet' },
  ];

  return (
    <div style={S.page}>
      <div style={S.pageHeader}>
        <h1 style={S.h1}>Rapporter</h1>
        <div style={{display:'flex', gap:8}}>
          <button style={S.btnGhost} onClick={printReport}>🖨 Skriv ut / PDF</button>
          <button style={{...S.btnPrimary, background:'#065F46'}} onClick={() => {
            if (activeTab === 'invoicing') {
              exportCSV(
                invoicingData.map(p => [p.client?.name||'', p.name, p.hours, p.value||0, p.estimated_hours||0, fmtDate(p.deadline)]),
                ['Kund','Projekt','Nedlagda timmar','Offererat (SEK)','Estimat (h)','Deadline'],
                'faktureringsunderlag.csv'
              );
            } else if (activeTab === 'persons') {
              exportCSV(
                personData.map(p => [p.person, p.total, p.billable, p.rate+'%']),
                ['Medarbetare','Totalt (h)','Debiterbart (h)','Debiteringsgrad'],
                'timmar_per_person.csv'
              );
            } else if (activeTab === 'billable') {
              const rows = [];
              billableData.forEach(cl => cl.rows.forEach(p => rows.push([cl.client.name, p.name, p.hours, p.estimated_hours||0, p.pct !== null ? p.pct+'%' : '–'])));
              exportCSV(rows, ['Kund','Projekt','Timmar (period)','Estimat (h)','Förbrukat'], 'debiterbar_tid.csv');
            } else {
              exportCSV(
                profitData.map(p => [p.client?.name||'', p.name, p.value||0, p.estimated_hours||0, p.hours, p.overrun, p.pct !== null ? p.pct+'%' : '–']),
                ['Kund','Projekt','Offererat (SEK)','Estimat (h)','Nedlagda (h)','Överskridning (h)','Förbrukat %'],
                'projektlonsamhet.csv'
              );
            }
          }}>⬇ Exportera CSV</button>
        </div>
      </div>

      {/* Period-filter */}
      <div style={{background:'#fff', borderRadius:12, padding:'16px 20px', boxShadow:'0 1px 3px rgba(0,0,0,.06)', marginBottom:20, display:'flex', gap:16, alignItems:'center', flexWrap:'wrap'}}>
        <span style={{fontWeight:600, fontSize:13, color:'#374151'}}>Period:</span>
        <div style={{display:'flex', alignItems:'center', gap:8}}>
          <input type="date" style={{...S.input, maxWidth:160}} value={dateFrom} onChange={e=>setDateFrom(e.target.value)}/>
          <span style={{color:'#9CA3AF'}}>→</span>
          <input type="date" style={{...S.input, maxWidth:160}} value={dateTo} onChange={e=>setDateTo(e.target.value)}/>
        </div>
        {['Den här månaden','Förra månaden','Det här året'].map((lbl,i) => (
          <button key={lbl} style={S.periodBtn} onClick={()=>{
            const n = new Date();
            if (i===0) { setDateFrom(new Date(n.getFullYear(),n.getMonth(),1).toISOString().slice(0,10)); setDateTo(n.toISOString().slice(0,10)); }
            if (i===1) { setDateFrom(new Date(n.getFullYear(),n.getMonth()-1,1).toISOString().slice(0,10)); setDateTo(new Date(n.getFullYear(),n.getMonth(),0).toISOString().slice(0,10)); }
            if (i===2) { setDateFrom(new Date(n.getFullYear(),0,1).toISOString().slice(0,10)); setDateTo(n.toISOString().slice(0,10)); }
          }}>{lbl}</button>
        ))}
      </div>

      {/* KPI rad */}
      <div style={{display:'grid', gridTemplateColumns:'repeat(4,1fr)', gap:16, marginBottom:20}}>
        <KpiCard label="Totala timmar (period)"   value={`${periodTotal} h`}    sub={`${periodEntries.length} poster`}  accent="#B45309"/>
        <KpiCard label="Debiterbart (period)"     value={`${periodBillable} h`} sub="på prissatta projekt"               accent="#065F46"/>
        <KpiCard label="Debiteringsgrad"          value={`${overallRate}%`}     sub="av total tid"                       accent="#1D4ED8"/>
        <KpiCard label="Ej fakturerat (totalt)"   value={fmtSEK(uninvoicedTotal)} sub={`${allInvoicingData.filter(p=>!p.invoiced).length} projekt`} accent="#7C3AED"/>
      </div>

      {/* Tabbar */}
      <div style={{display:'flex', gap:4, marginBottom:20, background:'#F3F4F6', borderRadius:10, padding:4}}>
        {tabs.map(t => (
          <button key={t.id} onClick={()=>setActiveTab(t.id)}
            style={{flex:1, padding:'8px 12px', borderRadius:8, border:'none', cursor:'pointer', fontSize:13, fontWeight:600,
              background: activeTab===t.id ? '#fff' : 'none',
              color: activeTab===t.id ? '#111827' : '#6B7280',
              boxShadow: activeTab===t.id ? '0 1px 3px rgba(0,0,0,.1)' : 'none'
            }}>{t.label}</button>
        ))}
      </div>

      {/* ── Tab: Faktureringsunderlag ── */}
      {activeTab==='invoicing' && (
        <div>
          {/* Filter-rad */}
          <div style={{display:'flex', gap:12, flexWrap:'wrap', marginBottom:16, alignItems:'center'}}>
            <input
              style={{...S.input, maxWidth:220}}
              placeholder="Sök kund eller projekt…"
              value={invSearch}
              onChange={e=>setInvSearch(e.target.value)}
            />
            <select style={{...S.input, maxWidth:200}} value={invFilterClient} onChange={e=>setInvFilterClient(e.target.value)}>
              <option value="">Alla kunder</option>
              {clients.map(c=><option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
            <select style={{...S.input, maxWidth:180}} value={invFilterStatus} onChange={e=>setInvFilterStatus(e.target.value)}>
              <option value="all">Alla status</option>
              <option value="not_invoiced">Ej fakturerade</option>
              <option value="invoiced">Fakturerade</option>
            </select>
            <select style={{...S.input, maxWidth:180}} value={invSort} onChange={e=>setInvSort(e.target.value)}>
              <option value="client">Sortera: Kund</option>
              <option value="project">Sortera: Projekt</option>
              <option value="hours">Sortera: Timmar</option>
              <option value="value">Sortera: Offererat</option>
              <option value="deadline">Sortera: Deadline</option>
            </select>
          </div>

          <div style={S.tableWrap}>
            <table style={S.table}>
              <thead>
                <tr>
                  {['Kund','Projekt','Nedlagda timmar','Estimat','Offererat','Deadline','Fakturastatus',''].map(h=>(
                    <th key={h} style={S.th}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {invoicingData.map(p => {
                  const d = daysLeft(p.deadline);
                  return (
                    <tr key={p.id} style={{...S.tr, opacity: p.invoiced ? 0.72 : 1}}>
                      <td style={S.td}>
                        {p.client && <span style={{...S.clientBadge, background:p.client.color+'22', color:p.client.color}}>{p.client.name}</span>}
                      </td>
                      <td style={{...S.td, fontWeight:600}}>
                        {p.name}
                        {p.description && <div style={{fontSize:11,color:'#9CA3AF',marginTop:2}}>{p.description.slice(0,50)}{p.description.length>50?'…':''}</div>}
                      </td>
                      <td style={S.td}><span style={{fontWeight:700, fontSize:15}}>{p.hours} h</span></td>
                      <td style={S.td}>{p.estimated_hours ? `${p.estimated_hours} h` : '–'}</td>
                      <td style={{...S.td, fontWeight:600, color:'#065F46'}}>{fmtSEK(p.value||0)}</td>
                      <td style={S.td}>
                        <span style={{color: d!==null&&d<0?'#DC2626':d!==null&&d<7?'#D97706':'#374151'}}>
                          {fmtDate(p.deadline)}
                        </span>
                      </td>
                      <td style={S.td} onClick={e=>e.stopPropagation()}>
                        {p.invoiced
                          ? <div>
                              <span style={S.invoicedBadge}>✓ Fakturerad</span>
                              <div style={{fontSize:11,color:'#9CA3AF',marginTop:2}}>{fmtDate(p.invoiced_at)}</div>
                              <button style={{...S.uninvoiceBtn,marginTop:4}} onClick={()=>setPendingToggle(p)}>Ångra</button>
                            </div>
                          : <button style={S.invoiceBtnTable} onClick={()=>setPendingToggle(p)}>Markera fakturerad</button>
                        }
                      </td>
                      <td style={S.td}>
                        {p.client && (
                          <div style={{display:'flex',alignItems:'center',gap:4}}>
                            <div style={{width:8,height:8,borderRadius:'50%',background:p.client.color}}/>
                          </div>
                        )}
                      </td>
                    </tr>
                  );
                })}
                {invoicingData.length === 0 && (
                  <tr><td colSpan={8} style={{...S.td, textAlign:'center', color:'#9CA3AF', padding:32}}>
                    Inga projekt matchar filtret
                  </td></tr>
                )}
              </tbody>
              {invoicingData.length > 0 && (
                <tfoot>
                  <tr style={{background:'#F9FAFB', borderTop:'2px solid #E5E7EB'}}>
                    <td colSpan={2} style={{...S.td, fontWeight:700}}>Totalt ({invoicingData.length} projekt)</td>
                    <td style={{...S.td, fontWeight:700}}>{invoicingData.reduce((s,p)=>s+p.hours,0)} h</td>
                    <td style={S.td}></td>
                    <td style={{...S.td, fontWeight:700, color:'#065F46'}}>{fmtSEK(invoicingData.reduce((s,p)=>s+Number(p.value||0),0))}</td>
                    <td colSpan={3} style={S.td}></td>
                  </tr>
                </tfoot>
              )}
            </table>
          </div>

          {/* Bekräftelse-modal för faktura-toggle */}
          {pendingToggle && <ConfirmModal
            title={pendingToggle.invoiced ? 'Ångra fakturering' : 'Markera som fakturerad'}
            message={pendingToggle.invoiced
              ? `Vill du markera "${pendingToggle.name}" som ej fakturerad?`
              : `Vill du markera "${pendingToggle.name}" som fakturerad?`
            }
            onConfirm={async()=>{
              await onToggleInvoiced(pendingToggle.id);
              setPendingToggle(null);
            }}
            onCancel={()=>setPendingToggle(null)}
          />}
        </div>
      )}

      {/* ── Tab: Timmar per person ── */}
      {activeTab==='persons' && (
        <div>
          <p style={{color:'#6B7280', fontSize:13, marginBottom:16}}>Vald period: {fmtDate(dateFrom)} – {fmtDate(dateTo)}</p>
          <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill,minmax(320px,1fr))', gap:16}}>
            {personData.map(p => (
              <div key={p.person} style={{background:'#fff', borderRadius:12, padding:20, boxShadow:'0 1px 3px rgba(0,0,0,.07)'}}>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:16}}>
                  <div style={{fontWeight:700, fontSize:16}}>{p.person}</div>
                  <div style={{...S.invoicedBadge, background: p.rate>=70?'#D1FAE5':'#FEF3C7', color: p.rate>=70?'#065F46':'#92400E'}}>{p.rate}% debiterbar</div>
                </div>
                <div style={{display:'flex', gap:16, marginBottom:16}}>
                  <div style={S.detailStat}><div style={S.detailStatVal}>{p.total} h</div><div style={S.detailStatLbl}>Totalt</div></div>
                  <div style={S.detailStat}><div style={{...S.detailStatVal, color:'#065F46'}}>{p.billable} h</div><div style={S.detailStatLbl}>Debiterbart</div></div>
                  <div style={S.detailStat}><div style={{...S.detailStatVal, color:'#9CA3AF'}}>{(p.total-p.billable)} h</div><div style={S.detailStatLbl}>Ej debiterbart</div></div>
                </div>
                <div style={{...S.progressBg, height:8, marginBottom:12}}>
                  <div style={{...S.progressFill, width:p.rate+'%', height:8, background: p.rate>=70?'#065F46':'#D97706'}}/>
                </div>
                <div style={{borderTop:'1px solid #F3F4F6', paddingTop:12}}>
                  {p.byProject.slice(0,5).map(x => {
                    const cl = x.client;
                    return (
                      <div key={x.project.id} style={{display:'flex', justifyContent:'space-between', fontSize:13, marginBottom:6}}>
                        <div style={{display:'flex', alignItems:'center', gap:6, overflow:'hidden'}}>
                          {cl && <span style={{width:8,height:8,borderRadius:'50%',background:cl.color,flexShrink:0}}/>}
                          <span style={{color:'#4B5563', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap'}}>{x.project.name}</span>
                        </div>
                        <span style={{fontWeight:600, flexShrink:0, marginLeft:8}}>{x.hours} h</span>
                      </div>
                    );
                  })}
                  {p.byProject.length > 5 && <div style={{fontSize:12,color:'#9CA3AF'}}>+{p.byProject.length-5} projekt till…</div>}
                </div>
              </div>
            ))}
            {personData.length === 0 && <div style={{color:'#9CA3AF', padding:32}}>Inga timmar registrerade under vald period.</div>}
          </div>
        </div>
      )}

      {/* ── Tab: Debiterbar tid ── */}
      {activeTab==='billable' && (
        <div>
          <p style={{color:'#6B7280', fontSize:13, marginBottom:16}}>Nedlagd tid på prissatta projekt, per kund. Period: {fmtDate(dateFrom)} – {fmtDate(dateTo)}</p>
          {billableData.map(({client:cl, rows, totalHours}) => (
            <div key={cl.id} style={{marginBottom:24}}>
              <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:8}}>
                <div style={{width:12, height:12, borderRadius:'50%', background:cl.color}}/>
                <h3 style={{fontWeight:700, fontSize:16, color:'#111827'}}>{cl.name}</h3>
                <span style={{color:'#9CA3AF', fontSize:13}}>{totalHours} h totalt</span>
              </div>
              <div style={S.tableWrap}>
                <table style={S.table}>
                  <thead><tr>{['Projekt','Timmar (period)','Estimat','Förbrukat','Offererat'].map(h=><th key={h} style={S.th}>{h}</th>)}</tr></thead>
                  <tbody>
                    {rows.map(p => (
                      <tr key={p.id} style={S.tr}>
                        <td style={{...S.td, fontWeight:600}}>{p.name}{p.invoiced&&<span style={{...S.invoicedBadge,marginLeft:8,fontSize:10}}>✓</span>}</td>
                        <td style={{...S.td, fontWeight:700}}>{p.hours} h</td>
                        <td style={S.td}>{p.estimated_hours ? `${p.estimated_hours} h` : '–'}</td>
                        <td style={S.td}>
                          {p.pct !== null && (
                            <div style={{display:'flex', alignItems:'center', gap:8}}>
                              <div style={S.progressBg}><div style={{...S.progressFill,width:p.pct+'%',background:p.pct>90?'#DC2626':cl.color}}/></div>
                              <span style={{fontSize:12, color:p.pct>90?'#DC2626':'#6B7280'}}>{p.pct}%</span>
                            </div>
                          )}
                        </td>
                        <td style={{...S.td, color:'#065F46', fontWeight:600}}>{fmtSEK(p.value||0)}</td>
                      </tr>
                    ))}
                  </tbody>
                  <tfoot>
                    <tr style={{background:'#F9FAFB'}}>
                      <td style={{...S.td,fontWeight:700}}>Totalt {cl.name}</td>
                      <td style={{...S.td,fontWeight:700}}>{totalHours} h</td>
                      <td colSpan={3} style={S.td}></td>
                    </tr>
                  </tfoot>
                </table>
              </div>
            </div>
          ))}
          {billableData.length === 0 && <div style={{color:'#9CA3AF', padding:32}}>Inga debiterbara timmar under vald period.</div>}
        </div>
      )}

      {/* ── Tab: Projektlönsamhet ── */}
      {activeTab==='profit' && (
        <div>
          <p style={{color:'#6B7280', fontSize:13, marginBottom:16}}>Alla prissatta projekt — total nedlagd tid vs estimat. Röd = överskridna estimat.</p>
          <div style={S.tableWrap}>
            <table style={S.table}>
              <thead><tr>{['Projekt','Kund','Offererat','Estimat','Nedlagd tid','Överskridning','Förbrukat','Status'].map(h=><th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>
                {profitData.map(p => (
                  <tr key={p.id} style={{...S.tr, background: p.overrun>0?'#FFF7F7':''}}>
                    <td style={{...S.td,fontWeight:600}}>{p.name}</td>
                    <td style={S.td}>{p.client&&<span style={{...S.clientBadge,background:p.client.color+'22',color:p.client.color}}>{p.client.name}</span>}</td>
                    <td style={{...S.td,color:'#065F46',fontWeight:600}}>{fmtSEK(p.value||0)}</td>
                    <td style={S.td}>{p.estimated_hours ? `${p.estimated_hours} h` : '–'}</td>
                    <td style={{...S.td,fontWeight:700}}>{p.hours} h</td>
                    <td style={{...S.td, color:p.overrun>0?'#DC2626':p.overrun<0?'#065F46':'#6B7280', fontWeight:p.overrun!==0?700:400}}>
                      {p.overrun>0 ? `+${p.overrun} h` : p.overrun<0 ? `${p.overrun} h` : '–'}
                      {p.overrun>0 && p.overrunValue>0 && <div style={{fontSize:11,color:'#DC2626'}}>{fmtSEK(p.overrunValue)}</div>}
                    </td>
                    <td style={S.td}>
                      {p.pct !== null && (
                        <div style={{display:'flex',alignItems:'center',gap:6}}>
                          <div style={S.progressBg}><div style={{...S.progressFill,width:Math.min(p.pct,100)+'%',background:p.pct>100?'#DC2626':p.pct>80?'#D97706':'#065F46'}}/></div>
                          <span style={{fontSize:12,fontWeight:600,color:p.pct>100?'#DC2626':p.pct>80?'#D97706':'#374151'}}>{p.pct}%</span>
                        </div>
                      )}
                    </td>
                    <td style={S.td}>
                      {p.invoiced
                        ? <span style={S.invoicedBadge}>✓ Fakturerad</span>
                        : <span style={{...S.clientBadge,background:'#FEF3C7',color:'#92400E'}}>Ej fakturerad</span>
                      }
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div style={{marginTop:16, padding:'12px 16px', background:'#FEF3C7', borderRadius:8, fontSize:13, color:'#92400E'}}>
            💡 <strong>Överskridning i kr</strong> är beräknat på offererat pris / estimerade timmar × överskridna timmar — ett indikativt värde.
          </div>
        </div>
      )}
    </div>
  );
}
