/* eslint-disable */
/* Taskoo Mobile — Supabase Auth + Real-time PWA */

const { useState, useEffect, useRef, useCallback } = React;

// ─── Supabase ─────────────────────────────────────────────────────────────────

const SUPABASE_URL = 'https://folwrssovadjvbnbpitn.supabase.co';
const SUPABASE_ANON_KEY = 'sb_publishable_mnXu7RNtooZ_1quppgQ3GQ_7o712sdU';
const sb = window.supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

const COURSE_COLORS = ['#df3e3a','#f5a623','#3db87a','#60a5fa','#a78bfa','#ea72c1','#f97316','#06b6d4'];

// ─── IndexedDB Cache ──────────────────────────────────────────────────────────

function _idbOpen() {
  return new Promise((resolve, reject) => {
    const req = indexedDB.open('taskoo-idb', 1);
    req.onupgradeneeded = ({ target: { result: db } }) => {
      ['tasks', 'deadlines', 'courses'].forEach(s => {
        if (!db.objectStoreNames.contains(s)) db.createObjectStore(s, { keyPath: 'id' });
      });
      if (!db.objectStoreNames.contains('kv')) db.createObjectStore('kv');
    };
    req.onsuccess = ({ target: { result } }) => resolve(result);
    req.onerror = ({ target: { error } }) => reject(error);
  });
}

async function idbGetAll(store) {
  try {
    const db = await _idbOpen();
    return new Promise(resolve => {
      const req = db.transaction(store, 'readonly').objectStore(store).getAll();
      req.onsuccess = () => resolve(req.result || []);
      req.onerror = () => resolve([]);
    });
  } catch { return []; }
}

async function idbPutAll(store, items) {
  if (!items || !items.length) return;
  try {
    const db = await _idbOpen();
    const tx = db.transaction(store, 'readwrite');
    const s = tx.objectStore(store);
    items.forEach(item => s.put(item));
    return new Promise(r => { tx.oncomplete = r; tx.onerror = r; });
  } catch {}
}

async function idbKvGet(key) {
  try {
    const db = await _idbOpen();
    return new Promise(resolve => {
      const req = db.transaction('kv', 'readonly').objectStore('kv').get(key);
      req.onsuccess = () => resolve(req.result !== undefined ? req.result : null);
      req.onerror = () => resolve(null);
    });
  } catch { return null; }
}

async function idbKvPut(key, value) {
  try {
    const db = await _idbOpen();
    const tx = db.transaction('kv', 'readwrite');
    tx.objectStore('kv').put(value, key);
    return new Promise(r => { tx.oncomplete = r; tx.onerror = r; });
  } catch {}
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

function fmt12(t) {
  if (!t) return '';
  const [h, m] = t.split(':').map(Number);
  const ampm = h < 12 ? 'am' : 'pm';
  const h12 = h % 12 || 12;
  return m === 0 ? `${h12}${ampm}` : `${h12}:${String(m).padStart(2,'0')}${ampm}`;
}

function formatDueDate(due) {
  if (!due) return '';
  const d = new Date(due + 'T00:00:00');
  const now = new Date(); now.setHours(0,0,0,0);
  const diff = Math.round((d - now) / 86400000);
  if (diff === 0) return 'Today';
  if (diff === 1) return 'Tomorrow';
  if (diff < 0) return `Overdue ${-diff}d`;
  const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  return `${months[d.getMonth()]} ${d.getDate()}`;
}

function isDueToday(due) {
  if (!due) return false;
  const d = new Date(due + 'T00:00:00');
  const now = new Date(); now.setHours(0,0,0,0);
  return Math.round((d - now) / 86400000) <= 0;
}

function courseColor(code, courses) {
  const c = courses.find(c => c.code === code || c.name === code);
  return c?.color || 'var(--text-soft)';
}

function mapTask(t) {
  return { id: t.id, title: t.name || '', course: t.course || '', urgent: t.urgency === 'urgent', done: t.done || false };
}

function mapDeadline(d, courses) {
  return {
    id: d.id, title: d.name || '', course: d.course || '',
    color: courseColor(d.course, courses),
    due: formatDueDate(d.due_date), urgent: isDueToday(d.due_date),
    done: d.done || false, tag: 'hw'
  };
}

function groupEvents(events) {
  const grouped = {};
  for (const e of events) {
    if (!e.date) continue;
    if (!grouped[e.date]) grouped[e.date] = [];
    grouped[e.date].push({
      time: e.start_time ? fmt12(e.start_time) : 'All day',
      title: e.title || e.summary || 'Event',
      color: '#df3e3a', loc: e.location || ''
    });
  }
  return grouped;
}

// ─── Icons ────────────────────────────────────────────────────────────────────

const I_STROKE = (path) => (
  <svg viewBox="0 0 24 24" width="1em" height="1em" fill="none"
    stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
    style={{ display:'inline-block', verticalAlign:'-0.15em', flexShrink:0 }}>
    {path}
  </svg>
);
const I_FILL = (path) => (
  <svg viewBox="0 0 24 24" width="1em" height="1em" fill="currentColor"
    style={{ display:'inline-block', verticalAlign:'-0.15em', flexShrink:0 }}>
    {path}
  </svg>
);

const ICONS = {
  'home': I_STROKE(<><path d="M3 11.5L12 4l9 7.5"/><path d="M5 10v10h14V10"/></>),
  'home-fill': I_FILL(<path d="M12 3L2 11h3v10h5v-6h4v6h5V11h3L12 3z"/>),
  'calendar': I_STROKE(<><rect x="3.5" y="5" width="17" height="15" rx="2"/><path d="M3.5 10h17"/><path d="M8 3v4M16 3v4"/></>),
  'alarm': I_STROKE(<><circle cx="12" cy="13" r="7"/><path d="M12 9v4l2 2"/><path d="M5 4l-2 2M19 4l2 2"/></>),
  'timer': I_STROKE(<><circle cx="12" cy="13" r="7"/><path d="M12 13V9"/><path d="M9 3h6"/><path d="M19 6l1.5-1.5"/></>),
  'add': I_STROKE(<><path d="M12 5v14M5 12h14"/></>),
  'check': I_STROKE(<path d="M5 12l5 5L20 7"/>),
  'sparkle': I_FILL(<path d="M12 2l1.6 5.4L19 9l-5.4 1.6L12 16l-1.6-5.4L5 9l5.4-1.6L12 2zm7 11l.9 2.6L22 17l-2.1.4L19 20l-.9-2.6L16 17l2.1-.4L19 13z"/>),
  'circle-check': I_STROKE(<><circle cx="12" cy="12" r="9"/><path d="M8 12.5l3 3L16 10"/></>),
  'time': I_STROKE(<><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>),
  'fire': I_FILL(<path d="M12 2c1 4 5 5 5 10a5 5 0 11-10 0c0-2 1-3 2-4-.5 2 .5 3 2 3 0-3 1-6 1-9z"/>),
  'search': I_STROKE(<><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4 4"/></>),
  'filter': I_STROKE(<path d="M4 6h16M7 12h10M10 18h4"/>),
  'right': I_STROKE(<path d="M9 6l6 6-6 6"/>),
  'left': I_STROKE(<path d="M15 6l-6 6 6 6"/>),
  'up': I_STROKE(<path d="M6 14l6-6 6 6"/>),
  'arrow-up': I_STROKE(<><path d="M12 19V5"/><path d="M6 11l6-6 6 6"/></>),
  'target': I_STROKE(<><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1.3" fill="currentColor"/></>),
  'skip-back': I_FILL(<path d="M6 5h2v14H6V5zm13 0v14l-10-7 10-7z"/>),
  'skip-fwd': I_FILL(<path d="M16 5h2v14h-2V5zM5 5l10 7-10 7V5z"/>),
  'pause': I_FILL(<><rect x="6.5" y="5" width="3.5" height="14" rx="1"/><rect x="14" y="5" width="3.5" height="14" rx="1"/></>),
  'play': I_FILL(<path d="M7 4l13 8-13 8V4z"/>),
  'stop': I_FILL(<rect x="6" y="6" width="12" height="12" rx="1.5"/>),
  'music': I_STROKE(<><circle cx="6" cy="18" r="2.5"/><circle cx="17" cy="16" r="2.5"/><path d="M8.5 18V5l11-2v13"/></>),
  'more': I_FILL(<><circle cx="6" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="18" cy="12" r="2"/></>),
  'chart': I_STROKE(<><path d="M4 4v16h16"/><path d="M7 14l3-3 3 3 4-6"/></>),
  'trophy': I_STROKE(<><path d="M8 4h8v6a4 4 0 11-8 0V4z"/><path d="M8 6H5v2a3 3 0 003 3M16 6h3v2a3 3 0 01-3 3"/><path d="M10 16h4l1 4H9l1-4z"/></>),
  'user': I_STROKE(<><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/></>),
  'moon': I_STROKE(<path d="M20 14a8 8 0 11-10-10 6 6 0 0010 10z"/>),
  'bell': I_STROKE(<><path d="M6 16h12l-2-3v-3a4 4 0 00-8 0v3l-2 3z"/><path d="M10 19a2 2 0 004 0"/></>),
  'warning': I_STROKE(<><path d="M12 4l9 16H3l9-16z"/><path d="M12 10v4M12 17v.5"/></>),
  'refresh': I_STROKE(<><path d="M4 12a8 8 0 0114-5l2 2"/><path d="M20 4v4h-4"/><path d="M20 12a8 8 0 01-14 5l-2-2"/><path d="M4 20v-4h4"/></>),
  'close': I_STROKE(<path d="M6 6l12 12M18 6L6 18"/>),
  'settings': I_STROKE(<><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 00.3 1.8l.1.1a2 2 0 11-2.8 2.8l-.1-.1a1.7 1.7 0 00-1.8-.3 1.7 1.7 0 00-1 1.5V21a2 2 0 11-4 0v-.1a1.7 1.7 0 00-1.1-1.5 1.7 1.7 0 00-1.8.3l-.1.1a2 2 0 11-2.8-2.8l.1-.1a1.7 1.7 0 00.3-1.8 1.7 1.7 0 00-1.5-1H3a2 2 0 110-4h.1a1.7 1.7 0 001.5-1.1 1.7 1.7 0 00-.3-1.8l-.1-.1a2 2 0 112.8-2.8l.1.1a1.7 1.7 0 001.8.3H9a1.7 1.7 0 001-1.5V3a2 2 0 114 0v.1a1.7 1.7 0 001 1.5 1.7 1.7 0 001.8-.3l.1-.1a2 2 0 112.8 2.8l-.1.1a1.7 1.7 0 00-.3 1.8V9a1.7 1.7 0 001.5 1H21a2 2 0 110 4h-.1a1.7 1.7 0 00-1.5 1z"/></>),
  'logout': I_STROKE(<><path d="M14 4h4a2 2 0 012 2v12a2 2 0 01-2 2h-4"/><path d="M10 8l-4 4 4 4"/><path d="M6 12h12"/></>),
  'loop': I_STROKE(<><path d="M17 4l3 3-3 3"/><path d="M4 12V9a2 2 0 012-2h14"/><path d="M7 20l-3-3 3-3"/><path d="M20 12v3a2 2 0 01-2 2H4"/></>),
  'crown': I_FILL(<path d="M3 7l4 3 5-6 5 6 4-3-2 11H5L3 7zm3 13h12v1.5H6V20z"/>),
  'volume': I_STROKE(<><path d="M5 10v4h3l4 3V7l-4 3H5z"/><path d="M16 9c1.5 1 1.5 5 0 6M19 7c3 2 3 8 0 10"/></>),
  'note': I_STROKE(<><path d="M5 5h11l3 3v11H5V5z"/><path d="M16 5v4h4"/></>),
  'pin': I_STROKE(<><path d="M12 21s-7-6.5-7-12a7 7 0 1114 0c0 5.5-7 12-7 12z"/><circle cx="12" cy="9" r="2.5"/></>),
  'links': I_STROKE(<><path d="M10 14l4-4"/><path d="M14 7l1.5-1.5a4 4 0 015.5 5.5L19 13"/><path d="M10 17l-1.5 1.5a4 4 0 01-5.5-5.5L5 11"/></>),
  'file-paper': I_STROKE(<><path d="M6 3h8l5 5v13H6V3z"/><path d="M14 3v5h5"/><path d="M9 14h6M9 17h6M9 11h2"/></>),
  'team': I_STROKE(<><circle cx="9" cy="9" r="3.5"/><path d="M3 19c0-3 3-5 6-5s6 2 6 5"/><circle cx="17" cy="8" r="2.5"/><path d="M16 14c2.5 0 5 1.5 5 4"/></>),
  'check-double': I_STROKE(<><path d="M3 12l4 4L15 8"/><path d="M11 16l4 4L21 14"/></>),
  'mail': I_STROKE(<><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></>),
  'lock': I_STROKE(<><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 118 0v4"/></>),
  'eye': I_STROKE(<><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></>),
  'eye-off': I_STROKE(<><path d="M17.94 17.94A10 10 0 0112 19c-7 0-10-7-10-7a18 18 0 015.06-6.94M9.9 4.24A9 9 0 0112 4c7 0 10 7 10 7a18 18 0 01-2.16 3.19M1 1l22 22"/></>),
};

function Icon({ name, style, className }) {
  const svg = ICONS[name];
  if (!svg) return <span style={{ display:'inline-block', width:'1em', height:'1em', background:'currentColor', opacity:0.3, borderRadius:2, ...(style||{}) }} />;
  return React.cloneElement(svg, { style:{ ...svg.props.style, ...(style||{}) }, className });
}

// ─── Install Banner ───────────────────────────────────────────────────────────

function InstallBanner() {
  const isStandalone = window.navigator.standalone || window.matchMedia('(display-mode: standalone)').matches;
  const [dismissed, setDismissed] = useState(() => !!localStorage.getItem('ib-dismissed'));
  const [deferredPrompt, setDeferredPrompt] = useState(null);
  const [showIOSSteps, setShowIOSSteps] = useState(false);
  const isIOS = /iphone|ipad|ipod/i.test(navigator.userAgent);

  useEffect(() => {
    const handler = (e) => { e.preventDefault(); setDeferredPrompt(e); };
    window.addEventListener('beforeinstallprompt', handler);
    return () => window.removeEventListener('beforeinstallprompt', handler);
  }, []);

  if (isStandalone || dismissed) return null;
  if (!isIOS && !deferredPrompt) return null;

  const dismiss = () => { localStorage.setItem('ib-dismissed', '1'); setDismissed(true); };

  const androidInstall = async () => {
    if (!deferredPrompt) return;
    deferredPrompt.prompt();
    const { outcome } = await deferredPrompt.userChoice;
    if (outcome === 'accepted') dismiss();
    setDeferredPrompt(null);
  };

  return (
    <div className="install-overlay">
      <div className="install-sheet">
        <button className="install-close" onClick={dismiss}>
          <Icon name="close" style={{ fontSize: 18 }} />
        </button>
        <div className="install-hero">
          <img src="/apple-touch-icon.png" className="install-icon" alt="Taskoo" />
          <div>
            <div className="install-title">Add Taskoo to your Home Screen</div>
            <div className="install-sub">Full app experience — no browser bar, works offline</div>
          </div>
        </div>
        {isIOS && !showIOSSteps && (
          <button className="install-btn" onClick={() => setShowIOSSteps(true)}>Show me how</button>
        )}
        {isIOS && showIOSSteps && (
          <div className="install-steps">
            <div className="install-step">
              <div className="install-step-num">1</div>
              <div className="install-step-text">
                Tap the <strong>Share</strong> button
                <svg style={{ display:'inline-block', verticalAlign:'-0.2em', margin:'0 3px' }} viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M8 12H3v9h18v-9h-5"/><path d="M12 3v12"/><path d="M8 7l4-4 4 4"/>
                </svg>
                at the bottom of Safari
              </div>
            </div>
            <div className="install-step">
              <div className="install-step-num">2</div>
              <div className="install-step-text">Scroll down and tap <strong>"Add to Home Screen"</strong></div>
            </div>
            <div className="install-step">
              <div className="install-step-num">3</div>
              <div className="install-step-text">Tap <strong>Add</strong> — opens fullscreen like a native app</div>
            </div>
          </div>
        )}
        {!isIOS && deferredPrompt && (
          <button className="install-btn" onClick={androidInstall}>Install App</button>
        )}
        <button className="install-skip" onClick={dismiss}>Maybe later</button>
      </div>
    </div>
  );
}

// ─── Offline Banner ───────────────────────────────────────────────────────────

function OfflineBanner() {
  const [online, setOnline] = useState(navigator.onLine);
  useEffect(() => {
    const on = () => setOnline(true);
    const off = () => setOnline(false);
    window.addEventListener('online', on);
    window.addEventListener('offline', off);
    return () => { window.removeEventListener('online', on); window.removeEventListener('offline', off); };
  }, []);
  if (online) return null;
  return (
    <div className="offline-banner">
      <Icon name="warning" style={{ fontSize: 13, color: '#F59E0B', flexShrink: 0 }} />
      Offline — showing cached data
    </div>
  );
}

// ─── Loading Screen ───────────────────────────────────────────────────────────

function LoadingScreen() {
  return (
    <div className="loading-screen">
      <div className="loading-logo">
        <img src="/logo-icon.png" width="72" height="72" alt="Taskoo" style={{ borderRadius: 18, display: 'block' }} />
      </div>
      <div className="loading-dots"><span /><span /><span /></div>
    </div>
  );
}

// ─── Auth Screen ──────────────────────────────────────────────────────────────

function AuthScreen() {
  const [tab, setTab] = useState('login');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [info, setInfo] = useState('');
  const [showPw, setShowPw] = useState(false);
  const [rememberMe, setRememberMe] = useState(false);
  const [studyTips, setStudyTips] = useState(false);

  const pwStrength = password.length === 0 ? 0 : password.length < 8 ? 1 : password.length < 12 ? 2 : 3;
  const pwColors = ['', '#ef4444', '#f59e0b', '#3db87a'];
  const pwLabels = ['', 'Weak', 'Fair', 'Strong'];
  const pwWidths = ['0%', '33%', '66%', '100%'];

  const submit = async () => {
    setError(''); setInfo('');
    if (!email || !password) { setError('Please fill in all fields.'); return; }
    setLoading(true);
    if (tab === 'login') {
      const { error: e } = await sb.auth.signInWithPassword({ email, password });
      if (e) { setError(e.message); setLoading(false); }
    } else {
      if (!name.trim()) { setError('Please enter your name.'); setLoading(false); return; }
      const { error: e } = await sb.auth.signUp({ email, password, options: { data: { full_name: name } } });
      if (e) { setError(e.message); } else { setInfo('Account created! Check your email to confirm, then log in.'); setTab('login'); }
      setLoading(false);
    }
  };

  const signInWithGoogle = async () => {
    const { error: e } = await sb.auth.signInWithOAuth({
      provider: 'google',
      options: { redirectTo: window.location.origin + '/' },
    });
    if (e) setError(e.message);
  };

  const handleKey = (e) => { if (e.key === 'Enter') submit(); };

  const switchTab = (t) => { setTab(t); setError(''); setInfo(''); };

  const GoogleIcon = () => (
    <svg width="18" height="18" viewBox="0 0 18 18">
      <path fill="#4285F4" d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z"/>
      <path fill="#34A853" d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 009 18z"/>
      <path fill="#FBBC05" d="M3.964 10.71A5.41 5.41 0 013.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 000 9c0 1.452.348 2.827.957 4.042l3.007-2.332z"/>
      <path fill="#EA4335" d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 00.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z"/>
    </svg>
  );

  const AppleIcon = () => (
    <svg width="18" height="18" viewBox="0 0 18 18" fill="currentColor">
      <path d="M12.47 0c.08.95-.27 1.89-.79 2.59-.54.73-1.41 1.3-2.28 1.23-.1-.91.29-1.85.79-2.5C10.73.58 11.65.04 12.47 0zm2.66 4.7c-1.19-.74-2.54-.68-3.31-.68-.77 0-1.77.22-2.64.72C8.27 5.26 7.4 6.12 7.4 7.54c0 .79.22 1.55.59 2.22-.73 1.82-1.64 3.26-2.47 4.16-.54.59-1.02.88-1.55.88-.39 0-.76-.14-1.21-.4L2.5 14.5c-.44.26-.85.4-1.28.4-.73 0-1.22-.5-1.22-1.32 0-.35.07-.71.22-1.07.46-1.13 1.44-3.01 2.56-4.68C3.89 6.17 5.2 4.6 6.8 3.7c.86-.5 1.86-.8 2.97-.8.77 0 1.72.2 2.54.64.53.28.97.66 1.3 1.12l-.48.04z"/>
    </svg>
  );

  const LogoMark = () => (
    <div className="auth-v2-top">
      <img src="/logo-full.png" alt="Taskoo" style={{ height: 36, width: 'auto', display: 'block' }} />
    </div>
  );

  if (tab === 'login') {
    return (
      <div className="auth-v2">
        <LogoMark />
        <div className="auth-v2-body">
          <h1 className="auth-v2-heading">Welcome back.</h1>
          <p className="auth-v2-sub">Pick up where you left off. Your week is already planned.</p>

          {info && <div className="auth-v2-info">{info}</div>}
          {error && <div className="auth-v2-error">{error}</div>}

          <div className="auth-v2-label">EMAIL</div>
          <div className="auth-v2-field">
            <input className="auth-v2-input" type="email" placeholder="alex@uoft.ca" value={email}
              onChange={e => setEmail(e.target.value)} onKeyDown={handleKey} autoComplete="email" />
          </div>

          <div className="auth-v2-label">PASSWORD</div>
          <div className="auth-v2-field">
            <input className="auth-v2-input" type={showPw ? 'text' : 'password'} placeholder="••••••••" value={password}
              onChange={e => setPassword(e.target.value)} onKeyDown={handleKey} autoComplete="current-password" />
            <button type="button" onClick={() => setShowPw(v => !v)} style={{ flexShrink:0, opacity:0.5, fontSize:18 }}>
              {showPw ? '🙈' : '👁'}
            </button>
          </div>

          <div className="auth-v2-remember">
            <div className="auth-v2-remember-left" onClick={() => setRememberMe(v => !v)}>
              <div className={`auth-v2-checkbox ${rememberMe ? 'checked' : ''}`}>
                {rememberMe && <svg width="10" height="8" viewBox="0 0 10 8" fill="none"><path d="M1 4l3 3 5-6" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>}
              </div>
              Remember me
            </div>
            <button type="button" className="auth-v2-forgot">Forgot password?</button>
          </div>

          <button className="auth-v2-btn" onClick={submit} disabled={loading}>
            {loading ? '…' : 'Log in →'}
          </button>

          <div className="auth-v2-divider"><span>OR CONTINUE WITH</span></div>

          <div className="auth-v2-social">
            <button className="auth-v2-social-btn" onClick={signInWithGoogle}>
              <GoogleIcon /> Google
            </button>
            <button className="auth-v2-social-btn" onClick={() => {}}>
              <AppleIcon /> Apple
            </button>
          </div>

          <div className="auth-v2-switch">
            New to Taskoo?{' '}
            <button onClick={() => switchTab('signup')}>Create an account</button>
          </div>
        </div>
      </div>
    );
  }

  // signup view
  return (
    <div className="auth-v2">
      <LogoMark />
      <div className="auth-v2-body">
        <h1 className="auth-v2-heading">
          Start your best <span className="accent">semester.</span>
        </h1>
        <p className="auth-v2-sub">Free for students. No credit card. Just better study days.</p>

        <div className="auth-v2-pills">
          <span className="auth-v2-pill">🤖 AI study planner</span>
          <span className="auth-v2-pill">📋 All deadlines, one place</span>
          <span className="auth-v2-pill">⏱ Pomodoro built-in</span>
        </div>

        {info && <div className="auth-v2-info">{info}</div>}
        {error && <div className="auth-v2-error">{error}</div>}

        <div className="auth-v2-label">FULL NAME</div>
        <div className="auth-v2-field">
          <input className="auth-v2-input" type="text" placeholder="Alex Tran" value={name}
            onChange={e => setName(e.target.value)} onKeyDown={handleKey} />
        </div>

        <div className="auth-v2-label">SCHOOL EMAIL</div>
        <div className="auth-v2-field">
          <input className="auth-v2-input" type="email" placeholder="alex@uoft.ca" value={email}
            onChange={e => setEmail(e.target.value)} onKeyDown={handleKey} autoComplete="email" />
        </div>

        <div className="auth-v2-label">PASSWORD</div>
        <div className="auth-v2-field">
          <input className="auth-v2-input" type={showPw ? 'text' : 'password'} placeholder="••••••••" value={password}
            onChange={e => setPassword(e.target.value)} onKeyDown={handleKey} autoComplete="new-password" />
          <button type="button" onClick={() => setShowPw(v => !v)} style={{ flexShrink:0, opacity:0.5, fontSize:18 }}>
            {showPw ? '🙈' : '👁'}
          </button>
        </div>

        {password.length > 0 && (
          <>
            <div className="auth-v2-strength">
              <div className="auth-v2-strength-bar" style={{ width: pwWidths[pwStrength], background: pwColors[pwStrength] }} />
            </div>
            <div className="auth-v2-strength-label" style={{ color: pwColors[pwStrength] }}>
              STRENGTH: {pwLabels[pwStrength].toUpperCase()}
            </div>
          </>
        )}

        <div className="auth-v2-checkbox-row" onClick={() => setStudyTips(v => !v)}>
          <div className={`auth-v2-checkbox ${studyTips ? 'checked' : ''}`}>
            {studyTips && <svg width="10" height="8" viewBox="0 0 10 8" fill="none"><path d="M1 4l3 3 5-6" stroke="#fff" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>}
          </div>
          Send me weekly study tips
        </div>

        <button className="auth-v2-btn" onClick={submit} disabled={loading}>
          {loading ? '…' : '⚡ Create my account'}
        </button>

        <div className="auth-v2-divider"><span>OR SIGN UP WITH</span></div>

        <div className="auth-v2-social">
          <button className="auth-v2-social-btn" onClick={signInWithGoogle}>
            <GoogleIcon /> Google
          </button>
          <button className="auth-v2-social-btn" onClick={() => {}}>
            <AppleIcon /> Apple
          </button>
        </div>

        <p className="auth-v2-terms">
          By signing up, you agree to Taskoo's{' '}
          <a href="/terms.html" target="_blank" rel="noopener">Terms</a> and <a href="/privacy.html" target="_blank" rel="noopener">Privacy Policy</a>
        </p>

        <div className="auth-v2-switch">
          Already a member?{' '}
          <button onClick={() => switchTab('login')}>Log in</button>
        </div>
      </div>
    </div>
  );
}

// ─── Status Bar ───────────────────────────────────────────────────────────────

function StatusBar() {
  const [time, setTime] = useState(() => {
    const n = new Date();
    return `${n.getHours()}:${String(n.getMinutes()).padStart(2,'0')}`;
  });
  useEffect(() => {
    const t = setInterval(() => {
      const n = new Date();
      setTime(`${n.getHours()}:${String(n.getMinutes()).padStart(2,'0')}`);
    }, 10000);
    return () => clearInterval(t);
  }, []);
  return (
    <div className="status-bar">
      <span className="status-time">{time}</span>
      <div className="status-icons">
        <svg width="16" height="12" viewBox="0 0 16 12" fill="currentColor">
          <rect x="0" y="4" width="3" height="8" rx="0.5" opacity="0.4"/>
          <rect x="4" y="2.5" width="3" height="9.5" rx="0.5" opacity="0.6"/>
          <rect x="8" y="1" width="3" height="11" rx="0.5" opacity="0.8"/>
          <rect x="12" y="0" width="3" height="12" rx="0.5"/>
        </svg>
        <svg width="15" height="12" viewBox="0 0 15 12" fill="currentColor">
          <path d="M7.5 2.5C10.5 2.5 13 4.5 14 7.5L12.5 9C11.8 6.8 9.8 5.5 7.5 5.5C5.2 5.5 3.2 6.8 2.5 9L1 7.5C2 4.5 4.5 2.5 7.5 2.5Z" opacity="0.4"/>
          <path d="M7.5 5.5C9.5 5.5 11.2 6.7 12 8.5L10.5 10C10 8.5 8.8 7.5 7.5 7.5C6.2 7.5 5 8.5 4.5 10L3 8.5C3.8 6.7 5.5 5.5 7.5 5.5Z" opacity="0.7"/>
          <circle cx="7.5" cy="11" r="1.5"/>
        </svg>
        <svg width="25" height="12" viewBox="0 0 25 12" fill="currentColor">
          <rect x="0.5" y="0.5" width="21" height="11" rx="3.5" stroke="currentColor" strokeOpacity="0.35" fill="none"/>
          <rect x="22" y="3.5" width="3" height="5" rx="1" opacity="0.4"/>
          <rect x="2" y="2" width="16" height="8" rx="2" opacity="0.9"/>
        </svg>
      </div>
    </div>
  );
}

// ─── Bottom Nav ───────────────────────────────────────────────────────────────

function BottomNav({ active, onNavigate, onAdd }) {
  return (
    <nav className="bottom-nav">
      <button className={`nav-btn ${active === 'dashboard' ? 'active' : ''}`}
        onClick={() => onNavigate('dashboard')} aria-label="Home">
        <Icon name="home-fill" style={{ fontSize: 22 }} />
        <span>Home</span>
      </button>
      <button className={`nav-btn ${active === 'calendar' ? 'active' : ''}`}
        onClick={() => onNavigate('calendar')} aria-label="Calendar">
        <Icon name="calendar" style={{ fontSize: 22 }} />
        <span>Calendar</span>
      </button>
      <div className="nav-fab-wrap">
        <button
          className={`nav-fab ${active === 'focus' ? 'active' : ''}`}
          onClick={() => onNavigate('focus')}
          aria-label="Focus"
        >
          <Icon name="add" style={{ fontSize: 26 }} />
        </button>
      </div>
      <button className={`nav-btn ${active === 'chat' ? 'active' : ''}`}
        onClick={() => onNavigate('chat')} aria-label="AI Chat">
        <Icon name="sparkle" style={{ fontSize: 22 }} />
        <span>AI Chat</span>
      </button>
    </nav>
  );
}

// ─── Dashboard Screen ─────────────────────────────────────────────────────────

function DashboardScreen({ tasks, courses, deadlines, userName, streak, onToggleTask, onPush, onAdd }) {
  const today = new Date();
  const dayNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
  const monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  const firstName = (userName || 'Student').split(' ')[0];
  const dateStr = `${dayNames[today.getDay()]} · ${monthNames[today.getMonth()]} ${today.getDate()}`;

  // Stats
  const totalToday = tasks.length;
  const doneToday = tasks.filter(t => t.done).length;
  const weekDeadlines = deadlines.filter(d => !d.done);
  const urgentDeadlines = deadlines.filter(d => !d.done && d.urgent).length;

  // Next deadline card
  const nextDeadline = weekDeadlines[0];

  // Today's focus tasks
  const focusTasks = tasks.filter(t => !t.done).slice(0, 3);

  // Courses
  const displayCourses = courses.slice(0, 4);

  // Time estimates per task (placeholder)
  const timeEstimates = ['30 min', '45 min', '60 min'];

  return (
    <div className="screen screen-in">
      <div className="screen-scroll">

        {/* Header */}
        <div className="dash-v2-header">
          <div>
            <h1 className="dash-v2-greeting">Hi, {firstName} 🤖</h1>
            <div className="dash-v2-date">{dateStr}</div>
          </div>
          <div className="dash-v2-actions">
            <button className="icon-btn" onClick={() => onPush('search')}>
              <Icon name="search" style={{ fontSize:20 }} />
            </button>
            <button className="icon-btn" onClick={() => onPush('settings')}>
              <Icon name="bell" style={{ fontSize:20 }} />
            </button>
          </div>
        </div>

        {/* Stats chips */}
        <div className="dash-v2-stats">
          <div className="dash-v2-chip">
            <span className="dash-v2-chip-dot" style={{ background:'var(--red)' }} />
            <span>{doneToday}/{totalToday}</span>
            <span style={{ color:'var(--text-soft)', fontWeight:500 }}>tasks today</span>
          </div>
          <div className="dash-v2-chip">
            <span className="dash-v2-chip-dot" style={{ background:'#F59E0B' }} />
            <span>{weekDeadlines.length} Deadlines this week</span>
            {urgentDeadlines > 0 && (
              <span className="dash-v2-chip-badge">{urgentDeadlines} due soon</span>
            )}
          </div>
        </div>

        {/* Next deadline card */}
        {nextDeadline && (
          <div className="dash-v2-deadline-card">
            <div className="dash-v2-deadline-count">{nextDeadline.due}.</div>
            <div className="dash-v2-deadline-title">{nextDeadline.title}</div>
            <div className="dash-v2-deadline-date">{nextDeadline.course}</div>
            <div className="dash-v2-deadline-badge">{weekDeadlines.length}</div>
          </div>
        )}

        {/* Today's focus */}
        <div className="section-header">
          <span>Today's focus</span>
          <div style={{ display:'flex', alignItems:'center', gap:8 }}>
            <button className="icon-btn-sm" onClick={onAdd} aria-label="Add task">
              <Icon name="add" style={{ fontSize:16 }} />
            </button>
            <button className="see-all" onClick={() => onPush('deadlines')}>See all</button>
          </div>
        </div>

        {focusTasks.length === 0 ? (
          <div className="dash-v2-empty">
            <Icon name="circle-check" style={{ fontSize:28, opacity:0.25 }} />
            <span>All caught up!</span>
          </div>
        ) : focusTasks.map((task, idx) => {
          const color = courseColor(task.course, courses);
          const dayAbbr = ['SUN','MON','TUE','WED','THU','FRI','SAT'][today.getDay()];
          return (
            <div key={task.id}
              className={`dash-v2-task-row${task.done ? ' done' : ''}`}
              onClick={() => onToggleTask(task.id)}>
              <div className={`dash-v2-task-check${task.done ? ' checked' : ''}`}>
                {task.done && <Icon name="check" style={{ fontSize:11 }} />}
              </div>
              <div className="dash-v2-task-body">
                <div className="dash-v2-task-title">{task.title}</div>
                <div className="dash-v2-task-meta">
                  <span className="dash-v2-task-course" style={{ color }}>{task.course}</span>
                  <span className="dash-v2-task-time">· {timeEstimates[idx] || '30 min'}</span>
                </div>
              </div>
              {task.urgent
                ? <span className="dash-v2-task-badge today">TODAY</span>
                : <span className="dash-v2-task-badge day">{dayAbbr}</span>
              }
            </div>
          );
        })}

        {/* Courses */}
        <div className="section-header" style={{ marginTop:8 }}>
          <span>Courses</span>
          <button className="see-all" onClick={() => onAdd && onAdd()}>+ Add</button>
        </div>
        {courses.length === 0 ? (
          <div style={{ fontSize:13, color:'var(--text-muted)', padding:'8px 0 12px', fontWeight:500 }}>
            No courses yet — add one to get started
          </div>
        ) : (
          <div className="dash-v2-courses-scroll">
            {displayCourses.map(c => {
              const color = c.color || courseColor(c.code || c.name, courses);
              const courseTasks = tasks.filter(t => t.course === (c.code || c.name));
              const donePct = courseTasks.length > 0
                ? Math.round((courseTasks.filter(t => t.done).length / courseTasks.length) * 100)
                : 0;
              return (
                <div key={c.id} className="dash-v2-course-chip">
                  <div className="dash-v2-course-code">{c.code || c.name}</div>
                  <div className="dash-v2-course-tasks">{courseTasks.filter(t => !t.done).length} tasks left</div>
                  <div className="dash-v2-course-bar">
                    <div className="dash-v2-course-fill" style={{ width: `${donePct}%`, background: color }} />
                  </div>
                </div>
              );
            })}
          </div>
        )}

        {/* AI Banner */}
        <div className="dash-v2-ai-banner" onClick={() => onPush('chat')}>
          <div className="dash-v2-ai-label">✨ Taskoo AI</div>
          <div className="dash-v2-ai-text">Want me to plan your week around the chem midterm?</div>
          <div className="dash-v2-ai-cta">Yes, plan it →</div>
        </div>

        <div style={{ height:80 }} />
      </div>
    </div>
  );
}

// ─── Calendar Screen ──────────────────────────────────────────────────────────

function CalendarScreen({ events }) {
  const today = new Date();
  const todayD = today.getDate();
  const todayM = today.getMonth();
  const todayY = today.getFullYear();
  const [year, setYear] = useState(todayY);
  const [month, setMonth] = useState(todayM);
  const [selectedDay, setSelectedDay] = useState(todayD);

  const monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const startDow = new Date(year, month, 1).getDay();
  const cells = [];
  for (let i = 0; i < startDow; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  const dateKey = `${year}-${String(month+1).padStart(2,'0')}-${String(selectedDay).padStart(2,'0')}`;
  const dayEvents = (events || {})[dateKey] || [];

  const prevMonth = () => { if (month === 0) { setYear(y => y-1); setMonth(11); } else setMonth(m => m-1); setSelectedDay(1); };
  const nextMonth = () => { if (month === 11) { setYear(y => y+1); setMonth(0); } else setMonth(m => m+1); setSelectedDay(1); };

  // Today's events for subtitle
  const todayKey = `${todayY}-${String(todayM+1).padStart(2,'0')}-${String(todayD).padStart(2,'0')}`;
  const todayEvents = (events || {})[todayKey] || [];

  // Week strip: selectedDay ± 3, clamped to [1, daysInMonth]
  const dayLetters = ['S','M','T','W','T','F','S'];
  const stripDays = [];
  for (let offset = -3; offset <= 3; offset++) {
    const d = selectedDay + offset;
    stripDays.push(d >= 1 && d <= daysInMonth ? d : null);
  }

  // Day label row helpers
  const selectedDate = new Date(year, month, selectedDay);
  const fullDayNames = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
  const fullMonthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  const isSelectedToday = selectedDay === todayD && month === todayM && year === todayY;

  return (
    <div className="screen screen-in">
      <div className="screen-scroll">

        {/* Header */}
        <div className="cal-v2-header">
          <div>
            <h1 className="cal-v2-title">Calendar</h1>
            <div className="cal-v2-subtitle">
              {todayEvents.length} event{todayEvents.length !== 1 ? 's' : ''} today
            </div>
          </div>
          <div className="cal-v2-actions">
            <button className="icon-btn"><Icon name="search" style={{ fontSize:20 }} /></button>
            <button className="icon-btn"><Icon name="add" style={{ fontSize:20 }} /></button>
          </div>
        </div>

        {/* Month nav */}
        <div className="cal-v2-month-nav">
          <button className="icon-btn" onClick={prevMonth}><Icon name="left" style={{ fontSize:18 }} /></button>
          <span className="cal-v2-month-label">{monthNames[month]} {year}</span>
          <button className="icon-btn" onClick={nextMonth}><Icon name="right" style={{ fontSize:18 }} /></button>
        </div>

        {/* Week strip */}
        <div className="cal-v2-week-strip">
          {stripDays.map((d, i) => {
            if (!d) return <div key={i} className="cal-v2-day-col" />;
            const jsDay = new Date(year, month, d).getDay();
            const letter = dayLetters[jsDay];
            const isToday = d === todayD && month === todayM && year === todayY;
            const isSel = d === selectedDay;
            return (
              <div key={i} className="cal-v2-day-col">
                <span className="cal-v2-day-letter">{letter}</span>
                <button
                  className={`cal-v2-day-num${isSel ? ' selected' : isToday ? ' today' : ''}`}
                  onClick={() => setSelectedDay(d)}
                >
                  {d}
                </button>
              </div>
            );
          })}
        </div>

        {/* Day label row */}
        <div className="cal-v2-day-label-row">
          {isSelectedToday && <span className="cal-v2-today-badge">Today</span>}
          <span className="cal-v2-day-full">
            {fullDayNames[selectedDate.getDay()].toUpperCase()}, {fullMonthNames[month].toUpperCase()} {selectedDay}
          </span>
        </div>

        {/* Events */}
        {dayEvents.length === 0 ? (
          <div className="empty-state">
            <Icon name="calendar" style={{ fontSize:32, opacity:0.3, marginBottom:8 }} />
            <div>No events today</div>
          </div>
        ) : (
          <div className="cal-v2-timeline">
            {dayEvents.map((ev, i) => (
              <div key={i} className="cal-v2-event">
                <div className="cal-v2-event-time">{ev.time}</div>
                <div className="cal-v2-event-dot" style={{ background: ev.color || 'var(--red)' }} />
                <div className="cal-v2-event-card" style={{ borderLeftColor: ev.color || 'var(--red)' }}>
                  <div className="cal-v2-event-title">{ev.title}</div>
                  {ev.loc && (
                    <div className="cal-v2-event-loc">
                      <Icon name="pin" style={{ fontSize:11 }} /> {ev.loc}
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>
        )}

        <div style={{ height:80 }} />
      </div>
    </div>
  );
}

// ─── Deadlines Screen ─────────────────────────────────────────────────────────

function DeadlinesScreen({ deadlines, onPush }) {
  const [filter, setFilter] = useState('All');
  const filters = ['All', 'Pending', 'Done'];

  const visible = deadlines.filter(d => {
    if (filter === 'Done') return d.done;
    if (filter === 'Pending') return !d.done;
    return true;
  });

  const urgentCount = deadlines.filter(d => !d.done && d.urgent).length;

  return (
    <div className="screen screen-in">
      <div className="screen-scroll">
        <div className="page-header">
          <h1 className="page-title">Deadlines</h1>
          <button className="icon-btn"><Icon name="filter" style={{ fontSize:20 }} /></button>
        </div>

        <div className="segment">
          {filters.map(f => (
            <button key={f} className={`seg-btn ${filter === f ? 'active' : ''}`}
              onClick={() => setFilter(f)}>{f}</button>
          ))}
        </div>

        {urgentCount > 0 && filter !== 'Done' && (
          <div className="urgent-banner">
            <Icon name="warning" style={{ fontSize:16, color:'#F59E0B' }} />
            <span><strong>{urgentCount} deadline{urgentCount > 1 ? 's' : ''} due today</strong></span>
          </div>
        )}

        <div className="deadlines-list">
          {visible.length === 0 ? (
            <div className="empty-state">
              <Icon name="alarm" style={{ fontSize:32, opacity:0.3, marginBottom:8 }} />
              <div>No deadlines here</div>
            </div>
          ) : visible.map(d => (
            <div key={d.id} className={`deadline-card ${d.urgent && !d.done ? 'urgent' : ''}`}>
              <div className="deadline-bar" style={{ background: d.color }} />
              <div className="deadline-body">
                <div className="deadline-title" style={{ opacity: d.done ? 0.5 : 1, textDecoration: d.done ? 'line-through' : 'none' }}>{d.title}</div>
                <div className="deadline-meta">
                  <span className="deadline-course" style={{ color: d.color }}>{d.course}</span>
                  <span className={`deadline-due ${d.urgent && !d.done ? 'red' : ''}`}>
                    <Icon name="time" style={{ fontSize:11 }} /> {d.due}
                  </span>
                </div>
              </div>
              <div className="deadline-tag">{d.tag || 'hw'}</div>
            </div>
          ))}
        </div>

        <button className="ai-cta" onClick={() => onPush('studyplan')}>
          <Icon name="sparkle" style={{ fontSize:18, color:'var(--red)' }} />
          <span>Generate AI Study Plan</span>
          <Icon name="right" style={{ fontSize:16, marginLeft:'auto' }} />
        </button>

        <div style={{ height:80 }} />
      </div>
    </div>
  );
}

// ─── Focus Screen ─────────────────────────────────────────────────────────────

function FocusScreen({ uid }) {
  const MODES = [
    { key: 'focus', label: 'Focus', secs: 25 * 60 },
    { key: 'short', label: 'Short', secs: 5 * 60 },
    { key: 'long', label: 'Long', secs: 15 * 60 },
  ];
  const [modeIdx, setModeIdx] = useState(0);
  const [remaining, setRemaining] = useState(MODES[0].secs);
  const [running, setRunning] = useState(false);
  const [pomos, setPomos] = useState([false, false, false, false]);
  const intervalRef = useRef(null);
  const sessionStartRef = useRef(null);

  const mode = MODES[modeIdx];
  const total = mode.secs;
  const mins = Math.floor(remaining / 60);
  const secs = remaining % 60;
  const progress = 1 - remaining / total;
  const R = 90;
  const C = 2 * Math.PI * R;

  const saveSession = useCallback(async (duration) => {
    if (!uid || duration < 60) return;
    await sb.from('focus_sessions').insert({
      user_id: uid,
      duration: Math.round(duration / 60),
      date: new Date().toISOString().split('T')[0],
    });
  }, [uid]);

  const switchMode = (idx) => {
    clearInterval(intervalRef.current);
    setRunning(false);
    setModeIdx(idx);
    setRemaining(MODES[idx].secs);
    sessionStartRef.current = null;
  };

  const toggle = () => {
    if (running) {
      clearInterval(intervalRef.current);
      setRunning(false);
      if (sessionStartRef.current) {
        saveSession(Date.now() - sessionStartRef.current);
        sessionStartRef.current = null;
      }
    } else {
      setRunning(true);
      sessionStartRef.current = Date.now();
    }
  };

  const stop = () => {
    clearInterval(intervalRef.current);
    if (running && sessionStartRef.current) {
      saveSession(Date.now() - sessionStartRef.current);
    }
    setRunning(false);
    setRemaining(total);
    sessionStartRef.current = null;
  };

  useEffect(() => {
    if (running) {
      intervalRef.current = setInterval(() => {
        setRemaining(r => {
          if (r <= 1) {
            clearInterval(intervalRef.current);
            setRunning(false);
            if (modeIdx === 0) {
              setPomos(p => { const n = [...p]; const i = n.findIndex(x => !x); if (i !== -1) n[i] = true; return n; });
              if (sessionStartRef.current) { saveSession(total * 1000); sessionStartRef.current = null; }
            }
            return 0;
          }
          return r - 1;
        });
      }, 1000);
    }
    return () => clearInterval(intervalRef.current);
  }, [running]);

  return (
    <div className="screen screen-in" style={{ display:'flex', flexDirection:'column' }}>
      <div className="focus-v2-header-wrap">
        <div className="focus-v2-header">
          <div className="focus-v2-header-left">
            <p className="focus-v2-title">Focus</p>
            <p className="focus-v2-subtitle">{mode.label} · session {pomos.filter(Boolean).length + 1} of {pomos.length}</p>
          </div>
          <button className="icon-btn" style={{ color:'#fff' }}>
            <Icon name="volume" style={{ fontSize:20 }} />
          </button>
        </div>
      </div>

      <div className="focus-v2-body">
        <div className="focus-v2-tabs">
          <div className="segment">
            {MODES.map((m, i) => (
              <button key={m.key} className={`seg-btn ${modeIdx === i ? 'active' : ''}`}
                onClick={() => switchMode(i)}>{m.label}</button>
            ))}
          </div>
        </div>

        <div className="focus-v2-timer-wrap">
          <div className="focus-v2-time">
            {String(mins).padStart(2,'0')}:{String(secs).padStart(2,'0')}
          </div>
          <div className="focus-v2-task-name">{mode.label} session</div>
          <div className="focus-v2-session-label">
            SESSION {pomos.filter(Boolean).length + 1} / {pomos.length}
          </div>
        </div>

        <div className="focus-v2-controls">
          <button className="focus-v2-ctrl-btn" onClick={stop}>
            <Icon name="skip-back" style={{ fontSize:22 }} />
          </button>
          <button className="focus-v2-play-btn" onClick={toggle}>
            <Icon name={running ? 'pause' : 'play'} style={{ fontSize:28 }} />
          </button>
          <button className="focus-v2-ctrl-btn">
            <Icon name="skip-fwd" style={{ fontSize:22 }} />
          </button>
        </div>

        <div className="focus-v2-pomo-dots">
          {pomos.map((done, i) => (
            <div key={i} className={`focus-v2-pomo-dot ${done ? 'done' : ''}`} />
          ))}
        </div>
      </div>
    </div>
  );
}

// ─── Tracking Screen ──────────────────────────────────────────────────────────

function TrackingScreen({ courses, onBack }) {
  const bars = [65,90,45,120,80,55,30];
  const days = ['M','T','W','T','F','S','S'];
  const maxH = Math.max(...bars);
  const total = bars.reduce((a,b) => a+b, 0);
  const displayCourses = courses.length > 0 ? courses : [];

  return (
    <div className="screen slide-in">
      <div className="screen-scroll">
        <div className="page-header">
          <button className="icon-btn back-btn" onClick={onBack}><Icon name="left" style={{ fontSize:20 }} /></button>
          <h1 className="page-title">Tracking</h1>
          <div style={{ width:36 }} />
        </div>

        <div className="tracking-hero">
          <svg viewBox="0 0 140 140" width="140" height="140">
            <circle cx="70" cy="70" r="60" fill="none" stroke="currentColor" strokeOpacity="0.08" strokeWidth="12"/>
            <circle cx="70" cy="70" r="60" fill="none" stroke="var(--red)" strokeWidth="12"
              strokeDasharray={`${0.72 * 376.8} 376.8`} strokeLinecap="round" transform="rotate(-90 70 70)"/>
          </svg>
          <div className="tracking-ring-inner">
            <div className="tracking-pct">72%</div>
            <div className="tracking-sublbl">on track</div>
          </div>
        </div>

        <div className="tracking-stats">
          <div className="tracking-stat"><div className="ts-val">{Math.round(total/60)}h</div><div className="ts-lbl">This week</div></div>
          <div className="tracking-stat"><div className="ts-val">{Math.round(total/7/60)}h</div><div className="ts-lbl">Daily avg</div></div>
          <div className="tracking-stat"><div className="ts-val">7🔥</div><div className="ts-lbl">Streak</div></div>
        </div>

        <div className="section-header"><span>Study hours this week</span></div>
        <div className="bar-chart">
          {bars.map((h, i) => (
            <div key={i} className="bar-col">
              <div className="bar-wrap">
                <div className="bar-fill" style={{ height:`${(h/maxH)*80}px`, background: i===4 ? 'var(--red)' : 'var(--border)' }} />
              </div>
              <div className="bar-label">{days[i]}</div>
            </div>
          ))}
        </div>

        {displayCourses.length > 0 && (
          <>
            <div className="section-header"><span>By course</span></div>
            <div className="courses-breakdown">
              {displayCourses.map((c, i) => (
                <div key={c.id} className="breakdown-row">
                  <div className="breakdown-dot" style={{ background: c.color || COURSE_COLORS[i % COURSE_COLORS.length] }} />
                  <div className="breakdown-name">{c.code || c.name}</div>
                  <div className="breakdown-bar-wrap">
                    <div className="breakdown-bar" style={{ width:'60%', background: c.color || COURSE_COLORS[i % COURSE_COLORS.length] }} />
                  </div>
                  <div className="breakdown-pct">60%</div>
                </div>
              ))}
            </div>
          </>
        )}

        <div style={{ height:80 }} />
      </div>
    </div>
  );
}

// ─── Chat Screen ──────────────────────────────────────────────────────────────

function ChatScreen({ onBack }) {
  const [msgs, setMsgs] = useState([
    { role:'ai', text:"Hi! I'm Taskoo AI. Ask me anything about your schedule, deadlines, or how to study smarter. 🎓" }
  ]);
  const [input, setInput] = useState('');
  const [typing, setTyping] = useState(false);
  const bottomRef = useRef(null);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior:'smooth' });
  }, [msgs, typing]);

  const AI_RESPONSES = [
    "Based on your schedule, I'd prioritize your most urgent deadline first. You've got this!",
    "Your study streak is active — keep it going! Consistent daily sessions beat cramming every time.",
    "Want me to create a focused study plan for your upcoming deadlines?",
    "Great progress today! Remember to take short breaks between sessions for better retention.",
  ];

  const send = () => {
    if (!input.trim()) return;
    const userMsg = input.trim();
    setInput('');
    setMsgs(m => [...m, { role:'user', text:userMsg }]);
    setTyping(true);
    setTimeout(() => {
      setTyping(false);
      const reply = AI_RESPONSES[Math.floor(Math.random() * AI_RESPONSES.length)];
      setMsgs(m => [...m, { role:'ai', text:reply }]);
    }, 1000);
  };

  // Format current time for divider
  const now = new Date();
  const timeStr = `${now.getHours()}:${String(now.getMinutes()).padStart(2,'0')}`;

  return (
    <div className="screen slide-in chat-v2-screen">

      {/* Header */}
      <div className="chat-v2-header">
        <button className="icon-btn" onClick={onBack} style={{ opacity: onBack ? 1 : 0, pointerEvents: onBack ? 'auto' : 'none' }}>
          <Icon name="left" style={{ fontSize:20 }} />
        </button>
        <div className="chat-v2-header-center">
          <div className="chat-v2-header-name">Taskoo AI</div>
          <div className="chat-v2-header-status">
            <span className="chat-v2-online-dot" />
            Always here to help
          </div>
        </div>
        <button className="icon-btn">
          <Icon name="more" style={{ fontSize:20 }} />
        </button>
      </div>

      {/* Messages */}
      <div className="chat-v2-messages">
        {/* Date divider */}
        <div className="chat-v2-divider">
          <span>TODAY · {timeStr}</span>
        </div>

        {msgs.map((m, i) => (
          <div key={i} className={`chat-v2-row ${m.role === 'user' ? 'user' : 'ai'}`}>
            {m.role === 'ai' && (
              <div className="chat-v2-avatar">
                <Icon name="sparkle" style={{ fontSize:14, color:'#fff' }} />
              </div>
            )}
            <div className={`chat-v2-bubble ${m.role}`}>
              {m.text}
            </div>
          </div>
        ))}

        {/* Typing indicator */}
        {typing && (
          <div className="chat-v2-row ai">
            <div className="chat-v2-avatar">
              <Icon name="sparkle" style={{ fontSize:14, color:'#fff' }} />
            </div>
            <div className="chat-v2-typing">
              <span /><span /><span />
            </div>
          </div>
        )}

        <div ref={bottomRef} />
      </div>

      {/* Input bar */}
      <div className="chat-v2-input-row">
        <input
          className="chat-v2-input"
          placeholder="Message Taskoo..."
          value={input}
          onChange={e => setInput(e.target.value)}
          onKeyDown={e => e.key === 'Enter' && send()}
        />
        <button className="chat-v2-send" onClick={send} disabled={!input.trim()}>
          <Icon name="arrow-up" style={{ fontSize:18 }} />
        </button>
      </div>
    </div>
  );
}

// ─── Study Plan Screen ────────────────────────────────────────────────────────

function StudyPlanScreen({ onBack }) {
  const PLAN_STEPS = [
    { id:1, title:'Review lecture slides (Ch. 12-14)', duration:'45 min', done:false },
    { id:2, title:'Re-read textbook sections 12.3-12.5', duration:'30 min', done:false },
    { id:3, title:'Complete practice problems (set B)', duration:'40 min', done:true },
    { id:4, title:'Watch supplemental video', duration:'20 min', done:true },
    { id:5, title:'Self-quiz using flashcard deck', duration:'25 min', done:false },
  ];
  const [steps, setSteps] = useState(PLAN_STEPS);
  const toggle = (id) => setSteps(s => s.map(x => x.id === id ? {...x, done:!x.done} : x));
  const done = steps.filter(s => s.done).length;

  return (
    <div className="screen slide-in">
      <div className="screen-scroll">
        <div className="page-header">
          <button className="icon-btn back-btn" onClick={onBack}><Icon name="left" style={{ fontSize:20 }} /></button>
          <h1 className="page-title">Study Plan</h1>
          <div style={{ width:36 }} />
        </div>

        <div className="plan-hero">
          <div className="plan-title">AI-Generated Study Plan</div>
          <div className="plan-progress-lbl">{done} of {steps.length} steps completed</div>
        </div>

        <div className="plan-steps">
          {steps.map(s => (
            <div key={s.id} className={`plan-step ${s.done ? 'done' : ''}`} onClick={() => toggle(s.id)}>
              <div className={`plan-check ${s.done ? 'checked' : ''}`}>
                {s.done && <Icon name="check" style={{ fontSize:11 }} />}
              </div>
              <div className="plan-step-body">
                <div className="plan-step-title">{s.title}</div>
                <div className="plan-step-dur">{s.duration}</div>
              </div>
            </div>
          ))}
        </div>

        <div style={{ height:80 }} />
      </div>
    </div>
  );
}

// ─── Settings Screen ──────────────────────────────────────────────────────────

function SettingsScreen({ theme, onThemeToggle, onBack, userName, userEmail, plan, onLogout }) {
  const initials = (userName || 'S').split(' ').map(p => p[0]).join('').toUpperCase().slice(0,2);

  const rows = [
    { icon:'user', label:'Account', sub: userEmail || '' },
    { icon:'bell', label:'Notifications', sub:'Push & reminders' },
    { icon:'moon', label:'Dark mode', sub:'', toggle:true, val:theme==='dark', onToggle:onThemeToggle },
    { icon:'links', label:'Integrations', sub:'Calendar, Canvas' },
    { icon:'file-paper', label:'Export data', sub:'' },
    { icon:'logout', label:'Sign out', sub:'', accent:true, onTap:onLogout },
  ];

  return (
    <div className="screen slide-in">
      <div className="screen-scroll">
        <div className="page-header">
          <button className="icon-btn back-btn" onClick={onBack}><Icon name="left" style={{ fontSize:20 }} /></button>
          <h1 className="page-title">Settings</h1>
          <div style={{ width:36 }} />
        </div>

        <div className="profile-card">
          <div className="profile-avatar">{initials}</div>
          <div className="profile-info">
            <div className="profile-name">{userName || 'Student'}</div>
            <div className="profile-email">{userEmail || ''}</div>
            <div className="profile-plan">{plan === 'premium' ? '⭐ Premium' : 'Free plan'}</div>
          </div>
        </div>

        <div className="settings-rows">
          {rows.map((r, i) => (
            <div key={i} className={`settings-row ${r.accent ? 'accent' : ''}`}
              onClick={r.onTap ? r.onTap : undefined}
              style={{ cursor: r.onTap ? 'pointer' : undefined }}>
              <div className={`settings-row-icon ${r.accent ? 'accent' : ''}`}>
                <Icon name={r.icon} style={{ fontSize:18 }} />
              </div>
              <div className="settings-row-body">
                <div className="settings-row-label">{r.label}</div>
                {r.sub && <div className="settings-row-sub">{r.sub}</div>}
              </div>
              {r.toggle
                ? <button className={`toggle-pill ${r.val ? 'on' : ''}`} onClick={r.onToggle}><div className="toggle-knob" /></button>
                : <Icon name="right" style={{ fontSize:16, color:'var(--text-soft)' }} />
              }
            </div>
          ))}
        </div>

        <div className="app-version">Taskoo v1.0.0</div>
        <div style={{ height:40 }} />
      </div>
    </div>
  );
}

// ─── Add Task Sheet ───────────────────────────────────────────────────────────

function AddTaskSheet({ courses, uid, onClose, onAdd }) {
  const [title, setTitle] = useState('');
  const [courseId, setCourseId] = useState(courses[0]?.id || '');
  const [urgent, setUrgent] = useState(false);
  const [loading, setLoading] = useState(false);

  const submit = async () => {
    if (!title.trim() || !uid) return;
    setLoading(true);
    const c = courses.find(c => c.id === courseId);
    const { data, error } = await sb.from('tasks').insert({
      user_id: uid,
      name: title.trim(),
      course: c?.code || c?.name || '',
      urgency: urgent ? 'urgent' : 'normal',
      done: false,
    }).select().single();
    if (!error && data) onAdd(mapTask(data));
    setLoading(false);
    onClose();
  };

  return (
    <div className="sheet-backdrop" onClick={onClose}>
      <div className="sheet" onClick={e => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-header">
          <h2 className="sheet-title">New Task</h2>
          <button className="icon-btn" onClick={onClose}><Icon name="close" style={{ fontSize:20 }} /></button>
        </div>

        <input className="sheet-input" placeholder="Task name…" value={title}
          onChange={e => setTitle(e.target.value)} autoFocus
          onKeyDown={e => e.key === 'Enter' && submit()} />

        {courses.length > 0 && (
          <>
            <div className="sheet-label">Course</div>
            <div className="course-picker">
              {courses.map(c => (
                <button key={c.id} className={`course-chip ${courseId === c.id ? 'selected' : ''}`}
                  style={courseId === c.id ? { background:(c.color||'#df3e3a')+'22', borderColor:c.color||'#df3e3a', color:c.color||'#df3e3a' } : {}}
                  onClick={() => setCourseId(c.id)}>
                  {c.code || c.name}
                </button>
              ))}
            </div>
          </>
        )}

        <div className="sheet-row">
          <div className="sheet-row-left">
            <Icon name="warning" style={{ fontSize:16, color:'#F59E0B' }} />
            <span>Mark as urgent</span>
          </div>
          <button className={`toggle-pill ${urgent ? 'on' : ''}`} onClick={() => setUrgent(v => !v)}>
            <div className="toggle-knob" />
          </button>
        </div>

        <button className="sheet-submit" onClick={submit} disabled={!title.trim() || loading}>
          {loading ? 'Adding…' : 'Add Task'}
        </button>
      </div>
    </div>
  );
}

// ─── App Root ─────────────────────────────────────────────────────────────────

function App() {
  const [session, setSession] = useState(undefined);
  const [theme, setTheme] = useState(() => localStorage.getItem('taskoo-theme') || 'dark');
  const [tab, setTab] = useState('dashboard');
  const [pushed, setPushed] = useState(null);
  const [showAdd, setShowAdd] = useState(false);

  const [tasks, setTasks] = useState([]);
  const [deadlines, setDeadlines] = useState([]);
  const [courses, setCourses] = useState([]);
  const [events, setEvents] = useState({});
  const [streak, setStreak] = useState(0);

  const channelRef = useRef(null);

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('taskoo-theme', theme);
  }, [theme]);

  useEffect(() => {
    sb.auth.getSession().then(({ data: { session: s } }) => setSession(s ?? null));
    const { data: { subscription } } = sb.auth.onAuthStateChange((_, s) => setSession(s ?? null));
    return () => subscription.unsubscribe();
  }, []);

  useEffect(() => {
    if (!session) {
      setTasks([]); setDeadlines([]); setCourses([]); setEvents({});
      if (channelRef.current) { sb.removeChannel(channelRef.current); channelRef.current = null; }
      return;
    }

    const uid = session.user.id;

    const loadAll = async () => {
      if (!navigator.onLine) {
        const [cachedTasks, cachedDeadlines, cachedCourses, cachedEvents] = await Promise.all([
          idbGetAll('tasks'), idbGetAll('deadlines'), idbGetAll('courses'), idbKvGet('events'),
        ]);
        setCourses(cachedCourses);
        setTasks(cachedTasks);
        setDeadlines(cachedDeadlines);
        setEvents(cachedEvents || {});
        return;
      }

      const [tRes, dRes, cRes, eRes] = await Promise.all([
        sb.from('tasks').select('*').eq('user_id', uid).eq('deleted', false).order('created_at', { ascending: false }),
        sb.from('deadlines').select('*').eq('user_id', uid).eq('deleted', false).order('due_date', { ascending: true }),
        sb.from('courses').select('*').eq('user_id', uid).order('created_at', { ascending: true }),
        sb.from('events').select('*').eq('user_id', uid),
      ]);
      const loadedCourses = cRes.data || [];
      const loadedTasks = (tRes.data || []).map(mapTask);
      const loadedDeadlines = (dRes.data || []).map(d => mapDeadline(d, loadedCourses));
      const loadedEvents = groupEvents(eRes.data || []);

      setCourses(loadedCourses);
      setTasks(loadedTasks);
      setDeadlines(loadedDeadlines);
      setEvents(loadedEvents);

      idbPutAll('tasks', loadedTasks);
      idbPutAll('deadlines', loadedDeadlines);
      idbPutAll('courses', loadedCourses);
      idbKvPut('events', loadedEvents);
    };

    loadAll();

    if (channelRef.current) sb.removeChannel(channelRef.current);

    const channel = sb.channel(`rt_${uid}`)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'tasks', filter: `user_id=eq.${uid}` },
        ({ eventType: et, new: n, old: o }) => {
          setTasks(ts => {
            let updated;
            if (n?.deleted || et === 'DELETE') updated = ts.filter(t => t.id !== (n?.id || o?.id));
            else if (et === 'INSERT') updated = [mapTask(n), ...ts.filter(t => t.id !== n.id)];
            else if (et === 'UPDATE') updated = ts.map(t => t.id === n.id ? mapTask(n) : t);
            else return ts;
            idbPutAll('tasks', updated);
            return updated;
          });
        })
      .on('postgres_changes', { event: '*', schema: 'public', table: 'deadlines', filter: `user_id=eq.${uid}` },
        ({ eventType: et, new: n, old: o }) => {
          setCourses(cs => {
            setDeadlines(ds => {
              let updated;
              if (n?.deleted) updated = ds.filter(d => d.id !== n.id);
              else if (et === 'INSERT') updated = [mapDeadline(n, cs), ...ds.filter(d => d.id !== n.id)];
              else if (et === 'UPDATE') updated = ds.map(d => d.id === n.id ? mapDeadline(n, cs) : d);
              else if (et === 'DELETE') updated = ds.filter(d => d.id !== o.id);
              else return ds;
              idbPutAll('deadlines', updated);
              return updated;
            });
            return cs;
          });
        })
      .on('postgres_changes', { event: '*', schema: 'public', table: 'courses', filter: `user_id=eq.${uid}` },
        ({ eventType: et, new: n, old: o }) => {
          setCourses(cs => {
            let updated;
            if (et === 'INSERT') updated = [...cs.filter(c => c.id !== n.id), n];
            else if (et === 'UPDATE') updated = cs.map(c => c.id === n.id ? n : c);
            else if (et === 'DELETE') updated = cs.filter(c => c.id !== o.id);
            else return cs;
            idbPutAll('courses', updated);
            return updated;
          });
        })
      .on('postgres_changes', { event: '*', schema: 'public', table: 'events', filter: `user_id=eq.${uid}` },
        () => {
          sb.from('events').select('*').eq('user_id', uid).then(({ data }) => {
            if (data) {
              const grouped = groupEvents(data);
              setEvents(grouped);
              idbKvPut('events', grouped);
            }
          });
        })
      .subscribe();

    channelRef.current = channel;
    return () => { sb.removeChannel(channel); channelRef.current = null; };
  }, [session]);

  if (session === undefined) return (
    <div className="app">
      <OfflineBanner />
      <div className="phone"><div className="phone-content"><LoadingScreen /></div></div>
      <InstallBanner />
    </div>
  );

  if (!session) return (
    <div className="app">
      <OfflineBanner />
      <div className="phone"><div className="phone-content"><AuthScreen /></div></div>
      <InstallBanner />
    </div>
  );

  const uid = session.user.id;
  const userName = session.user.user_metadata?.full_name || session.user.email?.split('@')[0] || 'Student';
  const userEmail = session.user.email || '';

  const toggleTheme = () => setTheme(t => t === 'dark' ? 'light' : 'dark');
  const push = (screen) => setPushed(screen);
  const pop = () => setPushed(null);

  const toggleTask = async (id) => {
    const task = tasks.find(t => t.id === id);
    if (!task) return;
    const newDone = !task.done;
    setTasks(ts => ts.map(t => t.id === id ? { ...t, done: newDone } : t));
    const { error } = await sb.from('tasks').update({ done: newDone }).eq('id', id);
    if (error) {
      setTasks(ts => ts.map(t => t.id === id ? { ...t, done: !newDone } : t));
    }
  };

  const addTask = (task) => setTasks(ts => [task, ...ts]);
  const logout = async () => { await sb.auth.signOut(); };

  const renderScreen = () => {
    if (pushed === 'tracking') return <TrackingScreen courses={courses} onBack={pop} />;
    if (pushed === 'chat') return <ChatScreen onBack={pop} />;
    if (pushed === 'studyplan') return <StudyPlanScreen onBack={pop} />;
    if (pushed === 'settings') return <SettingsScreen theme={theme} onThemeToggle={toggleTheme} onBack={pop}
      userName={userName} userEmail={userEmail} plan="free" onLogout={logout} />;

    switch (tab) {
      case 'dashboard': return <DashboardScreen tasks={tasks} courses={courses} deadlines={deadlines}
        userName={userName} streak={streak} onToggleTask={toggleTask} onPush={push} onAdd={() => setShowAdd(true)} />;
      case 'calendar': return <CalendarScreen events={events} />;
      case 'focus': return <FocusScreen uid={uid} />;
      case 'chat': return <ChatScreen />;
      default: return <DashboardScreen tasks={tasks} courses={courses} deadlines={deadlines}
        userName={userName} streak={streak} onToggleTask={toggleTask} onPush={push} onAdd={() => setShowAdd(true)} />;
    }
  };

  return (
    <div className="app">
      <OfflineBanner />
      <InstallBanner />
      <div className="phone">
        <div className="phone-content">
          {renderScreen()}
          {!pushed && <BottomNav active={tab} onNavigate={setTab} onAdd={() => setShowAdd(true)} />}
          {showAdd && <AddTaskSheet courses={courses} uid={uid} onClose={() => setShowAdd(false)} onAdd={addTask} />}
        </div>
      </div>
    </div>
  );
}

// ─── Mount ────────────────────────────────────────────────────────────────────

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
