/* ============================================================
   EDUCARE — Agenda (Dia / Semana / Mês)
   ============================================================ */
(function () {
  const { useState, useEffect } = React;
  const Icon = window.Icon;

  const DOW_FULL = ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"];
  const DOW_SHORT = ["DOM", "SEG", "TER", "QUA", "QUI", "SEX", "SÁB"];
  const MON_SHORT = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"];
  const MON_FULL = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"];

  const iso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  const todayLocal = () => (window.todayLocal ? window.todayLocal() : (() => { const n = new Date(); return new Date(n.getFullYear(), n.getMonth(), n.getDate()); })());
  const sameDay = (a, b) => iso(a) === iso(b);
  const evFor = (d) => window.EVENTS.filter((e) => e.date === iso(d)).sort((a, b) => (a.start || "").localeCompare(b.start || ""));
  const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x; };

  function EventChip({ e, onEvent }) {
    return (
      <button className={"ev " + e.type} onClick={() => onEvent && onEvent(e)}>
        {!e.allDay && <span className="et">{e.start}</span>}
        <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{e.title}</span>
      </button>
    );
  }

  function DiaView({ date, onEvent }) {
    const all = evFor(date);
    const allDay = all.filter((e) => e.allDay);
    const timed = all.filter((e) => !e.allDay);
    const hours = [];
    for (let h = 8; h <= 19; h++) hours.push(h);
    return (
      <>
        {allDay.length > 0 && (
          <div style={{ display: "flex", gap: 8, marginBottom: 12, flexWrap: "wrap" }}>
            {allDay.map((e, i) => <EventChip key={i} e={e} onEvent={onEvent} />)}
          </div>
        )}
        <div className="day-grid">
          {hours.map((h) => {
            const evs = timed.filter((e) => parseInt(e.start) === h);
            return (
              <div className="hour-row" key={h}>
                <div className="hour-lbl">{String(h).padStart(2, "0")}:00</div>
                <div className="hour-cell">
                  {evs.map((e, i) => <EventChip key={i} e={e} onEvent={onEvent} />)}
                </div>
              </div>
            );
          })}
        </div>
      </>
    );
  }

  function SemanaView({ date, onEvent, todayIso }) {
    // week Monday-first containing `date`
    const leading = (date.getDay() + 6) % 7;
    const monday = addDays(date, -leading);
    const days = Array.from({ length: 7 }, (_, i) => addDays(monday, i));
    return (
      <div className="week-grid">
        {days.map((d, i) => {
          const evs = evFor(d);
          return (
            <div className={"week-col" + (iso(d) === todayIso ? " is-today" : "")} key={i}>
              <div className="wc-head">
                <div className="dow">{DOW_SHORT[d.getDay()]}</div>
                <div className="num">{d.getDate()}</div>
              </div>
              <div className="wc-body">
                {evs.length ? evs.map((e, j) => <EventChip key={j} e={e} onEvent={onEvent} />) : <div className="wc-empty">—</div>}
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  function MesView({ date, onOpen, onPickDay, todayIso }) {
    const y = date.getFullYear(), m = date.getMonth();
    const first = new Date(y, m, 1);
    const leading = (first.getDay() + 6) % 7;
    const daysInMonth = new Date(y, m + 1, 0).getDate();
    const total = Math.ceil((leading + daysInMonth) / 7) * 7;
    const cells = Array.from({ length: total }, (_, i) => new Date(y, m, 1 - leading + i));
    return (
      <>
        <div className="month-grid" style={{ marginBottom: 8 }}>
          {["SEG", "TER", "QUA", "QUI", "SEX", "SÁB", "DOM"].map((d) => <div className="month-dow" key={d}>{d}</div>)}
        </div>
        <div className="month-grid">
          {cells.map((d, i) => {
            const inMonth = d.getMonth() === m;
            const evs = evFor(d);
            return (
              <div className={"mcell" + (inMonth ? "" : " muted") + (iso(d) === todayIso ? " is-today" : "")} key={i} onClick={() => onPickDay(d)}>
                <div className="mnum">{d.getDate()}</div>
                {evs.slice(0, 2).map((e, j) => <div className={"ev-mini " + e.type} key={j}>{e.allDay ? e.title : `${e.start} ${e.title}`}</div>)}
                {evs.length > 2 && <div className="ev-more">+{evs.length - 2} mais</div>}
              </div>
            );
          })}
        </div>
      </>
    );
  }

  const SCHED_TYPES = [
    { k: "agendado", l: "Sessão agendada", session: true },
    { k: "confirmado", l: "Sessão confirmada", session: true },
    { k: "realizado", l: "Sessão realizada", session: true },
    { k: "falta", l: "Falta (não compareceu)", session: true },
    { k: "compromisso", l: "Compromisso", session: false },
    { k: "bloqueado", l: "Bloqueio de horário", session: false },
  ];
  const feeOf = (p) => Math.max(0, Math.round(Number(p && p.fee)) || 0);
  const brl = (v) => "R$ " + (Math.round(v || 0)).toLocaleString("pt-BR");
  // Sincroniza a cobrança (billing) ao salvar/editar/excluir um agendamento.
  // Regra: cobrança nasce da sessão REALIZADA; FALTA = R$ 0,00 (sem cobrança).
  // Unicidade paciente_id + data no billing evita duplicar.
  function syncBilling(oldEv, next) {
    const bi = window.Billing; if (!bi) return;
    const wasCharge = oldEv && (oldEv.type === "realizado" || oldEv.type === "falta") && oldEv.pid;
    const nowCharge = next && (next.type === "realizado" || next.type === "falta") && next.pid;
    // Remove a cobrança antiga se deixou de ser sessão-com-cobrança ou mudou paciente/data.
    if (wasCharge && (!nowCharge || oldEv.pid !== next.pid || oldEv.date !== next.date)) {
      try { bi.removeSession(oldEv.pid, oldEv.date); } catch (e) { /* */ }
    }
    if (nowCharge) {
      const p = (window.PATIENTS || []).find((x) => x.id === next.pid);
      try { bi.recordSession(next.pid, next.date, next.type === "falta" ? 0 : feeOf(p), next.type === "falta" ? "falta" : "realizado"); } catch (e) { /* */ }
    }
  }

  function AgendarModal({ onClose, onSaved, onDeleted, defaultDate, event, onOpenPatient }) {
    const isEdit = !!event;
    const [type, setType] = useState(event ? event.type : "agendado");
    const [pid, setPid] = useState(event ? (event.pid || "") : "");
    const [title, setTitle] = useState(event && !event.pid ? (event.title || "") : "");
    const [d, setD] = useState(event ? event.date : defaultDate);
    const [start, setStart] = useState(event ? (event.start || "09:00") : "09:00");
    const [end, setEnd] = useState(event ? (event.end || "09:50") : "09:50");
    const [err, setErr] = useState("");
    const tinfo = SCHED_TYPES.find((t) => t.k === type) || SCHED_TYPES[0];
    const isSession = tinfo.session;
    const patients = window.PATIENTS;
    const selPatient = patients.find((x) => x.id === pid);
    const geraCobranca = type === "realizado" || type === "falta";
    const wasCharge = event && (event.type === "realizado" || event.type === "falta") && event.pid;

    function save() {
      if (isSession && !pid) { setErr("Selecione o paciente."); return; }
      if (!isSession && !title.trim()) { setErr("Informe um título para o compromisso."); return; }
      if (!d) { setErr("Selecione a data."); return; }
      if (type !== "falta" && (!start || !end)) { setErr("Informe os horários de início e fim."); return; }
      if (start && end && end <= start) { setErr("O horário de término deve ser após o início."); return; }
      const p = isSession ? patients.find((x) => x.id === pid) : null;
      const next = { date: d, start, end, title: isSession ? (p ? p.name : "Sessão") : title.trim(), type, pid: isSession ? pid : undefined };
      // Aviso ao reverter uma sessão realizada/falta (remove a cobrança gerada).
      if (wasCharge && !(next.type === "realizado" || next.type === "falta" ? next.pid : false)) {
        if (!window.confirm("Esta sessão estava marcada como “" + (SCHED_TYPES.find((t) => t.k === event.type) || {}).l + "” e gerou lançamento no Financeiro. Alterar o tipo vai remover essa cobrança. Continuar?")) return;
      }
      if (isEdit && event.id && window.updateEvent) window.updateEvent(event.id, next); else window.addEvent(next);
      syncBilling(event || null, next);
      onSaved(d);
    }
    function excluir() {
      if (wasCharge && !window.confirm("Excluir esta sessão também remove a cobrança correspondente no Financeiro. Continuar?")) return;
      if (event && (event.type === "realizado" || event.type === "falta") && event.pid && window.Billing) { try { window.Billing.removeSession(event.pid, event.date); } catch (e) { /* */ } }
      if (event && event.id && window.removeEvent) window.removeEvent(event.id);
      (onDeleted || onSaved)(event ? event.date : d);
    }

    return (
      <div className="modal-scrim" onClick={onClose}>
        <div className="modal" onClick={(e) => e.stopPropagation()}>
          <div className="modal-head">
            <div>
              <h3>{isEdit ? "Editar agendamento" : "Novo agendamento"}</h3>
              <p>{isEdit ? "Altere o tipo/status ou exclua o agendamento." : "Agende uma sessão ou compromisso na sua agenda."}</p>
            </div>
            <button className="x" onClick={onClose} aria-label="Fechar"><Icon name="x" size={18} /></button>
          </div>
          <div className="modal-body">
            <div className="fld">
              <label>Tipo</label>
              <select className="ctrl" value={type} onChange={(e) => { setType(e.target.value); setErr(""); }}>
                {SCHED_TYPES.map((t) => <option key={t.k} value={t.k}>{t.l}</option>)}
              </select>
              <p className="help-text" style={{ marginBottom: 0 }}>Fluxo: Agendado → Confirmado → <b>Sessão realizada</b> (ou <b>Falta</b>).</p>
            </div>

            {isSession ? (
              <div className="fld">
                <label>Paciente <span className="req">*</span></label>
                <select className="ctrl" value={pid} onChange={(e) => setPid(e.target.value)}>
                  <option value="" disabled>Selecione o paciente...</option>
                  {patients.map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}
                </select>
                {patients.length === 0 && <p className="help-text">Cadastre um paciente antes de agendar uma sessão.</p>}
              </div>
            ) : (
              <div className="fld">
                <label>Título <span className="req">*</span></label>
                <input className="ctrl" placeholder="Ex: Reunião com a escola" value={title} onChange={(e) => setTitle(e.target.value)} />
              </div>
            )}

            <div className="fld">
              <label>Data{geraCobranca ? " do atendimento" : ""}</label>
              <input className="ctrl" type="date" value={d} onChange={(e) => setD(e.target.value)} />
            </div>
            <div className="grid-2">
              <div className="fld"><label>Início</label><input className="ctrl" type="time" value={start} onChange={(e) => setStart(e.target.value)} /></div>
              <div className="fld"><label>Fim</label><input className="ctrl" type="time" value={end} onChange={(e) => setEnd(e.target.value)} /></div>
            </div>

            {geraCobranca && (
              <div style={{ display: "flex", alignItems: "flex-start", gap: 8, background: type === "falta" ? "var(--surface-2)" : "var(--primary-soft)", border: "1px solid " + (type === "falta" ? "var(--border)" : "var(--primary)"), borderRadius: 10, padding: "9px 12px", marginTop: 4 }}>
                <span style={{ fontSize: 15 }}>{type === "falta" ? "🚫" : "💳"}</span>
                <p style={{ margin: 0, fontSize: 12.5, fontWeight: 700, lineHeight: 1.5, color: type === "falta" ? "var(--text-2)" : "var(--primary)" }}>
                  {type === "falta"
                    ? "Falta registrada com R$ 0,00 — mantém a frequência, sem gerar cobrança."
                    : "Ao salvar, gera a cobrança de " + brl(feeOf(selPatient)) + " no Financeiro (valor de sessão do paciente), na data do atendimento."}
                </p>
              </div>
            )}

            {err && (
              <p className="form-err" role="alert" style={{ display: "flex", alignItems: "center", gap: 7, color: "#EF4444", fontWeight: 700, fontSize: 13.5, margin: "4px 0 0" }}>
                <Icon name="x" size={15} /> {err}
              </p>
            )}

            <div className="form-actions" style={{ marginTop: 18, display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
              {isEdit && <button className="btn btn-sm" style={{ background: "#DC2626", color: "#fff" }} onClick={excluir}><Icon name="x" size={15} /> Excluir</button>}
              {isEdit && event.pid && onOpenPatient && <button className="btn btn-ghost btn-sm" onClick={() => { onClose(); onOpenPatient(event.pid); }}><Icon name="users" size={15} /> Ver paciente</button>}
              <button className="btn btn-ghost btn-sm" style={{ marginLeft: "auto" }} onClick={onClose}>Cancelar</button>
              <button className="btn btn-primary btn-sm" onClick={save}><Icon name={isEdit ? "clipboardCheck" : "plus"} size={16} />{isEdit ? "Salvar" : "Agendar"}</button>
            </div>
          </div>
        </div>
      </div>
    );
  }

  function Agenda({ onOpen, onSchedule, focusDate, focusKey }) {
    const [view, setView] = useState("semana");
    const [date, setDate] = useState(todayLocal);       // inicia sempre no período atual
    const [today, setToday] = useState(todayLocal);     // "hoje" para o destaque
    const [editEv, setEditEv] = useState(null);         // evento em edição (clique no chip)
    const [, forceA] = useState(0);
    function openEvent(e) { if (e && (e.type === "feriado" || e.type === "aniversario")) return; setEditEv(e); }

    // Migra o destaque de "hoje" na virada da meia-noite (checagem leve + foco/visibilidade).
    useEffect(() => {
      const check = () => { const t = todayLocal(); setToday((prev) => (iso(prev) !== iso(t) ? t : prev)); };
      const id = setInterval(check, 60 * 1000);
      window.addEventListener("focus", check);
      document.addEventListener("visibilitychange", check);
      return () => { clearInterval(id); window.removeEventListener("focus", check); document.removeEventListener("visibilitychange", check); };
    }, []);

    useEffect(() => {
      if (!focusDate) return;
      const [yy, mm, dd] = focusDate.split("-").map(Number);
      setDate(new Date(yy, mm - 1, dd));
      setView("dia");
    }, [focusKey]);

    const todayIso = iso(today);

    // Intervalo [ini, fim] efetivamente exibido, conforme a visão.
    const leadingW = (date.getDay() + 6) % 7;
    const weekMon = addDays(date, -leadingW), weekSun = addDays(weekMon, 6);
    let periodStart, periodEnd, periodLbl;
    if (view === "dia") { periodStart = periodEnd = date; periodLbl = `${date.getDate()} ${MON_SHORT[date.getMonth()]}`; }
    else if (view === "semana") { periodStart = weekMon; periodEnd = weekSun; periodLbl = "esta semana"; }
    else { periodStart = new Date(date.getFullYear(), date.getMonth(), 1); periodEnd = new Date(date.getFullYear(), date.getMonth() + 1, 0); periodLbl = MON_FULL[date.getMonth()].toLowerCase(); }
    const isoStart = iso(periodStart), isoEnd = iso(periodEnd);
    const periodCount = window.EVENTS.filter((e) => !e.allDay && (e.type === "agendado" || e.type === "confirmado") && e.date >= isoStart && e.date <= isoEnd).length;

    function step(dir) {
      if (view === "dia") setDate(addDays(date, dir));
      else if (view === "semana") setDate(addDays(date, dir * 7));
      else setDate(new Date(date.getFullYear(), date.getMonth() + dir, 1));
    }
    function irParaHoje() { const t = todayLocal(); setToday(t); setDate(t); }

    let rangelbl;
    if (view === "dia") rangelbl = `${DOW_FULL[date.getDay()]}, ${date.getDate()} ${MON_SHORT[date.getMonth()]} ${date.getFullYear()}`;
    else if (view === "semana") {
      rangelbl = `${weekMon.getDate()} ${MON_SHORT[weekMon.getMonth()]} – ${weekSun.getDate()} ${MON_SHORT[weekSun.getMonth()]} ${weekSun.getFullYear()}`;
    } else rangelbl = `${MON_FULL[date.getMonth()]} ${date.getFullYear()}`;

    return (
      <>
        <div className="crumb">Dashboard <Icon name="chevR" size={13} /> <span className="cur">Agenda</span></div>
        <div className="page-head">
          <div>
            <h1><Icon name="calendar" size={26} /> Agenda</h1>
            <p className="sub">{periodCount} {periodCount === 1 ? "sessão agendada" : "sessões agendadas"} {view === "dia" ? "em" : view === "semana" ? "" : "em"} {periodLbl}</p>
          </div>
          <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
            <div className="seg">
              {[["dia", "Dia"], ["semana", "Semana"], ["mes", "Mês"]].map(([k, l]) => (
                <button key={k} className={view === k ? "on" : ""} onClick={() => setView(k)}>{l}</button>
              ))}
            </div>
            <button className="btn btn-primary btn-sm" onClick={() => onSchedule && onSchedule(iso(date))}><Icon name="plus" size={17} /> Agendar</button>
          </div>
        </div>

        <div className="agenda-bar">
          <div className="date-nav">
            <button className="nav" onClick={() => step(-1)}><Icon name="chevL" size={18} /></button>
            <span className="rangelbl">{rangelbl}</span>
            <button className="nav" onClick={() => step(1)}><Icon name="chevR" size={18} /></button>
          </div>
          <button className="today-btn" onClick={irParaHoje}>Hoje</button>
        </div>

        {view === "dia" && <DiaView date={date} onEvent={openEvent} />}
        {view === "semana" && <SemanaView date={date} onEvent={openEvent} todayIso={todayIso} />}
        {view === "mes" && <MesView date={date} todayIso={todayIso} onPickDay={(d) => { setDate(d); setView("dia"); }} />}

        {editEv && (
          <AgendarModal
            event={editEv}
            onOpenPatient={onOpen}
            onClose={() => setEditEv(null)}
            onSaved={() => { setEditEv(null); forceA((n) => n + 1); }}
            onDeleted={() => { setEditEv(null); forceA((n) => n + 1); }}
          />
        )}
      </>
    );
  }

  window.Agenda = Agenda;
  window.AgendarModal = AgendarModal;
})();
