
// ============================================================
// JuFlow — Agenda (Daily / Weekly / Monthly views)
// ============================================================
const { useState: useStA, useMemo: useMemoA, useCallback: useCbA, useRef: useRefA, useEffect: useEfA } = React;
const UA = window.JFUtils;

const START_HOUR = 7;
const END_HOUR   = 21;
const PX_PER_MIN = 1.8; // pixels per minute → 60min=108px, 30min=54px

const timeToY = (date) => {
  const d = new Date(date);
  const mins = (d.getHours() - START_HOUR) * 60 + d.getMinutes();
  return Math.max(0, mins * PX_PER_MIN);
};
const TOTAL_HEIGHT = (END_HOUR - START_HOUR) * 60 * PX_PER_MIN;

// Generate time labels (30-min increments)
const TIME_LABELS = [];
for (let h = START_HOUR; h <= END_HOUR; h++) {
  TIME_LABELS.push({ label: `${String(h).padStart(2,'0')}:00`, mins: (h - START_HOUR) * 60 });
  if (h < END_HOUR) TIME_LABELS.push({ label: `${String(h).padStart(2,'0')}:30`, mins: (h - START_HOUR) * 60 + 30 });
}

// ─── Appointment card for grid views ──────────────────────
const ApptCard = ({ appt, onOpen, compact = false }) => {
  const [hov, setHov] = useState(false);
  const client  = UA.getClient(appt.clientId);
  const service = UA.getService(appt.serviceId);
  const prof    = UA.getProfessional(appt.professionalId);
  const color   = prof?.color || '#FF6B35';
  const endTime = UA.addMinutes(appt.datetime, appt.duration);
  const isCancelled = appt.status === 'cancelled' || appt.status === 'no_show';

  return (
    <div
      onClick={() => onOpen(appt)}
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      style={{
        background: isCancelled ? '#F9FAFB' : UA.hexToRgba(color, hov ? 0.2 : 0.12),
        borderLeft: `3px solid ${isCancelled ? '#D1D5DB' : color}`,
        borderRadius: 8,
        padding: compact ? '3px 6px' : '6px 10px',
        cursor: 'pointer',
        transition: 'all .15s',
        boxShadow: hov ? `0 4px 14px ${UA.hexToRgba(color, 0.3)}` : 'none',
        transform: hov ? 'translateY(-1px)' : 'none',
        overflow: 'hidden',
        opacity: isCancelled ? 0.6 : 1,
        height: '100%',
        boxSizing: 'border-box',
      }}
    >
      {!compact && (
        <div style={{ fontSize: 10, fontWeight: 700, color, marginBottom: 2, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
          {UA.formatTime(appt.datetime)} – {UA.formatTime(endTime)}
        </div>
      )}
      <div style={{ fontSize: compact ? 10 : 12, fontWeight: 700, color:'#0A1F44', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
        {client?.name || '—'}
      </div>
      {!compact && (
        <div style={{ fontSize: 11, color:'#6B7280', whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>
          {service?.name}
        </div>
      )}
      {!compact && (
        <div style={{ fontSize: 10, color, fontWeight: 600, marginTop: 2, display:'flex', alignItems:'center', gap: 4 }}>
          <div style={{ width:5, height:5, borderRadius:'50%', background:color, flexShrink:0 }} />
          {prof?.name}
        </div>
      )}
    </div>
  );
};

// ─── DAILY VIEW ───────────────────────────────────────────
const DailyView = ({ date, appointments, onOpen, onNewAtTime }) => {
  const dayAppts = useMemoA(() =>
    UA.getAppointmentsForDay(appointments, date)
      .filter(a => a.status !== 'cancelled')
      .sort((a,b) => new Date(a.datetime) - new Date(b.datetime))
  , [appointments, date]);

  // Compute overlapping columns
  const positioned = useMemoA(() => {
    const groups = [];
    dayAppts.forEach(appt => {
      const start = new Date(appt.datetime).getTime();
      const end   = start + appt.duration * 60000;
      let placed  = false;
      for (const group of groups) {
        const overlaps = group.some(g => {
          const gs = new Date(g.datetime).getTime();
          const ge = gs + g.duration * 60000;
          return start < ge && end > gs;
        });
        if (!overlaps) { group.push(appt); placed = true; break; }
      }
      if (!placed) groups.push([appt]);
    });
    const result = {};
    groups.forEach((group, col) => {
      group.forEach(appt => { result[appt.id] = { col, totalCols: groups.length }; });
    });
    return result;
  }, [dayAppts]);

  const colWidth = 100 / Math.max(1, Object.values(positioned).reduce((m,v) => Math.max(m, v.totalCols), 1));

  return (
    <div style={{ display:'flex', flex:1, overflow:'hidden' }}>
      {/* Time column */}
      <div style={{ width:64, flexShrink:0, position:'relative', height:TOTAL_HEIGHT, marginTop: 24 }}>
        {TIME_LABELS.filter(t => t.label.endsWith(':00')).map(t => (
          <div key={t.label} style={{
            position:'absolute', top: t.mins * PX_PER_MIN - 8,
            right: 12, fontSize:11, color:'#9CA3AF', fontWeight:600,
            userSelect:'none',
          }}>{t.label}</div>
        ))}
      </div>

      {/* Grid */}
      <div style={{ flex:1, position:'relative', height:TOTAL_HEIGHT, marginTop:24 }}>
        {/* Hour lines */}
        {TIME_LABELS.map(t => (
          <div key={t.label} style={{
            position:'absolute', top: t.mins * PX_PER_MIN,
            left:0, right:0, height:1,
            background: t.label.endsWith(':00') ? '#E2E8F0' : '#F3F4F6',
            zIndex:0,
          }} />
        ))}

        {/* Click-to-create zones */}
        {TIME_LABELS.map(t => (
          <div
            key={'z'+t.label}
            onClick={() => onNewAtTime(date, t.mins)}
            style={{
              position:'absolute', top: t.mins * PX_PER_MIN,
              left:0, right:0, height: 30 * PX_PER_MIN,
              cursor:'pointer', zIndex:1,
            }}
            onMouseEnter={e => { e.currentTarget.style.background='rgba(255,107,53,.04)'; }}
            onMouseLeave={e => { e.currentTarget.style.background='transparent'; }}
          />
        ))}

        {/* Appointment cards */}
        {dayAppts.map(appt => {
          const pos = positioned[appt.id] || { col:0, totalCols:1 };
          const top    = timeToY(appt.datetime);
          const height = Math.max(appt.duration * PX_PER_MIN - 4, 32);
          const pct    = 100 / pos.totalCols;
          return (
            <div key={appt.id} style={{
              position:'absolute',
              top: top + 2, height,
              left: `calc(${pos.col * pct}% + 2px)`,
              width: `calc(${pct}% - 6px)`,
              zIndex: 10,
            }}>
              <ApptCard appt={appt} onOpen={onOpen} />
            </div>
          );
        })}

        {/* "Now" line */}
        {UA.isToday(date) && (() => {
          const now  = window.JF.TODAY;
          const y    = (now.getHours() - START_HOUR) * 60 * PX_PER_MIN + now.getMinutes() * PX_PER_MIN;
          return y >= 0 && y <= TOTAL_HEIGHT ? (
            <div style={{ position:'absolute', top: y, left:0, right:0, zIndex:20, display:'flex', alignItems:'center', gap:4 }}>
              <div style={{ width:10, height:10, borderRadius:'50%', background:'#EF4444', flexShrink:0 }} />
              <div style={{ flex:1, height:2, background:'#EF4444', opacity:.7 }} />
            </div>
          ) : null;
        })()}
      </div>
    </div>
  );
};

// ─── WEEKLY VIEW ──────────────────────────────────────────
const WeeklyView = ({ date, appointments, onOpen, onNewAtTime }) => {
  const weekDays = useMemoA(() => UA.getWeekDays(date), [date]);
  const DAY_NAMES = ['Seg','Ter','Qua','Qui','Sex','Sáb','Dom'];

  return (
    <div style={{ display:'flex', flex:1, overflow:'hidden' }}>
      {/* Time column */}
      <div style={{ width:52, flexShrink:0 }}>
        <div style={{ height:52, borderBottom:'1px solid #E2E8F0' }} />
        <div style={{ position:'relative', height:TOTAL_HEIGHT }}>
          {TIME_LABELS.filter(t => t.label.endsWith(':00')).map(t => (
            <div key={t.label} style={{
              position:'absolute', top: t.mins * PX_PER_MIN - 8,
              right:8, fontSize:10, color:'#9CA3AF', fontWeight:600,
            }}>{t.label}</div>
          ))}
        </div>
      </div>

      {/* Day columns */}
      {weekDays.map((day, di) => {
        const dayAppts = UA.getAppointmentsForDay(appointments, day).filter(a => a.status !== 'cancelled');
        const isToday  = UA.isToday(day);
        return (
          <div key={di} style={{ flex:1, borderLeft:'1px solid #E2E8F0', display:'flex', flexDirection:'column' }}>
            {/* Day header */}
            <div style={{
              height:52, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center',
              borderBottom:'1px solid #E2E8F0', flexShrink:0,
              background: isToday ? '#FFF0EA' : '#FAFAFA',
            }}>
              <span style={{ fontSize:10, fontWeight:600, color:'#9CA3AF', textTransform:'uppercase', letterSpacing:.5 }}>{DAY_NAMES[di]}</span>
              <span style={{
                fontSize:18, fontWeight:800,
                color: isToday ? '#FF6B35' : '#0A1F44',
                width:32, height:32, display:'flex', alignItems:'center', justifyContent:'center',
                borderRadius:'50%', background: isToday ? 'rgba(255,107,53,.1)' : 'none',
              }}>{day.getDate()}</span>
            </div>

            {/* Time grid */}
            <div style={{ position:'relative', height:TOTAL_HEIGHT, flex:1 }}>
              {TIME_LABELS.map(t => (
                <div key={t.label} style={{
                  position:'absolute', top: t.mins * PX_PER_MIN,
                  left:0, right:0, height:1,
                  background: t.label.endsWith(':00') ? '#E2E8F0' : '#F9FAFB',
                }} />
              ))}
              {TIME_LABELS.map(t => (
                <div key={'z'+t.label}
                  onClick={() => onNewAtTime(day, t.mins)}
                  style={{ position:'absolute', top: t.mins * PX_PER_MIN, left:0, right:0, height:30*PX_PER_MIN, cursor:'pointer', zIndex:1 }}
                  onMouseEnter={e => e.currentTarget.style.background='rgba(255,107,53,.04)'}
                  onMouseLeave={e => e.currentTarget.style.background='transparent'}
                />
              ))}
              {dayAppts.map(appt => {
                const top    = timeToY(appt.datetime);
                const height = Math.max(appt.duration * PX_PER_MIN - 3, 24);
                return (
                  <div key={appt.id} style={{ position:'absolute', top: top+1, left:2, right:2, height, zIndex:10 }}>
                    <ApptCard appt={appt} onOpen={onOpen} compact={true} />
                  </div>
                );
              })}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── MONTHLY VIEW ─────────────────────────────────────────
const MonthlyView = ({ date, appointments, onDayClick }) => {
  const calDays  = useMemoA(() => UA.getMonthCalendar(date), [date]);
  const DAY_NAMES = ['Seg','Ter','Qua','Qui','Sex','Sáb','Dom'];

  return (
    <div style={{ flex:1, display:'flex', flexDirection:'column' }}>
      {/* Week headers */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7,1fr)', borderBottom:'2px solid #E2E8F0', flexShrink:0 }}>
        {DAY_NAMES.map(d => (
          <div key={d} style={{ padding:'10px 0', textAlign:'center', fontSize:11, fontWeight:700, color:'#9CA3AF', textTransform:'uppercase', letterSpacing:.5 }}>{d}</div>
        ))}
      </div>
      {/* Calendar grid */}
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7,1fr)', gridTemplateRows:'repeat(6,1fr)', flex:1 }}>
        {calDays.map(({ date:d, currentMonth }, i) => {
          const dayAppts = appointments.filter(a => UA.isSameDay(a.datetime, d) && a.status !== 'cancelled');
          const isToday  = UA.isToday(d);
          const profColors = [...new Set(dayAppts.map(a => UA.getProfessional(a.professionalId)?.color).filter(Boolean))];
          return (
            <div
              key={i}
              onClick={() => onDayClick(d)}
              style={{
                border:'1px solid #F0F4F8', padding:'8px 6px',
                cursor:'pointer', transition:'background .1s',
                background: isToday ? '#FFF7F3' : currentMonth ? '#fff' : '#FAFAFA',
                opacity: currentMonth ? 1 : 0.5,
                display:'flex', flexDirection:'column', gap:4, minHeight:80,
              }}
              onMouseEnter={e => e.currentTarget.style.background = isToday ? '#FFF0EA' : '#F9FAFB'}
              onMouseLeave={e => e.currentTarget.style.background = isToday ? '#FFF7F3' : currentMonth ? '#fff' : '#FAFAFA'}
            >
              <div style={{
                fontSize:13, fontWeight:isToday ? 800 : 600,
                color: isToday ? '#FF6B35' : currentMonth ? '#0A1F44' : '#C4CDD6',
                width:26, height:26, display:'flex', alignItems:'center', justifyContent:'center',
                borderRadius:'50%', background: isToday ? 'rgba(255,107,53,.12)' : 'none',
              }}>{d.getDate()}</div>
              {dayAppts.length > 0 && (
                <div style={{ display:'flex', flexWrap:'wrap', gap:2, marginTop:2 }}>
                  {dayAppts.slice(0, 3).map(a => {
                    const prof = UA.getProfessional(a.professionalId);
                    const client = UA.getClient(a.clientId);
                    return (
                      <div key={a.id} style={{
                        height:16, padding:'0 5px', borderRadius:4,
                        background: UA.hexToRgba(prof?.color || '#FF6B35', 0.15),
                        fontSize:10, fontWeight:600,
                        color: prof?.color || '#FF6B35',
                        overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap',
                        maxWidth:'100%',
                      }}>
                        {UA.formatTime(a.datetime)} {client?.name?.split(' ')[0]}
                      </div>
                    );
                  })}
                  {dayAppts.length > 3 && (
                    <div style={{ fontSize:10, color:'#9CA3AF', fontWeight:600 }}>+{dayAppts.length-3} mais</div>
                  )}
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ─── PROFESSIONAL FILTER CHIPS ────────────────────────────
const ProfChips = ({ selected, onChange }) => (
  <div style={{ display:'flex', gap:6, flexWrap:'wrap' }}>
    <button
      onClick={() => onChange(null)}
      style={{
        padding:'5px 12px', borderRadius:20, fontSize:12, fontWeight:600, cursor:'pointer',
        background: selected === null ? '#0A1F44' : '#F3F4F6',
        color: selected === null ? '#fff' : '#6B7280',
        border:'none', transition:'all .15s',
      }}
    >Todos</button>
    {window.JF.PROFESSIONALS.map(p => (
      <button
        key={p.id}
        onClick={() => onChange(selected === p.id ? null : p.id)}
        style={{
          padding:'5px 12px', borderRadius:20, fontSize:12, fontWeight:600, cursor:'pointer',
          background: selected === p.id ? p.color : UA.hexToRgba(p.color, 0.1),
          color: selected === p.id ? '#fff' : p.color,
          border: `1.5px solid ${UA.hexToRgba(p.color, 0.3)}`,
          transition:'all .15s',
        }}
      >{p.name.split(' ')[0]} {p.name.split(' ')[1]}</button>
    ))}
  </div>
);

// ─── MAIN AGENDA COMPONENT ────────────────────────────────
const Agenda = ({ appointments, onOpenNew, onOpenAppt, date, onDateChange, view, onViewChange }) => {
  const [profFilter, setProfFilter] = useStA(null);
  const [statusFilter, setStatusFilter] = useStA('all');
  const scrollRef = useRefA(null);

  // Scroll to current time on load
  useEfA(() => {
    if (scrollRef.current && view === 'daily') {
      const now = window.JF.TODAY;
      const y   = (now.getHours() - START_HOUR) * 60 * PX_PER_MIN;
      scrollRef.current.scrollTop = Math.max(0, y - 100);
    }
  }, [view]);

  const filteredAppts = useMemoA(() => {
    let list = appointments;
    if (profFilter)           list = list.filter(a => a.professionalId === profFilter);
    if (statusFilter !== 'all') list = list.filter(a => a.status === statusFilter);
    return list;
  }, [appointments, profFilter, statusFilter]);

  const handleNewAtTime = (day, mins) => {
    const h = Math.floor(mins / 60) + START_HOUR;
    const m = mins % 60;
    const dt = new Date(day);
    dt.setHours(h, m, 0, 0);
    onOpenNew({ datetime: dt.toISOString() });
  };

  const navDate = (dir) => {
    const delta = view==='daily' ? 1 : view==='weekly' ? 7 : 30;
    onDateChange(UA.addDays(date, dir * delta));
  };

  const weekDays = UA.getWeekDays(date);
  const headerLabel = view === 'monthly'
    ? UA.formatMonthYear(date)
    : view === 'weekly'
    ? `${UA.formatDateShort(weekDays[0])} – ${UA.formatDateShort(weekDays[6])}, ${date.getFullYear()}`
    : UA.formatDateLong(date);

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', overflow:'hidden' }}>
      {/* Toolbar */}
      <div style={{
        padding:'16px 24px', background:'#fff', borderBottom:'1px solid #E2E8F0',
        display:'flex', flexDirection:'column', gap:12, flexShrink:0,
      }}>
        <div style={{ display:'flex', alignItems:'center', gap:12, flexWrap:'wrap' }}>
          {/* View toggle */}
          <div style={{ display:'flex', background:'#F3F4F6', borderRadius:10, padding:3 }}>
            {['daily','weekly','monthly'].map(v => (
              <button key={v} onClick={() => onViewChange(v)} style={{
                padding:'6px 14px', borderRadius:8, fontSize:12, fontWeight:600,
                background: view===v ? '#fff' : 'transparent',
                color: view===v ? '#0A1F44' : '#6B7280',
                border:'none', cursor:'pointer', boxShadow: view===v ? '0 1px 4px rgba(0,0,0,.08)' : 'none',
                transition:'all .15s',
              }}>{{daily:'Diário',weekly:'Semanal',monthly:'Mensal'}[v]}</button>
            ))}
          </div>

          {/* Date navigation */}
          <div style={{ display:'flex', alignItems:'center', gap:8 }}>
            <button onClick={() => navDate(-1)} style={{ width:32, height:32, borderRadius:8, border:'1px solid #E2E8F0', background:'#fff', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
              <Icon name="ChevronLeft" size={16} color="#6B7280" />
            </button>
            <button onClick={() => onDateChange(new Date(window.JF.TODAY))} style={{
              padding:'6px 14px', borderRadius:8, fontSize:12, fontWeight:600,
              border:'1px solid #E2E8F0', background:'#fff', cursor:'pointer', color:'#0A1F44',
            }}>Hoje</button>
            <button onClick={() => navDate(1)} style={{ width:32, height:32, borderRadius:8, border:'1px solid #E2E8F0', background:'#fff', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
              <Icon name="ChevronRight" size={16} color="#6B7280" />
            </button>
          </div>

          <div style={{ fontSize:15, fontWeight:700, color:'#0A1F44', flex:1 }}>{headerLabel}</div>

          {/* Status filter */}
          <select value={statusFilter} onChange={e => setStatusFilter(e.target.value)} style={{
            padding:'7px 12px', borderRadius:8, fontSize:12, border:'1px solid #E2E8F0',
            background:'#fff', color:'#0A1F44', cursor:'pointer', outline:'none',
          }}>
            {[['all','Todos os status'],['confirmed','Confirmados'],['pending','Pendentes'],['completed','Realizados'],['cancelled','Cancelados']].map(([v,l]) => (
              <option key={v} value={v}>{l}</option>
            ))}
          </select>

          <Button variant="primary" icon="Plus" onClick={() => onOpenNew({})}>Novo Agendamento</Button>
        </div>

        {/* Professional chips */}
        <ProfChips selected={profFilter} onChange={setProfFilter} />
      </div>

      {/* Calendar area */}
      <div ref={scrollRef} style={{ flex:1, overflow:'auto', background:'#fff' }}>
        <div style={{ minHeight: view==='monthly' ? 'auto' : TOTAL_HEIGHT + 80 }}>
          {view === 'daily'   && <DailyView   date={date} appointments={filteredAppts} onOpen={onOpenAppt} onNewAtTime={handleNewAtTime} />}
          {view === 'weekly'  && <WeeklyView  date={date} appointments={filteredAppts} onOpen={onOpenAppt} onNewAtTime={handleNewAtTime} />}
          {view === 'monthly' && <MonthlyView date={date} appointments={filteredAppts} onDayClick={d => { onDateChange(d); onViewChange('daily'); }} />}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { Agenda });
