/* FrontCall Hub — recorrência: Agenda v2 (fila "A encaixar" + ocorrências projetadas),
   PlansScreen, PlanCard (detalhe do cliente) e nudge do dashboard. */

/* ---------- helpers ---------- */
function schedAllOccs(kindF) {
  const S = window.FCSched, D = window.FCData;
  const real = D.appointments.concat(S.extras).map((a) => ({
    key: "r:" + a.id, real: a, planId: a.planId || null,
    plan: a.planId ? D.plans.find((p) => p.id === a.planId) : null,
    clientId: a.clientId, name: a.name, address: a.address, phone: a.phone,
    kind: a.kind, service: a.service, price: a.price, cleaner: a.cleaner,
    dObj: S.parsePt(a.date), date: a.date, time: a.time, window: a.window,
    status: a.status, virtual: false, fitted: !!a.fitted, id: a.id,
  }));
  const virt = S.occurrences().map((o) => ({ ...o, kind: "job", status: "projected" }));
  let items = real.concat(virt).filter((x) => x.dObj && x.dObj >= S.TODAY && x.dObj <= S.addDays(S.TODAY, S.horizon));
  if (kindF && kindF !== "all") items = items.filter((x) => x.kind === kindF);
  items.sort((a, b) => a.dObj - b.dObj || S.timeMin(a.time) - S.timeMin(b.time));
  return items;
}
function schedNextOf(planId, n = 3) {
  return schedAllOccs().filter((x) => x.planId === planId && !x.skipped).slice(0, n);
}

function RecurChip({ plan, moved }) {
  if (moved) return <Badge tone="warning">Fora do ritmo</Badge>;
  if (!plan) return null;
  return (
    <Badge tone="brand" style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
      <Icon name="repeat" size={11} color="currentColor" />{window.FCSched.freqLabel(plan)}
    </Badge>
  );
}

/* ---------- fila "A encaixar" (compacta — lista única, expande se tiver muitos) ---------- */
function FitQueue({ queue, go, onFit }) {
  const S = window.FCSched;
  const [all, setAll] = React.useState(false);
  const MAX = 3;
  const shown = all ? queue : queue.slice(0, MAX);
  return (
    <div>
      <SectionLabel>A encaixar — sem dia fixo</SectionLabel>
      <Card inset>
        {shown.map((q, i) => {
          const tone = q.overdue ? "var(--danger-600)" : "var(--warm-600)";
          return (
            <div key={q.plan.id} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 14px", borderBottom: i < shown.length - 1 || (!all && queue.length > MAX) ? "1px solid var(--border-subtle)" : "none" }}>
              <div onClick={() => go("client", q.client.id)} style={{ display: "flex", alignItems: "center", gap: 11, flex: 1, minWidth: 0, cursor: "pointer" }}>
                <Avatar name={q.client.name} size={36} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: "var(--fw-semibold)", color: "var(--text-strong)", fontSize: "var(--fs-sm)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{q.client.name}</div>
                  <div style={{ fontSize: "var(--fs-caption)", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    <span style={{ fontWeight: "var(--fw-bold)", color: tone }}>{q.label}</span>
                    <span style={{ color: "var(--text-muted)" }}> · {S.freqLabel(q.plan)} · {q.plan.service}</span>
                  </div>
                </div>
              </div>
              <Button size="sm" onClick={() => onFit(q)} style={{ flex: "none" }}>Encaixar</Button>
            </div>
          );
        })}
        {!all && queue.length > MAX && (
          <button onClick={() => setAll(true)} style={{ display: "block", width: "100%", border: "none", background: "none", padding: "11px 14px", color: "var(--text-link)", fontSize: "var(--fs-sm)", fontWeight: "var(--fw-semibold)", cursor: "pointer", fontFamily: "var(--font-sans)", textAlign: "center" }}>
            Ver todos ({queue.length})
          </button>
        )}
      </Card>
    </div>
  );
}

/* ============ AGENDA v2 ============ */
function AgendaScreenV2({ go }) {
  const S = window.FCSched, D = window.FCData;
  const [, force] = React.useState(0);
  const bump = () => force((x) => x + 1);
  const [kindF, setKindF] = React.useState("all");
  const [sheet, setSheet] = React.useState(null); // {kind, ...}

  const queue = S.queue();
  const items = schedAllOccs(kindF);
  const all = schedAllOccs("all");
  const groups = {};
  items.forEach((x) => { (groups[x.date] = groups[x.date] || []).push(x); });
  const pending = D.appointments.concat(S.extras).filter((a) => a.status === "pending").length;

  const confirm = (occ) => { occ.real.status = "confirmed"; bump(); };

  return (
    <div style={{ padding: "12px 16px 24px", display: "flex", flexDirection: "column", gap: 18 }}>
      <SegmentedTabs value={kindF} onChange={setKindF} size="sm" style={{ width: "100%" }} items={[
        { value: "all", label: "Tudo", count: all.length },
        { value: "job", label: "Serviços", count: all.filter((a) => a.kind === "job").length },
        { value: "estimate", label: "Orçamentos", count: all.filter((a) => a.kind === "estimate").length },
      ]} />

      {queue.length > 0 && <FitQueue queue={queue} go={go} onFit={(q) => setSheet({ kind: "fit", q })} />}

      {pending > 0 && (
        <div style={{ background: "var(--warm-bg)", border: "1px solid color-mix(in oklab, var(--warm-500) 30%, white)", borderRadius: "var(--radius-md)", padding: "12px 16px", display: "flex", alignItems: "center", gap: 10 }}>
          <Icon name="clock" size={18} color="var(--warm-600)" />
          <span style={{ fontSize: "var(--fs-sm)", color: "var(--text-primary)", fontWeight: "var(--fw-medium)" }}>{pending} visita(s) aguardando sua confirmação</span>
        </div>
      )}

      {Object.keys(groups).map((date) => (
        <div key={date}>
          <SectionLabel>{date === S.fmt(S.TODAY) ? `Hoje · ${date}` : date}</SectionLabel>
          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
            {groups[date].map((occ) => {
              const ghostReal = !occ.virtual && (occ.status === "skipped" || occ.status === "canceled");
              if (occ.skipped || ghostReal) {
                const undo = () => {
                  if (occ.virtual) window.FCSched.unskip(occ);
                  else occ.real.status = occ.real.prevStatus || "confirmed";
                  bump();
                };
                return (
                  <div key={occ.key} style={{ display: "flex", alignItems: "center", gap: 10, padding: "11px 16px", borderRadius: "var(--radius-lg)", border: "1px dashed var(--border-default)", background: "var(--surface-sunken)" }}>
                    <Icon name={occ.status === "canceled" ? "x" : "skip-forward"} size={15} color="var(--text-faint)" />
                    <span style={{ flex: 1, fontSize: "var(--fs-sm)", color: "var(--text-muted)" }}><b>{occ.name}</b> — {occ.status === "canceled" ? "cancelada" : "pulada · volta no próximo ciclo"}</span>
                    <button onClick={undo} style={{ border: "none", background: "none", color: "var(--text-link)", fontSize: "var(--fs-caption)", fontWeight: "var(--fw-semibold)", cursor: "pointer", fontFamily: "var(--font-sans)" }}>Desfazer</button>
                  </div>
                );
              }
              return (
                <Card key={occ.key} interactive onClick={() => occ.virtual ? go("occ", occ.key) : go("job", occ.id)} style={{ padding: "14px 16px", ...(occ.virtual ? { borderStyle: "dashed", boxShadow: "none" } : {}) }}>
                  <div style={{ display: "flex", gap: 14 }}>
                    <div style={{ flex: "none", textAlign: "center", minWidth: 56 }}>
                      <div style={{ fontFamily: "var(--font-mono)", fontWeight: "var(--fw-bold)", color: "var(--text-strong)", fontSize: "var(--fs-body)" }}>{occ.time.replace(" ", "")}</div>
                      <div style={{ fontSize: 10.5, color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: "var(--ls-wide)" }}>{occ.window}</div>
                    </div>
                    <div style={{ width: 1, background: "var(--border-subtle)" }} />
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8 }}>
                        <span style={{ fontWeight: "var(--fw-semibold)", color: "var(--text-strong)", fontSize: "var(--fs-body)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }}>{occ.name}</span>
                        <span style={{ display: "inline-flex", gap: 6, flex: "none" }}>
                          {occ.virtual
                            ? <RecurChip plan={occ.plan} moved={occ.moved} />
                            : (window.FCJobs && window.FCJobs[occ.id] && window.FCJobs[occ.id].stage !== "scheduled" && window.jobStatusBadge)
                              ? window.jobStatusBadge(window.FCJobs[occ.id].stage, occ.kind)
                              : occ.status === "confirmed"
                                ? <Badge tone="success" dot>Confirmada</Badge>
                                : <Badge tone="warning" dot>Pendente</Badge>}
                        </span>
                      </div>
                      <div style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)", marginTop: 3, display: "flex", alignItems: "center", gap: 6, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }}>
                        <Icon name={occ.plan ? "repeat" : occ.kind === "estimate" ? "search" : "map-pin"} size={13} color="var(--text-faint)" />
                        {occ.plan ? `${window.FCSched.freqLabel(occ.plan)} · ` : occ.kind === "estimate" ? "Orçamento · " : ""}{occ.service} · {occ.address}
                      </div>
                      {!occ.virtual && occ.status === "pending" && (
                        <div style={{ display: "flex", gap: 8, marginTop: 12 }}>
                          <Button size="sm" variant="primary" onClick={(e) => { e.stopPropagation(); confirm(occ); }} iconLeft={<Icon name="check" size={16} color="#fff" />}>Confirmar</Button>
                          <Button size="sm" variant="ghost" onClick={(e) => { e.stopPropagation(); setSheet({ kind: "resch", occ }); }} style={{ color: "var(--text-secondary)" }}>Remarcar</Button>
                        </div>
                      )}
                    </div>
                  </div>
                </Card>
              );
            })}
          </div>
        </div>
      ))}

      {sheet && sheet.kind === "fit" && <FitSheet q={sheet.q} onClose={() => setSheet(null)} onDone={bump} />}
      {sheet && sheet.kind === "resch" && <RescheduleSheet occ={sheet.occ} onClose={() => setSheet(null)} onDone={bump} />}
    </div>
  );
}

/* ============ detalhe de ocorrência projetada (mesmo padrão do detalhe de visita) ============ */
function OccurrenceScreen({ occKey, go }) {
  const S = window.FCSched;
  const [, force] = React.useState(0);
  const bump = () => force((x) => x + 1);
  const [sheet, setSheet] = React.useState(null); // "resch" | "plan"
  const [swap, setSwap] = React.useState(false);
  const [confirmSkip, setConfirmSkip] = React.useState(false);

  const occ = schedAllOccs().find((x) => x.key === occKey);
  if (!occ) {
    return (
      <EmptyState title="Visita não encontrada" description="Ela pode ter sido remarcada ou o plano mudou."
        art={<Icon name="calendar" size={28} color="var(--brand)" />}
        action={<Button variant="secondary" onClick={() => go("agenda")}>Voltar pra agenda</Button>} />
    );
  }
  const p = occ.plan;

  const actionRow = (icon, label, sub, onClick, tone, last) => (
    <button onClick={onClick} style={{ display: "flex", alignItems: "center", gap: 13, width: "100%", padding: "13px 16px", border: "none", borderBottom: last ? "none" : "1px solid var(--border-subtle)", background: "none", cursor: "pointer", textAlign: "left", fontFamily: "var(--font-sans)" }}>
      <div style={{ width: 36, height: 36, borderRadius: "var(--radius-md)", background: tone === "warm" ? "var(--warm-bg)" : "var(--surface-brand-subtle)", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}>
        <Icon name={icon} size={17} color={tone === "warm" ? "var(--warm-600)" : "var(--brand)"} />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: "var(--fs-body)", fontWeight: "var(--fw-semibold)", color: "var(--text-strong)" }}>{label}</div>
        {sub && <div style={{ fontSize: "var(--fs-micro)", color: "var(--text-muted)", marginTop: 1 }}>{sub}</div>}
      </div>
      <Icon name="chevron-right" size={16} color="var(--text-faint)" />
    </button>
  );

  return (
    <div style={{ padding: "16px 16px 28px", display: "flex", flexDirection: "column", gap: 16 }}>
      {/* cabeçalho da visita */}
      <Card>
        <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
          <Avatar name={occ.name} size={52} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: "var(--fs-h4)", fontWeight: "var(--fw-bold)", letterSpacing: "var(--ls-tight)", color: "var(--text-strong)" }}>{occ.name}</div>
            <div style={{ display: "flex", gap: 6, marginTop: 6, flexWrap: "wrap" }}>
              <RecurChip plan={p} moved={occ.moved} />
              {occ.skipped && <Badge tone="neutral">Pulada</Badge>}
            </div>
          </div>
        </div>
        <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 16 }}>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: "var(--fs-h3)", fontWeight: "var(--fw-bold)", letterSpacing: "var(--ls-tight)", color: "var(--text-strong)" }}>{occ.date} · {occ.time}</span>
        </div>
        <div style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)", marginTop: 4, display: "flex", alignItems: "center", gap: 6 }}>
          <Icon name="map-pin" size={13} color="var(--text-faint)" /> {occ.address}
        </div>
      </Card>

      {occ.skipped ? (
        <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "12px 14px", borderRadius: "var(--radius-md)", border: "1px dashed var(--border-default)", background: "var(--surface-sunken)" }}>
          <Icon name="skip-forward" size={16} color="var(--text-faint)" />
          <span style={{ flex: 1, fontSize: "var(--fs-sm)", color: "var(--text-muted)" }}>Pulada — volta no próximo ciclo, no ritmo normal.</span>
          <Button size="sm" variant="secondary" onClick={() => { S.unskip(occ); bump(); }}>Desfazer</Button>
        </div>
      ) : (
        <div style={{ display: "flex", gap: 8, alignItems: "flex-start", padding: "10px 13px", borderRadius: "var(--radius-md)", background: "var(--surface-brand-subtle)" }}>
          <Icon name="repeat" size={14} color="var(--brand)" style={{ marginTop: 1 }} />
          <span style={{ fontSize: "var(--fs-micro)", color: "var(--text-secondary)", lineHeight: 1.45 }}>Visita projetada do plano {S.freqLabel(p).toLowerCase()} — quando chegar a semana, ela vira um job de verdade com checklist e avisos.</span>
        </div>
      )}

      {/* detalhes */}
      <Card>
        <SectionLabel>Detalhes</SectionLabel>
        <KV k="Serviço" v={occ.service} />
        <KV k="Cleaner" v={occ.cleaner} />
        <KV k="Valor" v={<span style={{ color: "var(--brand)", fontWeight: "var(--fw-bold)" }}>${occ.price}</span>} />
      </Card>

      {/* ações */}
      {!occ.skipped && (
        <Card inset>
          {actionRow("calendar-clock", "Remarcar", "Só esta visita ou a série inteira", () => setSheet("resch"))}
          {!confirmSkip
            ? actionRow("skip-forward", "Pular esta visita", "Volta no próximo ciclo, no ritmo normal", () => setConfirmSkip(true), "warm")
            : (
              <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "13px 16px", borderBottom: "1px solid var(--border-subtle)" }}>
                <span style={{ flex: 1, fontSize: "var(--fs-sm)", color: "var(--text-primary)", fontWeight: "var(--fw-medium)" }}>Pular {occ.date}?</span>
                <Button size="sm" variant="secondary" onClick={() => setConfirmSkip(false)}>Voltar</Button>
                <Button size="sm" onClick={() => { S.skip(occ); setConfirmSkip(false); bump(); }}>Pular</Button>
              </div>
            )}
          {!swap
            ? actionRow("users", "Trocar cleaner", "Só nesta visita — a série não muda", () => setSwap(true), null, true)
            : (
              <div style={{ padding: "13px 16px" }}>
                <CleanerChips value={occ.cleaner} onChange={(n) => { S.setCleaner(occ, n); setSwap(false); bump(); }} />
              </div>
            )}
        </Card>
      )}

      {/* plano */}
      {p && (
        <Card>
          <SectionLabel action={
            <button onClick={() => setSheet("plan")} style={{ border: "none", background: "none", color: "var(--text-link)", fontSize: "var(--fs-caption)", fontWeight: "var(--fw-semibold)", cursor: "pointer", fontFamily: "var(--font-sans)" }}>Gerenciar</button>
          }>Plano de recorrência</SectionLabel>
          <div style={{ fontSize: "var(--fs-sm)", color: "var(--text-secondary)", display: "flex", alignItems: "center", gap: 7 }}>
            <Icon name="repeat" size={14} color="var(--text-faint)" />{S.planSub(p)} · {p.service}
          </div>
        </Card>
      )}

      <Button block size="lg" variant="secondary" onClick={() => go("client", occ.clientId)} iconLeft={<Icon name="user-round" size={18} color="var(--text-strong)" />}>Ver cliente</Button>

      {sheet === "resch" && <RescheduleSheet occ={occ} onClose={() => setSheet(null)} onDone={bump} />}
      {sheet === "plan" && <PlanSheet clientId={occ.clientId} onClose={() => setSheet(null)} onDone={bump} />}
    </div>
  );
}

/* ============ PLANOS (lista) ============ */
function PlansScreen({ go }) {
  const S = window.FCSched, D = window.FCData;
  const [, force] = React.useState(0);
  const bump = () => force((x) => x + 1);
  const [editClient, setEditClient] = React.useState(null);
  const [picking, setPicking] = React.useState(false);

  const plans = D.plans.filter((p) => p.status !== "cancelado");
  const noPlan = D.clients.filter((c) => c.relation === "ativo" && !S.planOf(c.id));

  const rightOf = (p) => {
    if (S.isPaused(p)) return <Badge tone="warning" dot>Pausado</Badge>;
    if (p.mode === "flex") {
      const q = S.queue().find((x) => x.plan.id === p.id);
      if (q) return <span style={{ fontSize: "var(--fs-caption)", fontWeight: "var(--fw-bold)", color: q.overdue ? "var(--danger-600)" : "var(--warm-600)" }}>{q.label}</span>;
      const next = p.scheduledNext && S.fromISO(p.scheduledNext) >= S.TODAY ? S.fmtShort(S.fromISO(p.scheduledNext)) : S.fmtShort(S.dueOf(p));
      return <span style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)" }}>próx. {next}</span>;
    }
    const nxt = schedNextOf(p.id, 1)[0];
    return nxt ? <span style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)" }}>próx. {S.fmtShort(nxt.dObj)}</span> : null;
  };

  return (
    <div style={{ padding: "16px 16px 28px", display: "flex", flexDirection: "column", gap: 18 }}>
      <div>
        <SectionLabel>Recorrências ativas · {plans.length}</SectionLabel>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {plans.map((p) => {
            const c = S.clientOf(p);
            return (
              <Card key={p.id} interactive onClick={() => setEditClient(p.clientId)} style={{ padding: "13px 14px" }}>
                <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                  <Avatar name={c.name} size={42} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: "var(--fw-semibold)", color: "var(--text-strong)", fontSize: "var(--fs-body)" }}>{c.name}</div>
                    <div style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)", marginTop: 2, display: "flex", alignItems: "center", gap: 5 }}>
                      <Icon name={p.mode === "fixo" ? "repeat" : "calendar-clock"} size={12} color="var(--text-faint)" />
                      {S.planSub(p)} · {p.service}
                    </div>
                  </div>
                  <div style={{ flex: "none", display: "flex", alignItems: "center", gap: 8 }}>
                    {rightOf(p)}
                    <Icon name="chevron-right" size={16} color="var(--text-faint)" />
                  </div>
                </div>
              </Card>
            );
          })}
        </div>
      </div>

      {!picking ? (
        <Button block variant="secondary" size="lg" onClick={() => setPicking(true)} iconLeft={<Icon name="plus" size={18} color="var(--text-strong)" />}>Novo plano</Button>
      ) : (
        <div>
          <SectionLabel action={<button onClick={() => setPicking(false)} style={{ border: "none", background: "none", color: "var(--text-muted)", fontSize: "var(--fs-caption)", cursor: "pointer", fontFamily: "var(--font-sans)" }}>fechar</button>}>Pra qual cliente?</SectionLabel>
          {noPlan.length === 0 ? (
            <Card><span style={{ fontSize: "var(--fs-sm)", color: "var(--text-muted)" }}>Todos os clientes ativos já têm plano. Cadastre um cliente novo em Clientes → +.</span></Card>
          ) : (
            <Card inset>
              {noPlan.map((c, i) => (
                <div key={c.id} onClick={() => { setPicking(false); setEditClient(c.id); }} style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 16px", borderBottom: i < noPlan.length - 1 ? "1px solid var(--border-subtle)" : "none", cursor: "pointer" }}>
                  <Avatar name={c.name} size={36} />
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: "var(--fw-semibold)", color: "var(--text-strong)", fontSize: "var(--fs-sm)" }}>{c.name}</div>
                    <div style={{ fontSize: "var(--fs-micro)", color: "var(--text-muted)" }}>{c.service} · {c.address}</div>
                  </div>
                  <Icon name="chevron-right" size={16} color="var(--text-faint)" />
                </div>
              ))}
            </Card>
          )}
        </div>
      )}

      {editClient && <PlanSheet clientId={editClient} onClose={() => setEditClient(null)} onDone={bump} />}
    </div>
  );
}

/* ============ card "Plano de limpeza" (detalhe do cliente) ============ */
function PlanCard({ clientId, go }) {
  const S = window.FCSched;
  const [, force] = React.useState(0);
  const bump = () => force((x) => x + 1);
  const [sheet, setSheet] = React.useState(null); // "plan" | {kind:"fit", q}
  const p = S.planOf(clientId);

  if (!p) {
    return (
      <Card>
        <SectionLabel>Plano de limpeza</SectionLabel>
        <div style={{ fontSize: "var(--fs-sm)", color: "var(--text-muted)", marginBottom: 12 }}>Cliente recorrente sem plano configurado — crie um pra ele entrar na agenda.</div>
        <Button block variant="secondary" onClick={() => setSheet("plan")} iconLeft={<Icon name="repeat" size={17} color="var(--text-strong)" />}>Criar plano</Button>
        {sheet === "plan" && <PlanSheet clientId={clientId} onClose={() => setSheet(null)} onDone={bump} />}
      </Card>
    );
  }

  const q = S.queue().find((x) => x.plan.id === p.id);
  const next = p.mode === "fixo" ? schedNextOf(p.id, 3) : [];

  return (
    <Card>
      <SectionLabel action={
        <button onClick={() => setSheet("plan")} style={{ border: "none", background: "none", color: "var(--text-link)", fontSize: "var(--fs-caption)", fontWeight: "var(--fw-semibold)", cursor: "pointer", fontFamily: "var(--font-sans)" }}>Gerenciar</button>
      }>Plano de limpeza</SectionLabel>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 4 }}>
        <Badge tone="brand" style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
          <Icon name={p.mode === "fixo" ? "repeat" : "calendar-clock"} size={11} color="currentColor" />
          {p.mode === "fixo" ? "Dia fixo" : "Flexível"}
        </Badge>
        {S.isPaused(p) && <Badge tone="warning" dot>Pausado até {S.fmtShort(S.fromISO(p.pausedUntil))}</Badge>}
      </div>
      <KV k="Frequência" v={S.planSub(p)} />
      <KV k="Serviço" v={`${p.service} · $${p.price}`} />
      <KV k="Cleaner" v={p.cleaner} />

      {p.mode === "fixo" && next.length > 0 && (
        <div style={{ marginTop: 12 }}>
          <div style={{ fontSize: "var(--fs-micro)", fontWeight: "var(--fw-bold)", letterSpacing: "var(--ls-eyebrow)", textTransform: "uppercase", color: "var(--text-muted)", marginBottom: 7 }}>Próximas</div>
          <div style={{ display: "flex", gap: 7, flexWrap: "wrap" }}>
            {next.map((o) => (
              <span key={o.key} style={{ fontSize: "var(--fs-caption)", fontWeight: "var(--fw-semibold)", color: o.moved ? "var(--warm-600)" : "var(--text-secondary)", background: "var(--surface-sunken)", borderRadius: "var(--radius-full)", padding: "6px 12px", fontFamily: "var(--font-mono)" }}>
                {S.fmtShort(o.dObj)} · {o.time}{o.moved ? " *" : ""}
              </span>
            ))}
          </div>
        </div>
      )}

      {p.mode === "flex" && (
        q ? (
          <div style={{ marginTop: 12, display: "flex", alignItems: "center", gap: 10, padding: "11px 13px", borderRadius: "var(--radius-md)", background: q.overdue ? "var(--danger-bg)" : "var(--warm-bg)" }}>
            <Icon name="calendar-clock" size={16} color={q.overdue ? "var(--danger-600)" : "var(--warm-600)"} />
            <span style={{ flex: 1, fontSize: "var(--fs-sm)", fontWeight: "var(--fw-medium)", color: "var(--text-primary)" }}>Próxima limpeza {q.label}</span>
            <Button size="sm" onClick={() => setSheet({ kind: "fit", q })}>Encaixar</Button>
          </div>
        ) : (
          <div style={{ marginTop: 12, fontSize: "var(--fs-caption)", color: "var(--text-muted)" }}>
            {p.scheduledNext && S.fromISO(p.scheduledNext) >= S.TODAY
              ? <span>Próxima visita encaixada: <b style={{ color: "var(--text-secondary)" }}>{S.fmt(S.fromISO(p.scheduledNext))}</b></span>
              : <span>Janela abre em {S.fmtShort(S.dueOf(p))} — aparece em Agenda → A encaixar.</span>}
          </div>
        )
      )}

      {sheet === "plan" && <PlanSheet clientId={clientId} onClose={() => setSheet(null)} onDone={bump} />}
      {sheet && sheet.kind === "fit" && <FitSheet q={sheet.q} onClose={() => setSheet(null)} onDone={bump} />}
    </Card>
  );
}

/* ============ nudge do dashboard ============ */
function FitNudge({ go }) {
  const S = window.FCSched;
  const q = S.queue();
  if (!q.length) return null;
  const names = q.map((x) => `${x.client.name.split(" ")[0]} (${S.freqLabel(x.plan).toLowerCase()})`).join(" e ");
  return (
    <Card interactive onClick={() => go("agenda")} style={{ padding: "13px 16px", background: "var(--warm-bg)", border: "1px solid color-mix(in oklab, var(--warm-500) 30%, white)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 13 }}>
        <div style={{ width: 40, height: 40, borderRadius: "var(--radius-full)", background: "color-mix(in oklab, var(--warm-500) 18%, white)", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}>
          <Icon name="calendar-clock" size={19} color="var(--warm-600)" />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: "var(--fw-bold)", color: "var(--text-strong)", fontSize: "var(--fs-body)" }}>{q.length} cliente{q.length > 1 ? "s" : ""} pra encaixar</div>
          <div style={{ fontSize: "var(--fs-caption)", color: "var(--text-muted)", marginTop: 1 }}>{names} — sem dia fixo, a janela chegou</div>
        </div>
        <Icon name="chevron-right" size={18} color="var(--warm-600)" />
      </div>
    </Card>
  );
}

Object.assign(window, { AgendaScreen: AgendaScreenV2, AgendaScreenV2, FitQueue, PlansScreen, PlanCard, FitNudge, RecurChip, OccurrenceScreen, schedAllOccs });
