const {S,Head,I,P}=window.WFA;
const {UIButton,UIInput,UICard,UIAvatar,UIPill,UITabs,UIModal,UISelect,UIDrawer,UIEmptyState}=window.XCOPEDesignSystem_bf80f1;

// fixed "now" for the mock
const CL_TODAY={y:2026,m:7,day:24};const CL_NOW=14.6;
const CL_WD=["Seg","Ter","Qua","Qui","Sex","Sáb","Dom"];
const CL_MONTHS=["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"];
const CL_KIND={
  reuniao:{label:"Reunião",tone:"info"},
  entrevista:{label:"Entrevista",tone:"accent"},
  formacao:{label:"Formação",tone:"success"},
  ausencia:{label:"Ausência",tone:"warning"},
  pessoal:{label:"Pessoal",tone:"neutral"},
  tarefa:{label:"Tarefa",tone:"info"},
};
const CL_TONE={info:"var(--ui-info)",accent:"var(--ui-accent)",success:"var(--ui-success)",warning:"var(--ui-warning)",neutral:"var(--ui-text-3)"};
// day = day of July 2026
const CL_EV=[
  {id:1,day:20,s:10,e:11,t:"Ponto semanal de Pessoas",k:"reuniao",loc:"Sala Douro",who:["Carla Dias","Rui Pinto"]},
  {id:2,day:20,s:14.5,e:15.5,t:"Entrevista — QA sénior",k:"entrevista",loc:"Videochamada",who:["Ana Reis"]},
  {id:3,day:21,s:9.5,e:10.5,t:"Revisão de folhas de ponto",k:"reuniao",loc:"Sala Tejo",who:["Hugo Montenegro"]},
  {id:4,day:21,s:12,e:13.5,t:"Formação: nova política de despesas",k:"formacao",loc:"Auditório",who:["Toda a equipa"]},
  {id:5,day:22,s:10.5,e:11.5,t:"Alinhamento com Xcope Produto",k:"reuniao",loc:"Videochamada",who:["Tomás Jervell"]},
  {id:6,day:22,s:15,e:16,t:"Entrevista — Técnico de frota",k:"entrevista",loc:"Sala Douro",who:["Rui Pinto"]},
  {id:7,day:23,s:9,e:10,t:"Comité de contratações",k:"reuniao",loc:"Sala Tejo",who:["Carla Dias","Sofia Melo"]},
  {id:8,day:23,s:9.5,e:11,t:"Onboarding — sessão de boas-vindas",k:"formacao",loc:"Sala Douro",who:["Ana Reis"]},
  {id:9,day:23,s:16,e:17,t:"1:1 com Zain Franci",k:"reuniao",loc:"Sala Minho",who:["Zain Franci"]},
  {id:10,day:24,s:11,e:12,t:"Conversa de desempenho H1",k:"reuniao",loc:"Sala Tejo",who:["Rui Pinto"]},
  {id:11,day:24,s:15,e:16.5,t:"Plano de férias Q3",k:"reuniao",loc:"Sala Douro",who:["Tomás Jervell","Carla Dias"]},
  {id:12,day:25,s:10,e:11,t:"Entrevista — Analista de dados",k:"entrevista",loc:"Videochamada",who:["Sofia Melo"]},
  {id:13,day:27,s:9.5,e:10.5,t:"Kickoff do inquérito de clima",k:"reuniao",loc:"Sala Tejo",who:["Sofia Melo"]},
  {id:14,day:28,s:14,e:15,t:"Triagem de candidaturas QA",k:"entrevista",loc:"Sala Minho",who:["Hugo Montenegro"]},
];
// multi-day items: ONE entry with from/to, never one row per day
const CL_SPANS=[
  {id:200,from:22,to:24,t:"Ana Reis — férias",k:"ausencia",who:["Ana Reis"]},
  {id:201,from:27,to:31,t:"Zain Franci — férias",k:"ausencia",who:["Zain Franci"]},
  {id:202,from:26,to:26,t:"Feriado municipal",k:"pessoal",who:[]},
  {id:203,from:20,to:23,t:"Formação de segurança",k:"formacao",who:["Toda a equipa"]},
  // tarefas: a barra vai do arranque ao prazo; o prazo é o único ponto que interessa cumprir
  {id:210,from:21,to:28,t:"Rever candidaturas QA",k:"tarefa",who:["Hugo Montenegro"],prazo:28,pct:40},
  {id:211,from:23,to:31,t:"Plano de férias Q3",k:"tarefa",who:["Tomás Jervell"],prazo:31,pct:15},
];
const clSpansOn=d=>CL_SPANS.filter(s=>d>=s.from&&d<=s.to);

// organisation signals — NEVER rendered one chip per person; always aggregated per day
const CL_PEOPLE=["Ana Reis","Rui Pinto","Carla Dias","Sofia Melo","Zain Franci","Tomás Jervell","Mira Mango","João Alves","Beatriz Nunes","Paulo Sá","Inês Cardoso","Miguel Faria"];
const CL_SIGNALS={
  20:{aniversarios:["Mira Mango"],ausentes:["Ana Reis","Paulo Sá","Inês Cardoso"]},
  21:{ausentes:["Ana Reis","Paulo Sá","Inês Cardoso","Miguel Faria"]},
  22:{aniversarios:["João Alves","Beatriz Nunes"],ausentes:["Ana Reis","Paulo Sá","Inês Cardoso","Miguel Faria","Zain Franci"]},
  23:{ausentes:["Ana Reis","Zain Franci"]},
  24:{aniversarios:["Sofia Melo"],ausentes:["Zain Franci"]},
  26:{feriado:"Feriado municipal"},
  27:{aniversarios:["Rui Pinto","Carla Dias","Tomás Jervell"],ausentes:["Mira Mango","João Alves"]},
  28:{ausentes:["Mira Mango"]},
};
const clSigText=g=>{if(!g)return null;const p=[];
  if(g.feriado)p.push(g.feriado);
  if(g.aniversarios&&g.aniversarios.length)p.push(g.aniversarios.length+(g.aniversarios.length===1?" aniversário":" aniversários"));
  if(g.ausentes&&g.ausentes.length)p.push(g.ausentes.length+(g.ausentes.length===1?" ausente":" ausentes"));
  return p.length?p.join(" · "):null;};
const CL_H0=7,CL_H1=21,CL_ROW=56;
const clTime=v=>{const h=Math.floor(v),m=Math.round((v-h)*60);return String(h).padStart(2,"0")+":"+String(m).padStart(2,"0");};

// week containing `day` of July 2026 — 1 Jul 2026 is a Wednesday
const clWeekday=day=>((day+1)%7+7)%7; // 0=Mon
const clWeekStart=day=>day-clWeekday(day);

function ClEvent({e,style,onOpen,compact}){
  const c=CL_TONE[CL_KIND[e.k].tone];
  return <div onClick={ev=>{ev.stopPropagation();onOpen(e);}} title={e.t}
    style={{position:"absolute",...style,background:"var(--ui-surface)",border:"1px solid var(--ui-border)",borderLeft:"3px solid "+c,borderRadius:"var(--ui-r-sm)",padding:compact?"3px 7px":"6px 8px",cursor:"pointer",overflow:"hidden",boxShadow:"var(--ui-elev-1)"}}>
    <div style={{fontSize:"var(--ui-fs-xs)",fontWeight:600,lineHeight:1.25,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{e.t}</div>
    {!compact&&<div className="muted" style={{fontSize:"var(--ui-fs-xs)",marginTop:2,fontVariantNumeric:"tabular-nums"}}>{clTime(e.s)}–{clTime(e.e)}</div>}
  </div>;
}

// lay overlapping events side by side
function clLanes(items){
  const sorted=items.slice().sort((a,b)=>a.s-b.s||a.e-b.e);
  const out=[];let cluster=[],endMax=-1;
  const flush=()=>{if(!cluster.length)return;
    const lanes=[];
    cluster.forEach(ev=>{let li=lanes.findIndex(l=>l[l.length-1].e<=ev.s);if(li<0){lanes.push([ev]);li=lanes.length-1;}else lanes[li].push(ev);ev.__lane=li;});
    cluster.forEach(ev=>out.push({ev,lane:ev.__lane,lanes:lanes.length}));
    cluster=[];endMax=-1;};
  sorted.forEach(ev=>{if(cluster.length&&ev.s>=endMax)flush();cluster.push(ev);endMax=Math.max(endMax,ev.e);});
  flush();return out;
}

function ClDetail({e,onClose}){
  if(!e)return null;
  const k=CL_KIND[e.k];
  return <UIDrawer open width={440} onClose={onClose}
    header={<UIPill tone={k.tone} dot>{k.label}</UIPill>}
    footer={<React.Fragment><div className="spring"/><UIButton variant="ghost" onClick={onClose}>Fechar</UIButton><UIButton onClick={onClose}>Abrir evento</UIButton></React.Fragment>}>
      <div style={{display:"flex",flexDirection:"column",gap:20}}>
        <div>
          <div style={{fontSize:"var(--ui-fs-h2)",fontWeight:600,letterSpacing:"var(--ui-ls-h2)",lineHeight:1.25}}>{e.t}</div>
          <div className="muted" style={{marginTop:8,fontSize:"var(--ui-fs-body)"}}>{e.k==="tarefa"?"Prazo a "+e.prazo+" de julho · "+(e.pct||0)+"% concluído":e.from!=null?(e.from===e.to?e.from+" de julho · dia inteiro":e.from+" a "+e.to+" de julho · "+(e.to-e.from+1)+" dias"):e.day+" de julho"+(e.s!=null?" · "+clTime(e.s)+" – "+clTime(e.e):"")}</div>
        </div>
        <div style={{display:"grid",gridTemplateColumns:"96px minmax(0,1fr)",gap:"12px 14px",alignItems:"center",fontSize:"var(--ui-fs-sm)"}}>
          {e.loc&&<React.Fragment><span className="muted">Local</span><span>{e.loc}</span></React.Fragment>}
          {e.who&&<React.Fragment><span className="muted">Participantes</span>
            <div className="row" style={{gap:8,flexWrap:"wrap"}}>{e.who.map(n=><span key={n} className="row" style={{gap:8,background:"var(--ui-surface-2)",borderRadius:999,padding:"3px 10px 3px 3px"}}><UIAvatar name={n} size="xs"/><span>{n}</span></span>)}</div>
          </React.Fragment>}
        </div>
      </div>
  </UIDrawer>;
}

function ClWeekGrid({days,onOpen,onSignal,kinds}){
  const cols="56px repeat("+days.length+",minmax(0,1fr))";
  const vis=k=>!kinds||kinds.includes(k);
  const hours=[];for(let h=CL_H0;h<=CL_H1;h++)hours.push(h);
  const sigs=days.map(d=>clSigText(CL_SIGNALS[d]));
  const hasSig=sigs.some(Boolean)&&vis("org");
  return <div style={{flex:1,minHeight:0,display:"flex",flexDirection:"column"}}>
    <div style={{display:"grid",gridTemplateColumns:cols,borderBottom:"1px solid var(--ui-border)",background:"var(--ui-surface)",flexShrink:0}}>
      <div/>
      {days.map((d,i)=>{const today=d===CL_TODAY.day;
        return <div key={i} style={{padding:"10px 8px",textAlign:"center",borderLeft:"1px solid var(--ui-divider)"}}>
          <div className="muted" style={{fontSize:"var(--ui-fs-xs)",fontWeight:600,letterSpacing:"0.06em",textTransform:"uppercase"}}>{CL_WD[clWeekday(d)]}</div>
          <div style={{marginTop:4,display:"flex",justifyContent:"center"}}>
            <span style={{width:32,height:32,borderRadius:999,display:"flex",alignItems:"center",justifyContent:"center",fontWeight:today?700:500,fontSize:"var(--ui-fs-body)",background:today?"var(--ui-accent)":"transparent",color:today?"var(--ui-on-accent)":"var(--ui-text)"}}>{d>0&&d<=31?d:""}</span>
          </div>
        </div>;})}
    </div>
    {(()=>{const inWeek=CL_SPANS.filter(s=>vis(s.k)&&days.some(d=>d>=s.from&&d<=s.to));
      if(!inWeek.length)return null;
      const first=days[0],last=days[days.length-1];
      return <div style={{display:"grid",gridTemplateColumns:cols,borderBottom:"1px solid var(--ui-border)",background:"var(--ui-surface-2)"}}>
        <div/>
        <div style={{gridColumn:"2 / -1",padding:"6px 0",display:"flex",flexDirection:"column",gap:4}}>
          {inWeek.map(s=>{
            const a=Math.max(s.from,first), b=Math.min(s.to,last);
            const startCol=days.indexOf(a), spanCols=b-a+1;
            const cutL=s.from<first, cutR=s.to>last;
            const tone=CL_TONE[CL_KIND[s.k].tone];
            return <div key={s.id} style={{display:"grid",gridTemplateColumns:"repeat("+days.length+",1fr)"}}>
              <div onClick={()=>onOpen&&onOpen(s)} title={s.k==="tarefa"?s.t+" · prazo "+s.prazo+" de julho ("+(s.pct||0)+"%)":s.t+" · "+s.from+" a "+s.to+" de julho"}
                style={{gridColumn:(startCol+1)+" / span "+spanCols,margin:"0 3px",padding:"4px 10px",cursor:"pointer",
                  background:s.k==="tarefa"?"transparent":"var(--ui-"+CL_KIND[s.k].tone+"-bg)",
                  border:s.k==="tarefa"?"1px dashed "+tone:"none",
                  color:tone,
                  borderLeft:cutL?(s.k==="tarefa"?"1px dashed "+tone:"none"):"3px solid "+tone,
                  borderRadius:(cutL?"0":"var(--ui-r-sm)")+" "+(cutR?"0":"var(--ui-r-sm)")+" "+(cutR?"0":"var(--ui-r-sm)")+" "+(cutL?"0":"var(--ui-r-sm)"),
                  fontSize:"var(--ui-fs-xs)",fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",
                  display:"flex",alignItems:"center",gap:6}}>
                {cutL&&<span style={{opacity:0.6}}>◂</span>}
                <span style={{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis"}}>{s.t}</span>
                {s.k==="tarefa"&&s.pct!=null&&!cutR&&<span style={{fontVariantNumeric:"tabular-nums",opacity:0.75}}>{s.pct}%</span>}
                {s.k==="tarefa"&&!cutR&&<span title={"Prazo: "+s.prazo+" de julho"} style={{width:6,height:6,borderRadius:999,background:tone,flexShrink:0}}/>}
                {cutR&&<span style={{opacity:0.6}}>▸</span>}
              </div>
            </div>;})}
        </div>
      </div>;})()}
    {hasSig&&<div style={{display:"grid",gridTemplateColumns:cols,borderBottom:"1px solid var(--ui-border)",background:"var(--ui-surface-2)"}}>
      <div className="muted" style={{fontSize:"var(--ui-fs-xs)",padding:"8px",textAlign:"right"}}>Equipa</div>
      {days.map((d,i)=>{const txt=sigs[i];
        return <div key={i} style={{borderLeft:"1px solid var(--ui-divider)",padding:6,minHeight:34}}>
          {txt&&<div onClick={()=>onSignal(d)} title={txt} style={{cursor:"pointer",fontSize:"var(--ui-fs-xs)",fontWeight:500,color:"var(--ui-text-2)",padding:"4px 8px",borderRadius:999,background:"var(--ui-surface)",border:"1px solid var(--ui-border)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{txt}</div>}
        </div>;})}
    </div>}
    <div style={{flex:1,minHeight:0,overflow:"auto",display:"flex",alignItems:"stretch"}}>
      <div style={{flex:1,display:"grid",gridTemplateColumns:cols,position:"relative",minHeight:"100%"}}>
        <div style={{display:"grid",gridTemplateRows:"repeat("+hours.length+",minmax("+CL_ROW+"px,1fr))"}}>{hours.map(h=><div key={h} style={{position:"relative"}}>
          <span className="muted" style={{position:"absolute",top:-7,right:8,fontSize:"var(--ui-fs-xs)",fontVariantNumeric:"tabular-nums",background:"var(--ui-surface)",padding:"0 2px"}}>{h>CL_H0?String(h).padStart(2,"0")+":00":""}</span>
        </div>)}</div>
        {days.map((d,i)=>{const items=CL_EV.filter(e=>e.day===d&&vis(e.k));const laid=clLanes(items);const today=d===CL_TODAY.day;
          return <div key={i} style={{position:"relative",display:"grid",gridTemplateRows:"repeat("+hours.length+",minmax("+CL_ROW+"px,1fr))",borderLeft:"1px solid var(--ui-divider)",background:today?"var(--ui-surface-2)":"transparent"}}>
            {hours.map(h=><div key={h} style={{borderTop:h>CL_H0?"1px solid var(--ui-divider)":"none"}}/>)}
            {laid.map(({ev,lane,lanes})=><ClEvent key={ev.id} e={ev} onOpen={onOpen}
              compact={(ev.e-ev.s)<0.75}
              style={{zIndex:1+lane,top:"calc("+((ev.s-CL_H0)/hours.length*100)+"% + 1px)",height:"calc("+((ev.e-ev.s)/hours.length*100)+"% - 3px)",left:"calc("+(lanes>1?lane*(24/(lanes>2?lanes-1:1)):0)+"% + 3px)",width:"calc("+(lanes>1?76:100)+"% - 6px)"}}/>)}
            {today&&<div style={{position:"absolute",left:0,right:0,top:((CL_NOW-CL_H0)/hours.length*100)+"%",height:0,borderTop:"2px solid var(--ui-danger)",zIndex:2}}>
              <span style={{position:"absolute",left:-4,top:-4,width:8,height:8,borderRadius:999,background:"var(--ui-danger)"}}/>
            </div>}
          </div>;})}
      </div>
    </div>
  </div>;
}

function ClMonthGrid({onOpen,onDay,onSignal,kinds}){
  const vis=k=>!kinds||kinds.includes(k);
  const first=1,offset=clWeekday(1); // 1 Jul 2026 = Wednesday → index 2
  const cells=Array.from({length:35},(_,i)=>i-offset+1);
  return <div style={{flex:1,minHeight:0,overflow:"auto",padding:16,display:"flex"}}>
    <div style={{flex:1,display:"grid",gridTemplateColumns:"repeat(7,minmax(0,1fr))",gridTemplateRows:"auto repeat(5,minmax(128px,1fr))",gap:6}}>
      {CL_WD.map(d=><div key={d} className="muted" style={{textAlign:"center",fontSize:"var(--ui-fs-sm)",fontWeight:600,padding:"4px 0"}}>{d}</div>)}
      {cells.map((d,i)=>{const valid=d>=1&&d<=31;const items=valid?CL_EV.filter(e=>e.day===d&&vis(e.k)):[];const spans=valid?clSpansOn(d).filter(s=>vis(s.k)):[];const sig=valid&&vis("org")?clSigText(CL_SIGNALS[d]):null;
        // orçamento por célula: barras multi-dia e sinal contam; o resto dos eventos vai para "+N mais"
        const maxItems=Math.max(0,3-spans.length-(sig?1:0));
        const shown=items.slice(0,maxItems);const resto=items.length-shown.length;
        return <div key={i} onClick={()=>valid&&onDay(d)} style={{minHeight:0,overflow:"hidden",borderRadius:"var(--ui-r-sm)",border:"1px solid var(--ui-divider)",padding:8,background:valid?"var(--ui-surface)":"transparent",opacity:valid?1:0.35,display:"flex",flexDirection:"column",gap:4,cursor:valid?"pointer":"default"}}>
          {valid&&<React.Fragment>
            <span style={{fontWeight:d===CL_TODAY.day?700:500,fontSize:"var(--ui-fs-sm)",width:24,height:24,display:"flex",alignItems:"center",justifyContent:"center",borderRadius:999,background:d===CL_TODAY.day?"var(--ui-accent)":"transparent",color:d===CL_TODAY.day?"var(--ui-on-accent)":"var(--ui-text)",flexShrink:0}}>{d}</span>
            {spans.map(s=>{const tone=CL_TONE[CL_KIND[s.k].tone];const ini=d===s.from,fim=d===s.to;const rotula=ini||clWeekday(d)===0;
              return <div key={s.id} onClick={ev=>{ev.stopPropagation();onOpen&&onOpen(s);}} title={s.t+" · "+s.from+" a "+s.to+" de julho"}
                style={{margin:"0 -8px",padding:"2px 8px",height:18,boxSizing:"border-box",flexShrink:0,lineHeight:"14px",cursor:"pointer",background:"var(--ui-"+CL_KIND[s.k].tone+"-bg)",color:tone,
                  borderLeft:ini?"3px solid "+tone:"none",
                  borderRadius:(ini?"var(--ui-r-sm)":"0")+" "+(fim?"var(--ui-r-sm)":"0")+" "+(fim?"var(--ui-r-sm)":"0")+" "+(ini?"var(--ui-r-sm)":"0"),
                  fontSize:"var(--ui-fs-xs)",fontWeight:600,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>
                {rotula?s.t:"\u00a0"}
              </div>;})}
            {sig&&<div onClick={ev=>{ev.stopPropagation();onSignal(d);}} title={sig} style={{cursor:"pointer",flexShrink:0,fontSize:"var(--ui-fs-xs)",color:"var(--ui-text-3)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{sig}</div>}
            {shown.map(e=><div key={e.id} onClick={ev=>{ev.stopPropagation();onOpen(e);}} title={e.t} style={{cursor:"pointer",flexShrink:0,fontSize:"var(--ui-fs-xs)",fontWeight:500,padding:"3px 8px",borderRadius:6,background:"var(--ui-surface-2)",borderLeft:"3px solid "+CL_TONE[CL_KIND[e.k].tone],whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{e.t}</div>)}
            {resto>0&&<span className="muted" style={{fontSize:"var(--ui-fs-xs)",cursor:"pointer",flexShrink:0}} onClick={ev=>{ev.stopPropagation();onDay(d);}}>+{resto} mais</span>}
          </React.Fragment>}
        </div>;})}
    </div>
  </div>;
}

function ClSignals({day,onClose}){
  if(day==null)return null;
  const g=CL_SIGNALS[day]||{};
  const sec=(title,people,tone)=>people&&people.length?<div>
    <div className="row" style={{marginBottom:8}}><span style={{fontWeight:600,fontSize:"var(--ui-fs-sm)"}}>{title}</span><div className="spring"/><UIPill tone={tone}>{people.length}</UIPill></div>
    <div style={{display:"flex",flexDirection:"column"}}>{people.map(n=><div key={n} className="row" style={{gap:10,padding:"8px 0",borderBottom:"1px solid var(--ui-divider)"}}>
      <UIAvatar name={n} size="xs"/><span style={{fontSize:"var(--ui-fs-sm)"}}>{n}</span></div>)}</div>
  </div>:null;
  const vazio=!g.feriado&&!(g.aniversarios||[]).length&&!(g.ausentes||[]).length;
  return <UIDrawer open width={400} onClose={onClose} title={CL_WD[clWeekday(day)]+", "+day+" de julho"}>
      <div style={{display:"flex",flexDirection:"column",gap:24}}>
        {g.feriado&&<div style={{padding:"12px 16px",borderRadius:"var(--ui-r-md)",background:"var(--ui-surface-2)",fontSize:"var(--ui-fs-sm)",fontWeight:500}}>{g.feriado}</div>}
        {sec("Aniversários",g.aniversarios,"accent")}
        {sec("Ausentes",g.ausentes,"warning")}
        {vazio&&<UIEmptyState compact title="Nada a assinalar" description="Sem aniversários, ausências ou feriados neste dia."/>}
      </div>
  </UIDrawer>;
}

S.calendar=()=>{
  const [view,setView]=React.useState("semana");
  const [anchor,setAnchor]=React.useState(CL_TODAY.day);
  const [openId,setOpenId]=React.useState(null);
  const [sigDay,setSigDay]=React.useState(null);
  const [nova,setNova]=React.useState(false);
  const [modo,setModo]=React.useState("video");
  const [kinds,setKinds]=React.useState([...Object.keys(CL_KIND),"org"]);

  const start=clWeekStart(anchor);
  const days=Array.from({length:7},(_,i)=>start+i);
  const ev=CL_EV.concat(CL_SPANS).find(e=>e.id===openId)||null;
  const step=n=>setAnchor(a=>a+(view==="mes"?0:n*7));
  const range=view==="mes"?"Julho de 2026"
    :view==="agenda"?"Próximos dias"
    :(days[0]<1?1:days[0])+" – "+(days[6]>31?31:days[6])+" de "+CL_MONTHS[6];

  // Agenda: chronological, grouped by day — scales to any team size
  const agenda=(()=>{const out=[];for(let d=CL_TODAY.day;d<=31;d++){
    const items=CL_EV.filter(e=>e.day===d&&kinds.includes(e.k)).sort((a,b)=>a.s-b.s);
    // a multi-day item is listed once, on the first day it is visible, as a range
    const spans=CL_SPANS.filter(s=>kinds.includes(s.k)&&d===Math.max(s.from,CL_TODAY.day)&&s.to>=CL_TODAY.day);
    const sig=kinds.includes("org")?clSigText(CL_SIGNALS[d]):null;
    if(items.length||spans.length||sig)out.push({d,items,spans,sig});}
    return out;})();

  const filterChips=[...Object.entries(CL_KIND).map(([k,v])=>[k,v.label,CL_TONE[v.tone]]),["org","Equipa","var(--ui-text-3)"]];

  return <React.Fragment>
  <Head title="Calendário" desc="A tua agenda e os sinais da equipa" actions={<UIButton icon={<I d={P.plus} size={16}/>} onClick={()=>setNova(true)}>Novo evento</UIButton>}/>
  <UICard style={{padding:0,overflow:"hidden",flex:1,minHeight:0,display:"flex",flexDirection:"column"}}>
    <div className="row" style={{padding:"12px 16px",borderBottom:"1px solid var(--ui-divider)",gap:12,flexWrap:"wrap"}}>
      <UIButton size="sm" variant="outline" onClick={()=>setAnchor(CL_TODAY.day)}>Hoje</UIButton>
      {view==="semana"&&<div className="row" style={{gap:2}}>
        <span className="ico-btn" title="Semana anterior" onClick={()=>step(-1)}><I d={["m15 18-6-6 6-6"]} size={16}/></span>
        <span className="ico-btn" title="Semana seguinte" onClick={()=>step(1)}><I d={["m9 18 6-6-6-6"]} size={16}/></span>
      </div>}
      <span style={{fontWeight:600,minWidth:170}}>{range}</span>
      <div className="spring"/>
      <div className="row" style={{gap:8,flexWrap:"wrap"}}>
        {filterChips.map(([k,label,color])=>{const on=kinds.includes(k);
          return <span key={k} onClick={()=>setKinds(s=>on?s.filter(x=>x!==k):[...s,k])} className="row" style={{gap:8,cursor:"pointer",padding:"8px 12px",borderRadius:999,fontSize:"var(--ui-fs-sm)",fontWeight:500,background:on?"var(--ui-surface-2)":"transparent",color:on?"var(--ui-text)":"var(--ui-text-3)",border:"1px solid "+(on?"transparent":"var(--ui-border)")}}>
            <span style={{width:8,height:8,borderRadius:999,background:on?color:"var(--ui-border-2)"}}/>{label}</span>;})}
      </div>
      <UITabs variant="pill" value={view} onChange={setView} items={[{value:"semana",label:"Semana"},{value:"mes",label:"Mês"},{value:"agenda",label:"Agenda"}]}/>
    </div>

    {view==="semana"&&<ClWeekGrid days={days} kinds={kinds} onOpen={e=>setOpenId(e.id)} onSignal={setSigDay}/>}
    {view==="mes"&&<ClMonthGrid kinds={kinds} onOpen={e=>setOpenId(e.id)} onSignal={setSigDay} onDay={d=>{setAnchor(d);setView("semana");}}/>}
    {view==="agenda"&&<div style={{flex:1,minHeight:0,overflow:"auto",display:"flex",flexDirection:"column"}}>
      {agenda.length?agenda.map(({d,items,spans,sig})=><div key={d}>
        <div className="row" style={{gap:10,padding:"12px 16px",background:"var(--ui-surface-2)",borderBottom:"1px solid var(--ui-divider)"}}>
          <span style={{fontWeight:600,fontSize:"var(--ui-fs-sm)"}}>{CL_WD[clWeekday(d)]}, {d} de julho</span>
          {d===CL_TODAY.day&&<UIPill tone="accent">Hoje</UIPill>}
          <div className="spring"/>
          {sig&&<span onClick={()=>setSigDay(d)} className="muted" style={{fontSize:"var(--ui-fs-sm)",cursor:"pointer"}}>{sig}</span>}
        </div>
        {(spans||[]).map(s=><div key={s.id} onClick={()=>setOpenId(s.id)} className="tk-row" style={{display:"grid",gridTemplateColumns:"104px 4px minmax(0,1fr) repeat(2,140px)",gap:16,alignItems:"center",padding:"12px 16px",borderBottom:"1px solid var(--ui-divider)",cursor:"pointer"}}>
          <span className="muted" style={{fontSize:"var(--ui-fs-sm)"}}>{s.k==="tarefa"?"Prazo":s.from===s.to?"Dia inteiro":s.to-s.from+1+" dias"}</span>
          <span style={{width:4,height:26,borderRadius:2,background:CL_TONE[CL_KIND[s.k].tone]}}/>
          <span style={{fontWeight:500,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{s.t}</span>
          <span className="muted" style={{fontSize:"var(--ui-fs-sm)"}}>{s.k==="tarefa"?s.prazo+" de julho · "+(s.pct||0)+"%":s.from+" a "+s.to+" de julho"}</span>
          <span><UIPill tone={CL_KIND[s.k].tone} dot>{CL_KIND[s.k].label}</UIPill></span>
        </div>)}
        {items.map(e=><div key={e.id} onClick={()=>setOpenId(e.id)} className="tk-row" style={{display:"grid",gridTemplateColumns:"104px 4px minmax(0,1fr) repeat(2,140px)",gap:16,alignItems:"center",padding:"12px 16px",borderBottom:"1px solid var(--ui-divider)",cursor:"pointer"}}>
          <span className="muted" style={{fontSize:"var(--ui-fs-sm)",fontVariantNumeric:"tabular-nums"}}>{clTime(e.s)}–{clTime(e.e)}</span>
          <span style={{width:4,height:26,borderRadius:2,background:CL_TONE[CL_KIND[e.k].tone]}}/>
          <span style={{fontWeight:500,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{e.t}</span>
          <span className="muted row" style={{gap:8,fontSize:"var(--ui-fs-sm)",minWidth:0}}><I d={e.loc==="Videochamada"?P.chat:P.grid} size={14}/><span style={{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{e.loc}</span></span>
          <span className="row" style={{gap:6}}>{e.who.slice(0,3).map((n,ix)=><span key={n} style={{marginLeft:ix?-8:0,boxShadow:"0 0 0 2px var(--ui-surface)",borderRadius:"50%",display:"inline-flex"}}><UIAvatar name={n} size="xs"/></span>)}</span>
        </div>)}
        {!items.length&&<div className="muted" style={{padding:"12px 16px",fontSize:"var(--ui-fs-sm)",borderBottom:"1px solid var(--ui-divider)"}}>Sem eventos marcados.</div>}
      </div>):<div className="muted" style={{padding:"28px 18px",fontSize:"var(--ui-fs-sm)",textAlign:"center"}}>Nada agendado até ao fim do mês.</div>}
    </div>}
  </UICard>

  <ClDetail e={ev} onClose={()=>setOpenId(null)}/>
  <ClSignals day={sigDay} onClose={()=>setSigDay(null)}/>

  <UIModal open={nova} onClose={()=>setNova(false)} title="Novo evento" width={560}
    footer={<div className="row" style={{gap:8}}><div className="spring"/><UIButton variant="ghost" onClick={()=>setNova(false)}>Cancelar</UIButton><UIButton onClick={()=>setNova(false)}>Criar evento</UIButton></div>}>
    <div style={{display:"flex",flexDirection:"column",gap:14}}>
      <UIInput label="Título" placeholder="Assunto do evento"/>
      <div style={{display:"grid",gridTemplateColumns:"1.2fr 1fr 1fr",gap:12}}>
        <UIInput label="Dia" placeholder="24/07"/><UIInput label="Início" placeholder="10:00"/><UIInput label="Fim" placeholder="11:00"/>
      </div>
      <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12}}>
        <UISelect label="Tipo" options={Object.values(CL_KIND).map(v=>v.label)}/>
        <UISelect label="Repetição" options={["Não repete","Todas as semanas","Todos os meses"]}/>
      </div>
      <div>
        <div style={{fontSize:"var(--ui-fs-sm)",fontWeight:500,marginBottom:8}}>Onde</div>
        <div className="row" style={{gap:8,marginBottom:10,flexWrap:"wrap"}}>
          {[["video","Videochamada",P.chat],["sala","Sala",P.grid],["externo","Local externo",P.pin||P.grid]].map(([k,l,ic])=>
            <span key={k} onClick={()=>setModo(k)} className="row" style={{gap:8,cursor:"pointer",padding:"8px 12px",borderRadius:999,fontSize:"var(--ui-fs-sm)",fontWeight:500,border:"1px solid "+(modo===k?"var(--ui-text)":"var(--ui-border)"),background:modo===k?"var(--ui-text)":"var(--ui-surface)",color:modo===k?"var(--ui-surface)":"var(--ui-text-2)"}}>
              <I d={ic} size={15}/>{l}</span>)}
        </div>
        {modo==="video"&&<div className="row" style={{gap:10,padding:"12px 14px",borderRadius:"var(--ui-r-md)",background:"var(--ui-surface-2)",fontSize:"var(--ui-fs-sm)"}}>
          <I d={P.chat} size={16} c="var(--ui-text-3)"/><span style={{flex:1}}>Sala de vídeo criada automaticamente</span><UIButton size="sm" variant="ghost" onClick={e=>{e.preventDefault();if(navigator.clipboard)navigator.clipboard.writeText("https://meet.xcope.ai/"+Math.random().toString(36).slice(2,9));}}>Copiar link</UIButton></div>}
        {modo==="sala"&&<UISelect options={["Sala Douro (8 lugares)","Sala Tejo (12 lugares)","Sala Minho (4 lugares)","Auditório (40 lugares)"]}/>}
        {modo==="externo"&&<UIInput placeholder="Morada ou indicação do local"/>}
      </div>
      <UIInput label="Convidados" leading={<I d={P.users} size={15}/>} placeholder="Pessoas, equipas ou departamentos"/>
      <UIInput label="Notas" placeholder="Agenda da reunião, links, preparação…"/>
    </div>
  </UIModal>
  </React.Fragment>;
};
