/* global React, Icon */

// ===========================================================
// Área 7 — Calendar (month grid + day slot expansion)
// ===========================================================

const { useState: useStateC, useEffect: useEffectC, useMemo: useMemoC } = React;

const DAYS_ES = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
const MONTHS_ES = [
  'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
  'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre',
];

const HOURS = [
  '10:00', '11:00', '12:00', '13:00', '14:00', '15:00',
  '16:00', '17:00', '18:00', '19:00', '20:00', '21:00',
  '22:00', '23:00', '00:00',
];

// Deterministic pseudo-random availability per (court, date, hour) so the
// demo "feels real" without a backend. Booking actions overlay on top.
function hashSeed(...vals) {
  let h = 2166136261 >>> 0;
  for (const v of vals) {
    const s = String(v);
    for (let i = 0; i < s.length; i++) {
      h ^= s.charCodeAt(i);
      h = Math.imul(h, 16777619);
    }
  }
  return h >>> 0;
}
function rand01(seed) { return ((seed % 10000) / 10000); }

function defaultStatus(courtId, dateISO, hour) {
  const r = rand01(hashSeed(courtId, dateISO, hour));
  // Bias evening (18-22h) toward booked
  const h = parseInt(hour);
  const isEvening = h >= 19 && h <= 22;
  const isWeekend = new Date(dateISO).getDay() % 6 === 0;
  let bookedProb = isEvening ? 0.55 : 0.22;
  if (isWeekend && isEvening) bookedProb = 0.78;
  return r < bookedProb ? 'reservado' : 'disponible';
}

function getMonthGrid(year, month) {
  // first day index 0=Mon ... 6=Sun
  const first = new Date(year, month, 1);
  const dow = (first.getDay() + 6) % 7; // shift to Mon-first
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const prevDays = new Date(year, month, 0).getDate();
  const cells = [];
  for (let i = 0; i < dow; i++) {
    cells.push({ d: prevDays - dow + i + 1, month: month - 1, year, outside: true });
  }
  for (let d = 1; d <= daysInMonth; d++) {
    cells.push({ d, month, year, outside: false });
  }
  while (cells.length % 7 !== 0) {
    const last = cells[cells.length - 1];
    const next = last.outside ? last.d + 1 : 1;
    cells.push({ d: next, month: month + 1, year, outside: true });
  }
  // pad to 6 rows
  while (cells.length < 42) {
    const last = cells[cells.length - 1];
    cells.push({ d: last.d + 1, month: last.month, year: last.year, outside: true });
  }
  return cells;
}

function toISO(year, month, day) {
  const y = year;
  const m = String(month + 1).padStart(2, '0');
  const d = String(day).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

function dayAvailability(courtId, year, month, day, bookings) {
  const iso = toISO(year, month, day);
  let free = 0, total = HOURS.length;
  HOURS.forEach(h => {
    const key = `${courtId}|${iso}|${h}`;
    const overridden = bookings[key];
    const status = overridden || defaultStatus(courtId, iso, h);
    if (status === 'disponible') free++;
  });
  return { free, total, iso };
}

// ---------- COMPONENT ----------
function Calendar({
  courts, activeCourtId, onCourtChange,
  selected, onSelect, // { date, hour }
  bookings,           // { [court|iso|hour]: 'reservado' | 'disponible' }
  prices,             // { [courtId]: number }
  density,            // 'comfortable' | 'compact'
}) {
  const today = new Date();
  const [cursor, setCursor] = useStateC(() => ({ year: today.getFullYear(), month: today.getMonth() }));
  const [expandedDay, setExpandedDay] = useStateC(null); // ISO

  const cells = useMemoC(() => getMonthGrid(cursor.year, cursor.month), [cursor]);
  const activeCourt = courts.find(c => c.id === activeCourtId) || courts[0];

  const goPrev = () => setCursor(c => {
    const m = c.month - 1;
    return m < 0 ? { year: c.year - 1, month: 11 } : { ...c, month: m };
  });
  const goNext = () => setCursor(c => {
    const m = c.month + 1;
    return m > 11 ? { year: c.year + 1, month: 0 } : { ...c, month: m };
  });

  const isPast = (year, month, day) => {
    const d = new Date(year, month, day);
    const t = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    return d < t;
  };

  const isToday = (year, month, day) =>
    year === today.getFullYear() && month === today.getMonth() && day === today.getDate();

  const cellSize = density === 'compact' ? 40 : 56;
  const gap = density === 'compact' ? 4 : 6;

  return (
    <div>
      {/* Court tabs */}
      <div style={{
        display: 'flex', flexWrap: 'wrap', gap: 8,
        padding: 6, borderRadius: 999, background: 'var(--surface-1)',
        boxShadow: 'inset 0 0 0 1px var(--hair-2)', marginBottom: 24, width: 'fit-content',
      }}>
        {courts.map(c => {
          const active = c.id === activeCourtId;
          return (
            <button
              key={c.id}
              onClick={() => onCourtChange(c.id)}
              style={{
                padding: '12px 20px', borderRadius: 999,
                background: active ? 'var(--accent)' : 'transparent',
                color: active ? 'var(--accent-ink)' : 'var(--fill-secondary)',
                fontWeight: 800, fontSize: 14, letterSpacing: '0.02em',
                transition: 'background 200ms ease, color 200ms ease',
              }}
            >
              {c.name}
              <span style={{
                marginLeft: 8, opacity: 0.7, fontWeight: 600, fontSize: 12,
              }} className="num">
                ${(prices[c.id] ?? c.price).toLocaleString('es-AR')}/h
              </span>
            </button>
          );
        })}
      </div>

      {/* Header / nav */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, flexWrap: 'wrap', gap: 12 }}>
        <div>
          <div className="eyebrow" style={{ marginBottom: 6 }}>Disponibilidad — {activeCourt.name}</div>
          <div className="h-display" style={{ fontSize: 'clamp(32px, 4vw, 48px)' }}>
            {MONTHS_ES[cursor.month]} <span style={{ color: 'var(--fill-tertiary)' }}>{cursor.year}</span>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <button
            onClick={goPrev}
            style={{
              width: 44, height: 44, borderRadius: 999,
              background: 'var(--surface-2)', boxShadow: 'inset 0 0 0 1px var(--hair-3)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}
            aria-label="Mes anterior"
          ><Icon name="arrow-left" size={18}/></button>
          <button
            onClick={goNext}
            style={{
              width: 44, height: 44, borderRadius: 999,
              background: 'var(--surface-2)', boxShadow: 'inset 0 0 0 1px var(--hair-3)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}
            aria-label="Mes siguiente"
          ><Icon name="arrow-right" size={18}/></button>
        </div>
      </div>

      {/* Legend */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 16, marginBottom: 20, fontSize: 13, color: 'var(--fill-tertiary)' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'var(--accent)' }}/>Libre
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'var(--warn)' }}/>Quedan pocos
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 10, height: 10, borderRadius: '50%', background: 'var(--live)' }}/>Completo
        </span>
      </div>

      {/* Day-of-week labels */}
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap,
        marginBottom: 8,
      }}>
        {DAYS_ES.map(d => (
          <div key={d} style={{
            textAlign: 'center', fontSize: 11, fontWeight: 800,
            letterSpacing: '0.12em', textTransform: 'uppercase',
            color: 'var(--fill-tertiary)', padding: '6px 0',
          }}>{d}</div>
        ))}
      </div>

      {/* Grid of day chips */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap }}>
        {cells.map((cell, idx) => {
          const past = isPast(cell.year, cell.month, cell.d);
          const today = isToday(cell.year, cell.month, cell.d);
          const iso = toISO(cell.year, cell.month, cell.d);
          const av = dayAvailability(activeCourtId, cell.year, cell.month, cell.d, bookings);
          const ratio = av.free / av.total;
          let dot = 'disp';
          if (av.free === 0) dot = 'full';
          else if (av.free <= 3) dot = 'low';

          const isSelected = selected.date === iso;
          const isExpanded = expandedDay === iso;
          const disabled = cell.outside || past;

          const ring = isSelected
            ? 'var(--accent)'
            : isExpanded
              ? 'var(--accent)'
              : today
                ? 'var(--hair-4)'
                : 'transparent';

          const dotColor = dot === 'full' ? 'var(--live)' : dot === 'low' ? 'var(--warn)' : 'var(--accent)';

          return (
            <button
              key={idx}
              disabled={disabled}
              onClick={() => {
                if (disabled) return;
                setExpandedDay(prev => prev === iso ? null : iso);
                onSelect({ date: iso, hour: null });
              }}
              style={{
                aspectRatio: '1 / 1',
                minHeight: cellSize, position: 'relative',
                borderRadius: density === 'compact' ? 12 : 18,
                background: cell.outside
                  ? 'transparent'
                  : disabled
                    ? 'rgba(255,255,255,0.02)'
                    : isSelected
                      ? 'rgba(90,247,169,0.16)'
                      : 'var(--surface-1)',
                boxShadow: `inset 0 0 0 ${isSelected || isExpanded ? 1.5 : 1}px ${ring === 'transparent' ? 'var(--hair-2)' : ring}`,
                color: cell.outside ? 'var(--fill-disabled)' : past ? 'var(--fill-disabled)' : 'var(--fill-primary)',
                display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
                gap: 4, cursor: disabled ? 'default' : 'pointer',
                transition: 'background 150ms ease, box-shadow 150ms ease, transform 150ms ease',
              }}
              onMouseEnter={e => { if (!disabled && !isSelected) e.currentTarget.style.background = 'var(--surface-2)'; }}
              onMouseLeave={e => { if (!disabled && !isSelected) e.currentTarget.style.background = 'var(--surface-1)'; }}
            >
              <span className="num" style={{
                fontSize: density === 'compact' ? 14 : 18,
                fontWeight: today ? 900 : 700,
                fontStyle: today ? 'italic' : 'normal',
              }}>{cell.d}</span>
              {!cell.outside && !past && (
                <span style={{
                  display: 'flex', gap: 3, marginTop: 2,
                }}>
                  <span style={{ width: 5, height: 5, borderRadius: '50%', background: dotColor }}/>
                  {density !== 'compact' && (
                    <span style={{
                      fontSize: 9, color: 'var(--fill-tertiary)', fontWeight: 700, letterSpacing: '0.04em',
                      marginLeft: 2,
                    }}>
                      {av.free}
                    </span>
                  )}
                </span>
              )}
              {today && (
                <span style={{
                  position: 'absolute', top: 4, right: 6,
                  fontSize: 8, fontWeight: 900, letterSpacing: '0.1em',
                  color: 'var(--accent)',
                }}>HOY</span>
              )}
            </button>
          );
        })}
      </div>

      {/* Expanded day: hour slots */}
      {expandedDay && (
        <div className="fade-slide" style={{
          marginTop: 24, padding: 20, borderRadius: 20,
          background: 'var(--surface-1)', boxShadow: 'inset 0 0 0 1px var(--hair-3)',
        }}>
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            marginBottom: 16, gap: 12, flexWrap: 'wrap',
          }}>
            <div>
              <div className="eyebrow eyebrow-muted">Turnos disponibles</div>
              <div style={{ fontWeight: 800, fontSize: 22, marginTop: 4 }}>
                {formatDateLong(expandedDay)}
              </div>
            </div>
            <button
              onClick={() => setExpandedDay(null)}
              style={{
                width: 36, height: 36, borderRadius: 999,
                background: 'var(--surface-2)', boxShadow: 'inset 0 0 0 1px var(--hair-3)',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              }}
              aria-label="Cerrar"
            ><Icon name="close" size={16}/></button>
          </div>

          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(96px, 1fr))', gap: 8,
          }}>
            {HOURS.map(h => {
              const key = `${activeCourtId}|${expandedDay}|${h}`;
              const status = bookings[key] || defaultStatus(activeCourtId, expandedDay, h);
              const isSel = selected.date === expandedDay && selected.hour === h;
              const occ = status === 'reservado';
              return (
                <button
                  key={h}
                  disabled={occ}
                  onClick={() => onSelect({ date: expandedDay, hour: h })}
                  style={{
                    padding: '12px 10px',
                    borderRadius: 12,
                    background: isSel ? 'var(--accent)' : occ ? 'rgba(244,63,94,0.08)' : 'var(--surface-2)',
                    color: isSel ? 'var(--accent-ink)' : occ ? 'var(--fill-disabled)' : 'var(--fill-primary)',
                    boxShadow: `inset 0 0 0 1px ${isSel ? 'transparent' : occ ? 'rgba(244,63,94,0.25)' : 'var(--hair-3)'}`,
                    fontWeight: 800, fontSize: 14, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
                    textDecoration: occ ? 'line-through' : 'none',
                    transition: 'all 150ms ease',
                    cursor: occ ? 'not-allowed' : 'pointer',
                  }}
                >
                  <span className="num" style={{ fontSize: 16 }}>{h}</span>
                  <span style={{
                    fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase',
                    color: isSel ? 'var(--accent-ink)' : occ ? 'var(--live)' : 'var(--fill-tertiary)',
                  }}>
                    {occ ? 'Ocupado' : `$${(prices[activeCourtId] ?? activeCourt.price).toLocaleString('es-AR')}`}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

function formatDateLong(iso) {
  const [y, m, d] = iso.split('-').map(Number);
  const date = new Date(y, m - 1, d);
  const dow = ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'][date.getDay()];
  return `${dow} ${d} de ${MONTHS_ES[m-1]}`;
}

Object.assign(window, { Calendar, HOURS, DAYS_ES, MONTHS_ES, defaultStatus, hashSeed, formatDateLong, toISO });
