// features.jsx — Voice modal, WhatsApp share, Partner sync, Caregiver mode, Themes

// ─────────────────────────────────────────────────────────────
// Color palettes — base hue swaps for the whole app
// ─────────────────────────────────────────────────────────────
const PALETTES = {
  rosa: {
    label: 'Rosa',
    light: {
      bg: '#FAF6F6', surface: '#FFFFFF', surfaceAlt: '#FFF0F5',
      text: '#1F1515', textSoft: '#75605F',
      border: '#EDE0E0', borderSoft: '#F5EBEB',
      primary: '#C9626B', primarySoft: '#FFF0F5', primaryBorder: '#FFB8CC',
    },
    dark: {
      bg: '#1A1212', surface: '#241818', surfaceAlt: '#2E1E22',
      text: '#F5ECEC', textSoft: '#A8908F',
      border: '#3A2828', borderSoft: '#2E1E1E',
      primary: '#E07882', primarySoft: '#3A1F25', primaryBorder: '#5C2F38',
    },
    bodyBg: 'radial-gradient(ellipse at top, #F5E9EC 0%, #E8D8DC 60%, #DEC9CE 100%)',
  },
  morado: {
    label: 'Morado',
    light: {
      bg: '#F8F5FB', surface: '#FFFFFF', surfaceAlt: '#F3EEFF',
      text: '#1E1626', textSoft: '#6F5E83',
      border: '#E5DAEF', borderSoft: '#EFE6F6',
      primary: '#7A4DB5', primarySoft: '#F3EEFF', primaryBorder: '#CEBDFF',
    },
    dark: {
      bg: '#15101A', surface: '#1F1726', surfaceAlt: '#2A1E36',
      text: '#F0EAF7', textSoft: '#A395B5',
      border: '#352845', borderSoft: '#241B30',
      primary: '#A78AD5', primarySoft: '#2B1F3F', primaryBorder: '#4A3766',
    },
    bodyBg: 'radial-gradient(ellipse at top, #EFE6F6 0%, #DCCBEC 60%, #C9B4E0 100%)',
  },
  verde: {
    label: 'Verde',
    light: {
      bg: '#F4F8F5', surface: '#FFFFFF', surfaceAlt: '#E8F2EC',
      text: '#142018', textSoft: '#5F7568',
      border: '#D8E6DC', borderSoft: '#E6EFEA',
      primary: '#3E8A6A', primarySoft: '#E8F2EC', primaryBorder: '#B0D8C0',
    },
    dark: {
      bg: '#0F1714', surface: '#16201B', surfaceAlt: '#1D2C24',
      text: '#E8F1EC', textSoft: '#90A89A',
      border: '#26352D', borderSoft: '#1A2520',
      primary: '#5BAB85', primarySoft: '#1A2F25', primaryBorder: '#2E5443',
    },
    bodyBg: 'radial-gradient(ellipse at top, #E5EFE8 0%, #D0DFD5 60%, #BBCEC2 100%)',
  },
};

function makeTheme(paletteId, dark, customColor) {
  let p = PALETTES[paletteId] || PALETTES.rosa;
  let base = dark ? { ...p.dark } : { ...p.light };
  // Custom hue override — recompute primary tokens from a single hex
  if (paletteId === 'custom' && customColor) {
    const c = customColor;
    base = {
      ...base,
      primary: c,
      primarySoft: dark ? shadeHex(c, -0.55) : shadeHex(c, 0.85),
      primaryBorder: dark ? shadeHex(c, -0.35) : shadeHex(c, 0.55),
    };
  }
  return {
    ...base,
    palette: paletteId,
    customColor,
    secondary: '#E8789B',
    whatsapp: '#25D366',
    shadow: dark ? '0 1px 2px rgba(0,0,0,0.3)' : '0 1px 2px rgba(31,21,21,0.04)',
    overlay: dark ? 'rgba(0,0,0,0.65)' : 'rgba(31,21,21,0.45)',
  };
}

// Mezcla un hex con blanco (percent > 0) o negro (percent < 0).
// percent en [-1, 1]. 0 = sin cambio.
function shadeHex(hex, percent) {
  const h = hex.replace('#', '');
  const full = h.length === 3 ? h.split('').map(c => c + c).join('') : h;
  const r = parseInt(full.slice(0, 2), 16);
  const g = parseInt(full.slice(2, 4), 16);
  const b = parseInt(full.slice(4, 6), 16);
  const mix = (c) => {
    const target = percent > 0 ? 255 : 0;
    const amt = Math.abs(percent);
    return Math.round(c + (target - c) * amt);
  };
  const toHex = (n) => n.toString(16).padStart(2, '0');
  return '#' + toHex(mix(r)) + toHex(mix(g)) + toHex(mix(b));
}

// Construye un gradiente de header derivado del color primario del tema.
// Sutil: top ~15% más claro, bottom ~12% más oscuro. Mantiene el matiz.
function headerGradient(theme, dark) {
  const c = theme.primary;
  const top = dark ? shadeHex(c, -0.05) : shadeHex(c, 0.18);
  const bot = dark ? shadeHex(c, -0.45) : shadeHex(c, -0.10);
  return `linear-gradient(160deg, ${top} 0%, ${bot} 100%)`;
}

// ─────────────────────────────────────────────────────────────
// Voice modal — animated waveform + simulated transcription
// ─────────────────────────────────────────────────────────────
function VoiceModal({ open, onClose, theme, onTranscript }) {
  const [phase, setPhase] = React.useState('listening'); // listening | thinking | result
  const [transcript, setTranscript] = React.useState('');
  const [bars, setBars] = React.useState(() => Array(24).fill(0.3));
  const animRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    setPhase('listening');
    setTranscript('');

    // Animate waveform bars
    let frame = 0;
    const tick = () => {
      frame++;
      setBars(prev => prev.map((_, i) => {
        const t = frame * 0.08 + i * 0.4;
        const base = 0.25 + Math.abs(Math.sin(t)) * 0.55 + Math.random() * 0.18;
        return Math.min(1, base);
      }));
      animRef.current = requestAnimationFrame(tick);
    };
    animRef.current = requestAnimationFrame(tick);

    // After 2.4s, "transcribe"
    const t1 = setTimeout(() => {
      cancelAnimationFrame(animRef.current);
      setBars(Array(24).fill(0.15));
      setPhase('thinking');
      const phrases = [
        'Acordarme de comprar leche y pan mañana',
        'Llamar al pediatra antes del viernes',
        'Pago de la colegiatura el día 15',
        'Junta del kinder el jueves a las 6',
      ];
      const pick = phrases[Math.floor(Math.random() * phrases.length)];
      setTimeout(() => {
        setTranscript(pick);
        setPhase('result');
      }, 700);
    }, 2400);

    return () => {
      cancelAnimationFrame(animRef.current);
      clearTimeout(t1);
    };
  }, [open]);

  const accept = () => {
    if (transcript) onTranscript(transcript);
    onClose();
  };

  return (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 200,
      pointerEvents: open ? 'auto' : 'none',
    }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0,
        background: theme.overlay,
        opacity: open ? 1 : 0,
        transition: 'opacity .25s ease',
      }} />
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        background: '#3D2A2A', color: 'white',
        borderTopLeftRadius: 24, borderTopRightRadius: 24,
        padding: '24px 22px 32px',
        transform: open ? 'translateY(0)' : 'translateY(100%)',
        transition: 'transform .35s cubic-bezier(.3,.7,.4,1)',
        boxShadow: '0 -10px 40px rgba(0,0,0,0.3)',
      }}>
        {/* Handle */}
        <div style={{
          width: 36, height: 4, borderRadius: 2,
          background: 'rgba(255,255,255,0.25)',
          margin: '0 auto 18px',
        }} />

        {/* Status */}
        <div style={{
          fontSize: 11, fontWeight: 700, letterSpacing: 1.4,
          color: 'rgba(255,255,255,0.5)', textAlign: 'center',
          textTransform: 'uppercase', marginBottom: 10,
        }}>
          {phase === 'listening' ? '●' :
           phase === 'thinking'  ? '○ Procesando' :
                                   '✓ Listo'}
        </div>

        {phase !== 'listening' && (
          <React.Fragment>
            <div style={{
              fontSize: 22, fontWeight: 700, letterSpacing: -0.5,
              textAlign: 'center', marginBottom: 4, lineHeight: 1.25,
            }}>
              {phase === 'thinking' ? 'Un segundo' : 'Esto entendí'}
            </div>
            <div style={{
              fontSize: 13, color: 'rgba(255,255,255,0.55)', textAlign: 'center',
              marginBottom: 22, letterSpacing: -0.1,
            }}>
              {phase === 'thinking' ? 'Procesando lo que dijiste' : 'Confirma o vuelve a grabar'}
            </div>
          </React.Fragment>
        )}

        {/* Waveform / transcript */}
        <div style={{
          background: 'rgba(255,255,255,0.06)',
          border: '1px solid rgba(255,255,255,0.10)',
          borderRadius: 18, padding: '22px 20px',
          minHeight: 90, marginBottom: 18,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          {phase === 'result' ? (
            <div style={{
              fontSize: 16, fontWeight: 500, letterSpacing: -0.2,
              lineHeight: 1.4, textAlign: 'center', color: 'white',
            }}>"{transcript}"</div>
          ) : (
            <div style={{
              display: 'flex', alignItems: 'center', gap: 3,
              height: 56, width: '100%', justifyContent: 'center',
            }}>
              {bars.map((h, i) => (
                <div key={i} style={{
                  width: 4, borderRadius: 2,
                  height: `${Math.max(8, h * 56)}px`,
                  background: phase === 'listening'
                    ? `rgba(255, ${220 - h * 60}, ${200 - h * 60}, ${0.5 + h * 0.5})`
                    : 'rgba(255,255,255,0.3)',
                  transition: phase === 'thinking' ? 'height .3s ease' : 'none',
                }} />
              ))}
            </div>
          )}
        </div>

        {/* Actions */}
        {phase === 'result' ? (
          <div style={{ display: 'flex', gap: 10 }}>
            <button onClick={() => { setPhase('listening'); setTranscript(''); }}
              style={voiceBtn('ghost')}>↻ Otra vez</button>
            <button onClick={accept} style={voiceBtn('primary')}>
              ✓ Agregar tarea
            </button>
          </div>
        ) : (
          <button onClick={onClose} style={voiceBtn('ghost')}>Cancelar</button>
        )}
      </div>
    </div>
  );
}

function voiceBtn(kind) {
  const base = {
    appearance: 'none', cursor: 'pointer', flex: 1,
    border: 'none', borderRadius: 14, padding: '13px',
    fontSize: 14, fontWeight: 700, fontFamily: 'inherit',
    letterSpacing: -0.1,
  };
  if (kind === 'primary') return { ...base, background: 'white', color: '#3D2A2A' };
  return { ...base, background: 'rgba(255,255,255,0.10)', color: 'rgba(255,255,255,0.85)' };
}

// ─────────────────────────────────────────────────────────────
// WhatsApp share — compose a message and open wa.me link
// ─────────────────────────────────────────────────────────────
function buildWhatsAppMessage(task, family) {
  const member = family.find(m => m.id === task.who);
  const p = PILLARS[task.pillar];
  const when = task.time ? `${relativeDay(task.date)} a las ${fmtTime(task.time)}` : relativeDay(task.date);
  const lines = [
    `🌸 *${task.title}*`,
    `📅 ${when}`,
    p ? `🏷️ ${p.label}` : null,
    member && member.id !== 'me' ? `👤 ${member.name}` : null,
    '',
    'Te lo paso por MamaFlow — confirmas y listo.',
  ].filter(Boolean);
  return lines.join('\n');
}

function shareTaskOnWhatsApp(task, family) {
  const msg = buildWhatsAppMessage(task, family);
  const url = `https://wa.me/?text=${encodeURIComponent(msg)}`;
  try { window.open(url, '_blank'); }
  catch { alert('No se pudo abrir WhatsApp:\n\n' + msg); }
}

// ─────────────────────────────────────────────────────────────
// Recurring rule helper — humanize a rule into Spanish
// ─────────────────────────────────────────────────────────────
const WEEKDAY_SHORT = ['D','L','M','X','J','V','S'];
const WEEKDAY_NAMES = ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'];
const ORDINALS = ['', 'primer', 'segundo', 'tercer', 'cuarto', 'último'];

function describeRule(rule) {
  if (!rule || rule === null) return null;
  if (typeof rule === 'string') {
    if (rule === 'daily') return 'Cada día';
    if (rule === 'weekdays') return 'Lunes a viernes';
    if (rule === 'weekly') return 'Cada semana';
    return rule;
  }
  // Rich rule object
  if (rule.kind === 'every-n-days') return `Cada ${rule.n} día${rule.n === 1 ? '' : 's'}`;
  if (rule.kind === 'every-weekday') {
    if (!rule.days || rule.days.length === 0) return 'Cada semana';
    if (rule.days.length === 1) return `Cada ${WEEKDAY_NAMES[rule.days[0]]}`;
    if (rule.days.length === 7) return 'Cada día';
    const sorted = [...rule.days].sort((a, b) => a - b);
    if (sorted.join(',') === '1,2,3,4,5') return 'Lunes a viernes';
    if (sorted.join(',') === '0,6') return 'Fin de semana';
    return sorted.map(d => WEEKDAY_NAMES[d]).join(', ');
  }
  if (rule.kind === 'nth-weekday') {
    // e.g. primer lunes del mes
    const which = ORDINALS[rule.nth] || '';
    return `${which} ${WEEKDAY_NAMES[rule.day]} del mes`;
  }
  if (rule.kind === 'monthly-day') {
    return `Día ${rule.day} de cada mes`;
  }
  return 'Personalizado';
}

// Compute next instance date for a rule, given current iso date
function nextInstance(rule, currentISO) {
  const d = new Date(currentISO + 'T12:00:00');
  if (!rule) return null;
  if (rule === 'daily')    { d.setDate(d.getDate() + 1); return d.toISOString().slice(0, 10); }
  if (rule === 'weekdays') {
    do { d.setDate(d.getDate() + 1); } while (d.getDay() === 0 || d.getDay() === 6);
    return d.toISOString().slice(0, 10);
  }
  if (rule === 'weekly')   { d.setDate(d.getDate() + 7); return d.toISOString().slice(0, 10); }

  if (rule.kind === 'every-n-days') {
    d.setDate(d.getDate() + (rule.n || 1));
    return d.toISOString().slice(0, 10);
  }
  if (rule.kind === 'every-weekday') {
    if (!rule.days || rule.days.length === 0) return null;
    for (let i = 1; i <= 14; i++) {
      d.setDate(d.getDate() + 1);
      if (rule.days.includes(d.getDay())) return d.toISOString().slice(0, 10);
    }
    return null;
  }
  if (rule.kind === 'nth-weekday') {
    // Find next occurrence of nth weekday in next month (or this month if not passed yet)
    const probe = new Date(d); probe.setDate(1);
    for (let m = 0; m < 3; m++) {
      const monthDate = nthWeekdayOfMonth(probe.getFullYear(), probe.getMonth(), rule.nth, rule.day);
      if (monthDate && monthDate > d) return monthDate.toISOString().slice(0, 10);
      probe.setMonth(probe.getMonth() + 1);
    }
    return null;
  }
  if (rule.kind === 'monthly-day') {
    const probe = new Date(d.getFullYear(), d.getMonth() + 1, 1, 12, 0, 0);
    const lastDay = new Date(probe.getFullYear(), probe.getMonth() + 1, 0).getDate();
    probe.setDate(Math.min(rule.day, lastDay));
    return probe.toISOString().slice(0, 10);
  }
  return null;
}

function nthWeekdayOfMonth(year, month, nth, weekday) {
  if (nth === 5) {
    // "último" — find last occurrence
    const last = new Date(year, month + 1, 0, 12, 0, 0);
    let day = last.getDate();
    while (new Date(year, month, day, 12).getDay() !== weekday) day--;
    return new Date(year, month, day, 12, 0, 0);
  }
  const first = new Date(year, month, 1, 12, 0, 0);
  const offset = (weekday - first.getDay() + 7) % 7;
  const day = 1 + offset + (nth - 1) * 7;
  const lastDay = new Date(year, month + 1, 0).getDate();
  if (day > lastDay) return null;
  return new Date(year, month, day, 12, 0, 0);
}

// ─────────────────────────────────────────────────────────────
// Recurring rule editor — used inside NewTask + TaskDetail
// ─────────────────────────────────────────────────────────────
function RecurringEditor({ value, onChange, theme }) {
  const rule = value || null;
  const [advanced, setAdvanced] = React.useState(
    typeof rule === 'object' && rule !== null
  );

  const presets = [
    { id: null,        label: 'No' },
    { id: 'daily',     label: 'Cada día' },
    { id: 'weekdays',  label: 'L-V' },
    { id: 'weekly',    label: 'Semanal' },
  ];

  return (
    <div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 8 }}>
        {presets.map(o => {
          const isActive = !advanced && (rule || null) === o.id;
          return (
            <button key={String(o.id)}
              onClick={() => { setAdvanced(false); onChange(o.id); }}
              style={{
                appearance: 'none', cursor: 'pointer',
                padding: '7px 12px', borderRadius: 999,
                background: isActive ? theme.primarySoft : 'transparent',
                color: isActive ? theme.primary : theme.textSoft,
                border: `1px solid ${isActive ? theme.primaryBorder : theme.border}`,
                fontSize: 12, fontWeight: 600, fontFamily: 'inherit',
              }}>{o.label}</button>
          );
        })}
        <button onClick={() => setAdvanced(!advanced)}
          style={{
            appearance: 'none', cursor: 'pointer',
            padding: '7px 12px', borderRadius: 999,
            background: advanced ? theme.primarySoft : 'transparent',
            color: advanced ? theme.primary : theme.textSoft,
            border: `1px solid ${advanced ? theme.primaryBorder : theme.border}`,
            fontSize: 12, fontWeight: 600, fontFamily: 'inherit',
          }}>Más opciones…</button>
      </div>

      {advanced && (
        <div style={{
          background: theme.surfaceAlt, border: `1px solid ${theme.borderSoft}`,
          borderRadius: 12, padding: 12, marginTop: 6,
          display: 'flex', flexDirection: 'column', gap: 10,
        }}>
          <RuleKindSelector rule={rule} onChange={onChange} theme={theme} />
        </div>
      )}

      {rule && (
        <div style={{
          fontSize: 11.5, color: theme.textSoft, marginTop: 8,
          fontStyle: 'italic',
        }}>
          → {describeRule(rule)}
        </div>
      )}
    </div>
  );
}

function RuleKindSelector({ rule, onChange, theme }) {
  const kind = (typeof rule === 'object' && rule?.kind) || 'every-weekday';
  const kinds = [
    { id: 'every-weekday', label: 'Días de la semana' },
    { id: 'every-n-days',  label: 'Cada N días' },
    { id: 'nth-weekday',   label: 'Primer lunes…' },
    { id: 'monthly-day',   label: 'Día N del mes' },
  ];

  const setKind = (k) => {
    if (k === 'every-weekday')  onChange({ kind: 'every-weekday', days: [1, 3, 5] });
    else if (k === 'every-n-days') onChange({ kind: 'every-n-days', n: 3 });
    else if (k === 'nth-weekday')  onChange({ kind: 'nth-weekday', nth: 1, day: 1 });
    else onChange({ kind: 'monthly-day', day: 15 });
  };

  return (
    <>
      <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
        {kinds.map(k => (
          <button key={k.id} onClick={() => setKind(k.id)}
            style={{
              appearance: 'none', cursor: 'pointer',
              padding: '6px 10px', borderRadius: 8,
              background: kind === k.id ? theme.primary : 'transparent',
              color: kind === k.id ? 'white' : theme.textSoft,
              border: `1px solid ${kind === k.id ? theme.primary : theme.border}`,
              fontSize: 11.5, fontWeight: 600, fontFamily: 'inherit',
            }}>{k.label}</button>
        ))}
      </div>

      {kind === 'every-weekday' && rule?.days && (
        <div style={{ display: 'flex', gap: 4, justifyContent: 'space-between' }}>
          {WEEKDAY_SHORT.map((label, i) => {
            const on = rule.days.includes(i);
            return (
              <button key={i} onClick={() => {
                const days = on ? rule.days.filter(x => x !== i) : [...rule.days, i];
                onChange({ ...rule, days });
              }} style={{
                appearance: 'none', cursor: 'pointer', flex: 1,
                aspectRatio: '1 / 1', maxWidth: 36,
                borderRadius: '50%',
                background: on ? theme.primary : 'transparent',
                color: on ? 'white' : theme.textSoft,
                border: `1px solid ${on ? theme.primary : theme.border}`,
                fontSize: 12, fontWeight: 700, fontFamily: 'inherit',
              }}>{label}</button>
            );
          })}
        </div>
      )}

      {kind === 'every-n-days' && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontSize: 12.5, color: theme.text }}>Cada</span>
          <input type="number" min="1" max="60"
            value={rule?.n || 3}
            onChange={(e) => onChange({ kind: 'every-n-days', n: Math.max(1, parseInt(e.target.value || '1')) })}
            style={{
              width: 56, padding: '7px 10px', textAlign: 'center',
              background: theme.surface, border: `1px solid ${theme.border}`,
              borderRadius: 8, fontSize: 14, fontWeight: 700, color: theme.text,
              fontFamily: 'inherit', outline: 'none',
            }} />
          <span style={{ fontSize: 12.5, color: theme.text }}>días</span>
        </div>
      )}

      {kind === 'nth-weekday' && (
        <div style={{ display: 'flex', gap: 6 }}>
          <select value={rule?.nth || 1}
            onChange={(e) => onChange({ ...rule, nth: parseInt(e.target.value) })}
            style={selectStyle(theme)}>
            <option value="1">Primer</option>
            <option value="2">Segundo</option>
            <option value="3">Tercer</option>
            <option value="4">Cuarto</option>
            <option value="5">Último</option>
          </select>
          <select value={rule?.day ?? 1}
            onChange={(e) => onChange({ ...rule, day: parseInt(e.target.value) })}
            style={selectStyle(theme)}>
            {WEEKDAY_NAMES.map((n, i) => (
              <option key={i} value={i}>{n}</option>
            ))}
          </select>
          <span style={{ fontSize: 12.5, color: theme.textSoft, alignSelf: 'center' }}>del mes</span>
        </div>
      )}

      {kind === 'monthly-day' && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontSize: 12.5, color: theme.text }}>El día</span>
          <input type="number" min="1" max="31"
            value={rule?.day || 1}
            onChange={(e) => onChange({ kind: 'monthly-day', day: Math.max(1, Math.min(31, parseInt(e.target.value || '1'))) })}
            style={{
              width: 56, padding: '7px 10px', textAlign: 'center',
              background: theme.surface, border: `1px solid ${theme.border}`,
              borderRadius: 8, fontSize: 14, fontWeight: 700, color: theme.text,
              fontFamily: 'inherit', outline: 'none',
            }} />
          <span style={{ fontSize: 12.5, color: theme.text }}>de cada mes</span>
        </div>
      )}
    </>
  );
}

function selectStyle(theme) {
  return {
    background: theme.surface, border: `1px solid ${theme.border}`,
    borderRadius: 8, padding: '7px 10px',
    fontSize: 12.5, color: theme.text, fontFamily: 'inherit',
    outline: 'none',
  };
}

// ─────────────────────────────────────────────────────────────
// Member day sheet — ve el día de un familiar al tap en su avatar
// ─────────────────────────────────────────────────────────────
function PartnerSyncSheet({ memberId, onClose, theme, family, tasks, onToggle, onShareToPartner }) {
  const open = !!memberId;
  const partner = family.find(m => m.id === memberId);
  const [tick, setTick] = React.useState(0);
  // Simulate live updates every 8s while open
  React.useEffect(() => {
    if (!open) return;
    const id = setInterval(() => setTick(t => t + 1), 8000);
    return () => clearInterval(id);
  }, [open]);

  if (!partner) return <Sheet open={false} onClose={onClose} theme={theme} />;

  const today = todayISO();
  const partnerTasks = tasks.filter(t => t.who === partner.id);
  const todayP = partnerTasks.filter(t => t.date === today);
  const upcomingP = partnerTasks.filter(t => t.date > today).slice(0, 4);
  const doneToday = todayP.filter(t => t.done).length;
  const myTasksToShare = tasks.filter(t => t.who === 'me' && !t.done && t.date === today);

  return (
    <Sheet open={open} onClose={onClose} theme={theme} title={`Día de ${partner.name}`} maxHeight="90%">
      <div style={{ padding: '0 18px 18px', display: 'flex', flexDirection: 'column', gap: 16 }}>
        {/* Live status header */}
        <div style={{
          background: theme.surfaceAlt, border: `1px solid ${theme.borderSoft}`,
          borderRadius: 14, padding: '14px 16px',
          display: 'flex', alignItems: 'center', gap: 12,
        }}>
          <Avatar member={partner} size={44} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 6,
              fontSize: 13, fontWeight: 700, color: theme.text,
            }}>
              {partner.name}
              <span style={{
                width: 6, height: 6, borderRadius: '50%',
                background: '#1F8A5B',
                boxShadow: '0 0 0 3px rgba(31,138,91,0.18)',
                animation: 'mf-pulse 1.8s ease-in-out infinite',
              }} />
              <span style={{ fontSize: 10, color: theme.textSoft, fontWeight: 500 }}>en línea</span>
            </div>
            <div style={{ fontSize: 11.5, color: theme.textSoft, marginTop: 2 }}>
              {doneToday > 0
                ? `Lleva ${doneToday} de ${todayP.length} hoy`
                : todayP.length > 0
                  ? `${todayP.length} pendientes hoy`
                  : 'Sin tareas asignadas hoy'}
            </div>
          </div>
          <button onClick={() => alert('Ping enviado a ' + partner.name)}
            style={{
              appearance: 'none', cursor: 'pointer',
              background: 'transparent', border: `1px solid ${theme.border}`,
              borderRadius: 10, padding: '7px 12px',
              fontSize: 11.5, fontWeight: 700, color: theme.textSoft,
              fontFamily: 'inherit',
            }}>👋 Ping</button>
        </div>

        {/* What they're doing today */}
        <div>
          <SectionCaps theme={theme}>Su día — hoy</SectionCaps>
          {todayP.length === 0 ? (
            <div style={{
              fontSize: 13, color: theme.textSoft,
              background: theme.surface, border: `1px solid ${theme.border}`,
              borderRadius: 12, padding: '14px 16px', textAlign: 'center',
            }}>Sin nada asignado hoy</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {todayP.map(t => (
                <PartnerTaskRow key={t.id} task={t} theme={theme}
                  onToggle={() => onToggle(t.id)} />
              ))}
            </div>
          )}
        </div>

        {/* Upcoming */}
        {upcomingP.length > 0 && (
          <div>
            <SectionCaps theme={theme}>Próximos días</SectionCaps>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {upcomingP.map(t => (
                <PartnerTaskRow key={t.id} task={t} theme={theme} compact />
              ))}
            </div>
          </div>
        )}

        {/* Share to partner */}
        {myTasksToShare.length > 0 && (
          <div>
            <SectionCaps theme={theme}>Pasar a {partner.name}</SectionCaps>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {myTasksToShare.slice(0, 4).map(t => (
                <button key={t.id} onClick={() => onShareToPartner(t.id)}
                  style={{
                    appearance: 'none', cursor: 'pointer', textAlign: 'left',
                    background: theme.surface, border: `1px solid ${theme.border}`,
                    borderRadius: 12, padding: '11px 13px',
                    display: 'flex', alignItems: 'center', gap: 10,
                    fontFamily: 'inherit',
                  }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, color: theme.text, letterSpacing: -0.1 }}>{t.title}</div>
                    <div style={{ fontSize: 11, color: theme.textSoft, marginTop: 1 }}>
                      Pasar a {partner.name}
                    </div>
                  </div>
                  <span style={{ fontSize: 13, color: theme.primary }}>→</span>
                </button>
              ))}
            </div>
          </div>
        )}
      </div>
    </Sheet>
  );
}

function PartnerTaskRow({ task, theme, onToggle, compact }) {
  const p = PILLARS[task.pillar];
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      background: theme.surface, border: `1px solid ${theme.border}`,
      borderRadius: 12, padding: '10px 12px',
    }}>
      {!compact && (
        <Checkbox checked={task.done} onChange={onToggle}
          primary={theme.primary} border={theme.border} size={20} />
      )}
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontSize: 13, fontWeight: 600,
          color: task.done ? theme.textSoft : theme.text,
          letterSpacing: -0.1,
          textDecoration: task.done ? 'line-through' : 'none',
        }}>{task.title}</div>
        <div style={{ fontSize: 11, color: theme.textSoft, marginTop: 2, display: 'flex', gap: 8 }}>
          {task.time && <span>{fmtTime(task.time)}</span>}
          {compact && <span>· {relativeDay(task.date)}</span>}
          {p && <span style={{ color: p.text }}>· {p.label}</span>}
        </div>
      </div>
    </div>
  );
}

function SectionCaps({ theme, children }) {
  return (
    <div style={{
      fontSize: 10.5, fontWeight: 700, letterSpacing: 1.2,
      color: theme.textSoft, textTransform: 'uppercase',
      marginBottom: 8,
    }}>{children}</div>
  );
}

Object.assign(window, {
  PALETTES, makeTheme, shadeHex, headerGradient,
  VoiceModal, voiceBtn,
  buildWhatsAppMessage, shareTaskOnWhatsApp,
  WEEKDAY_SHORT, WEEKDAY_NAMES, describeRule, nextInstance,
  RecurringEditor,
  PartnerSyncSheet,
});
