// AppShell.jsx — iPad frame, lock screen, home dashboard, top bar
// Minimal Apple-inspired design. Neutral-only. Color reserved for status.

const { useState: useStateShell, useEffect: useEffectShell } = React;

// ------------------------------------------------------------------
// iPad frame — portrait only (iPad mini at ~744×1133)
// ------------------------------------------------------------------
const IPadFrame = ({ children, showFrame = true }) => {
  const screenW = 744;
  const screenH = 1133;
  const bezel = 22;
  const outerW = screenW + bezel * 2;
  const outerH = screenH + bezel * 2;

  if (!showFrame) {
    return (
      <div style={{
        width: screenW, height: screenH,
        background: 'var(--bg-page)',
        overflow: 'hidden', position: 'relative',
        borderRadius: 18,
        boxShadow: 'var(--shadow-2)',
      }}>
        {children}
      </div>
    );
  }

  return (
    <div style={{
      width: outerW, height: outerH,
      background: '#0A0A0A',
      borderRadius: 48,
      padding: bezel,
      position: 'relative',
      boxShadow: '0 30px 60px rgba(0,0,0,0.18), 0 0 0 1.5px #1F1F22',
    }}>
      <div style={{
        position: 'absolute',
        top: 11,
        left: '50%',
        transform: 'translateX(-50%)',
        width: 6, height: 6, borderRadius: 999, background: '#2A2A2D',
        zIndex: 5,
      }} />
      <div style={{
        width: screenW, height: screenH,
        background: 'var(--bg-page)',
        borderRadius: 28,
        overflow: 'hidden',
        position: 'relative',
      }}>
        {children}
      </div>
    </div>
  );
};

// ------------------------------------------------------------------
// Top status bar
// ------------------------------------------------------------------
const StatusStrip = ({ staff, onSignOut, onLock }) => {
  const [now, setNow] = useStateShell(new Date());
  useEffectShell(() => {
    const t = setInterval(() => setNow(new Date()), 30000);
    return () => clearInterval(t);
  }, []);
  const time = now.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
  const date = now.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
  return (
    <div style={{
      height: 44, padding: '0 22px',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      fontSize: 13, fontWeight: 500, color: 'var(--fg-2)',
      background: 'transparent',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ fontWeight: 600, color: 'var(--fg-1)' }}>{time}</span>
        <span style={{ color: 'var(--fg-3)' }}>·</span>
        <span>{date}</span>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--fg-3)', letterSpacing: '0.06em', textTransform: 'uppercase' }}>
          Kitchen iPad
        </span>
        <Icon name="wifi" size={14} color="var(--fg-2)" strokeWidth={1.8} />
        <Icon name="battery" size={22} color="var(--fg-2)" strokeWidth={1.4} />
        {onLock && (
          <button onClick={onLock} style={{
            width: 26, height: 26, borderRadius: 999,
            background: 'var(--bg-sunken)',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            marginLeft: 2,
          }} title="Lock device">
            <Icon name="lock" size={13} color="var(--fg-2)" strokeWidth={1.8} />
          </button>
        )}
      </div>
    </div>
  );
};

// ------------------------------------------------------------------
// Lock screen — DEVICE-level unlock. Not a personal login.
// The iPad belongs to the store. Each iPad consumes a unique device code
// generated in the admin portal. Once bound, this iPad never asks again
// unless the owner ends the session (which marks the code 'revoked').
// ------------------------------------------------------------------
const BOUND_CODE_KEY = 'snap-bound-code-v1';

// Look up a code in Supabase and return the row if it's not revoked.
// Returns { match, revoked } so the caller can distinguish "wrong code" from
// "revoked code" for a better error message.
const findValidDevice = async (code) => {
  if (!window.supa) return { match: null, revoked: false };
  const { data, error } = await window.supa
    .from('devices')
    .select('*')
    .eq('restaurant_id', window.RESTAURANT_ID)
    .eq('code', code)
    .maybeSingle();
  if (error || !data) return { match: null, revoked: false };
  if (data.status === 'revoked') return { match: null, revoked: true };
  return { match: data, revoked: false };
};

const LockScreen = ({ onUnlock }) => {
  const [pin, setPin] = useStateShell('');
  const [error, setError] = useStateShell('');
  const [shake, setShake] = useStateShell(false);

  const handleEnter = async (p) => {
    const { match, revoked } = await findValidDevice(p);
    if (!match) {
      setError(revoked ? 'This code has been revoked. Ask the owner for a new one.' : 'Wrong code. Try again.');
      setShake(true);
      setTimeout(() => { setPin(''); setShake(false); }, 500);
      setTimeout(() => setError(''), 3200);
      return;
    }
    // Bind: persist locally and flip the row to status=bound with a fresh
    // bound_at + last_seen so the admin portal sees this iPad as active.
    try { localStorage.setItem(BOUND_CODE_KEY, match.code); } catch {}
    const updates = { last_seen: new Date().toISOString() };
    if (match.status === 'unused') {
      updates.status = 'bound';
      updates.bound_at = new Date().toISOString();
    }
    window.supa.from('devices').update(updates).eq('id', match.id).then(() => {});
    onUnlock(match);
  };

  const dots = Array.from({ length: 6 }).map((_, i) => (
    <div key={i} style={{
      width: 14, height: 14, borderRadius: 999,
      background: i < pin.length ? 'var(--fg-1)' : 'transparent',
      border: '2px solid ' + (i < pin.length ? 'var(--fg-1)' : 'var(--border-1)'),
      transition: 'all 160ms var(--ease-snap)',
    }} />
  ));

  return (
    <div style={{
      height: '100%', width: '100%',
      background: '#FFFFFF',
      color: 'var(--fg-1)',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      padding: '48px 40px',
      gap: 36,
      position: 'relative',
    }}>
      <div style={{ textAlign: 'center', maxWidth: 480 }}>
        <div style={{
          fontSize: 12, fontWeight: 600, letterSpacing: '0.16em',
          textTransform: 'uppercase', color: 'var(--fg-3)',
          marginBottom: 22,
        }}>
          Snap Operation
        </div>
        <div style={{ fontSize: 38, fontWeight: 600, letterSpacing: '-0.025em', lineHeight: 1.1, color: 'var(--fg-1)' }}>
          Enter device code
        </div>
        <div style={{ marginTop: 14, fontSize: 15, color: 'var(--fg-2)', lineHeight: 1.5 }}>
          The owner will give you a 6-digit code in the admin portal.<br/>
          You only have to enter it once on this iPad.
        </div>
      </div>

      <div style={{
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 30,
        animation: shake ? 'shake 450ms' : 'none',
      }}>
        <div style={{ display: 'flex', gap: 16 }}>{dots}</div>
        <LockNumPad value={pin} onChange={setPin} onEnter={handleEnter} maxLen={6} />
        <div style={{ fontSize: 13, color: 'var(--danger)', height: 16, fontWeight: 500, textAlign: 'center', maxWidth: 320 }}>
          {error || ''}
        </div>
      </div>
      <style>{`
        @keyframes shake {
          10%, 90% { transform: translateX(-2px); }
          20%, 80% { transform: translateX(3px); }
          30%, 50%, 70% { transform: translateX(-6px); }
          40%, 60% { transform: translateX(6px); }
        }
      `}</style>
    </div>
  );
};

window.BOUND_CODE_KEY = BOUND_CODE_KEY;
window.findValidDevice = findValidDevice;

const LockNumPad = ({ value, onChange, onEnter, maxLen }) => {
  const keys = ['1','2','3','4','5','6','7','8','9','','0','⌫'];
  const tap = (k) => {
    if (k === '') return;
    if (k === '⌫') return onChange(value.slice(0, -1));
    if (value.length >= maxLen) return;
    const next = value + k;
    onChange(next);
    if (next.length === maxLen && onEnter) setTimeout(() => onEnter(next), 120);
  };
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 92px)', gap: 18 }}>
      {keys.map((k, i) => (
        <button key={i} onClick={() => tap(k)} disabled={k === ''} style={{
          height: 92, width: 92,
          background: k === '' ? 'transparent' : '#F2F2F5',
          borderRadius: 999,
          color: 'var(--fg-1)', fontSize: 38, fontWeight: 300,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          cursor: k === '' ? 'default' : 'pointer',
          transition: 'background 100ms, transform 120ms',
          letterSpacing: '-0.02em',
        }}
        onMouseDown={e => k && (e.currentTarget.style.background = '#E5E5EA')}
        onMouseUp={e => { e.currentTarget.style.background = k ? '#F2F2F5' : 'transparent'; }}
        onMouseLeave={e => { e.currentTarget.style.background = k ? '#F2F2F5' : 'transparent'; }}
        >
          {k === '⌫' ? <Icon name="backspace" size={26} color="var(--fg-1)" strokeWidth={1.4} /> : k}
        </button>
      ))}
    </div>
  );
};

// ------------------------------------------------------------------
// Home dashboard — minimal list-style tiles
// ------------------------------------------------------------------
const HomeScreen = ({ staff, onNavigate, prepState, closingState }) => {
  const prepItems = window.SAMPLE_PREP_ITEMS;
  const prepDone = prepItems.reduce((acc, it) => {
    const entries = prepState[it.id] || [];
    const total = entries.reduce((s, e) => s + e.qty, 0);
    return acc + Math.min(1, total / it.target);
  }, 0);
  const prepPct = Math.round((prepDone / prepItems.length) * 100);
  const prepPrimaryDone = prepItems.filter(it => it.priority === 'primary').reduce((acc, it) => {
    const entries = prepState[it.id] || [];
    const total = entries.reduce((s, e) => s + e.qty, 0);
    return total >= it.target ? acc + 1 : acc;
  }, 0);
  const prepPrimaryTotal = prepItems.filter(it => it.priority === 'primary').length;

  const closingTotalSteps = window.SAMPLE_CLOSING.reduce((acc, z) =>
    acc + z.tasks.reduce((a, t) => a + t.steps.length, 0), 0);
  const closingDoneSteps = Object.values(closingState).reduce((acc, task) =>
    acc + Object.values(task).filter(s => s.done).length, 0);
  const closingPct = closingTotalSteps ? Math.round((closingDoneSteps / closingTotalSteps) * 100) : 0;

  const now = new Date();
  const date = now.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
  const greeting = (() => {
    const h = now.getHours();
    if (h < 11) return 'Good morning';
    if (h < 17) return 'Good afternoon';
    return 'Good evening';
  })();

  const tiles = [
    {
      key: 'prep',
      title: 'Daily Prep',
      sub: `${prepPrimaryDone} of ${prepPrimaryTotal} primary items ready`,
      pct: prepPct,
      icon: 'clipboard',
      contributors: Array.from(new Set(Object.values(prepState).flat().map(e => e.staffId))),
    },
    {
      key: 'closing',
      title: 'Daily Closing',
      sub: `${closingDoneSteps} of ${closingTotalSteps} steps complete`,
      pct: closingPct,
      icon: 'broom',
      contributors: Array.from(new Set(Object.values(closingState).flatMap(t => Object.values(t).filter(s=>s.done).map(s=>s.staffId)))),
    },
    {
      key: 'ordering',
      title: 'Truck Order',
      sub: 'Count what you have, suggest the rest',
      pct: null,
      icon: 'truck',
      meta: 'Daily',
      contributors: [],
    },
    {
      key: 'training',
      title: 'Training',
      sub: 'Browse items and sign-offs',
      pct: null,
      icon: 'sparkle',
      meta: 'Anytime',
      contributors: [],
    },
  ];

  return (
    <div style={{
      height: '100%', display: 'flex', flexDirection: 'column',
      padding: '12px 32px 28px',
    }}>
      <div style={{ padding: '16px 0 24px' }}>
        <div style={{ fontSize: 13, color: 'var(--fg-2)', fontWeight: 500 }}>{date}</div>
        <div style={{ fontSize: 30, fontWeight: 600, letterSpacing: '-0.025em', color: 'var(--fg-1)', marginTop: 3 }}>
          {greeting}, {staff.name}
        </div>
      </div>

      <div style={{
        flex: 1,
        display: 'grid',
        gridTemplateColumns: '1fr 1fr',
        gridTemplateRows: '1fr 1fr',
        gap: 14,
      }}>
        {tiles.map(t => (
          <button key={t.key} onClick={() => onNavigate(t.key)} style={{
            position: 'relative',
            textAlign: 'left',
            borderRadius: 16,
            padding: 22,
            background: '#FFFFFF',
            border: '1px solid var(--border-2)',
            display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
            transition: 'transform 180ms var(--ease-snap), background 150ms',
            overflow: 'hidden',
          }}
          onMouseDown={e => e.currentTarget.style.transform = 'scale(0.994)'}
          onMouseUp={e => e.currentTarget.style.transform = ''}
          onMouseLeave={e => e.currentTarget.style.transform = ''}
          >
            <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' }}>
              <div style={{
                width: 36, height: 36, borderRadius: 9,
                background: 'var(--bg-sunken)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon name={t.icon} size={18} color="var(--fg-1)" strokeWidth={1.6} />
              </div>
              {t.meta && (
                <div style={{ fontSize: 10, fontWeight: 500, color: 'var(--fg-3)', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
                  {t.meta}
                </div>
              )}
            </div>
            <div>
              <div style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.02em', color: 'var(--fg-1)', lineHeight: 1.15 }}>
                {t.title}
              </div>
              <div style={{ fontSize: 13, color: 'var(--fg-2)', marginTop: 4, fontWeight: 400, lineHeight: 1.35 }}>{t.sub}</div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              {t.pct !== null ? (
                <>
                  <div style={{ flex: 1 }}>
                    <ProgressBar pct={t.pct} height={3} color="var(--fg-1)" bg="var(--bg-sunken)" />
                  </div>
                  <div style={{ fontSize: 12, fontWeight: 500, color: 'var(--fg-2)', fontFamily: 'var(--font-num)', letterSpacing: '-0.01em', minWidth: 28, textAlign: 'right' }}>
                    {t.pct}%
                  </div>
                </>
              ) : (
                <div style={{ display: 'flex', alignItems: 'center', gap: 3, color: 'var(--fg-2)', fontWeight: 500, fontSize: 13 }}>
                  Open <Icon name="chevron" size={13} color="var(--fg-2)" strokeWidth={1.8} />
                </div>
              )}
              {t.contributors.length > 0 && (
                <AvatarStack ids={t.contributors} size={20} max={4} />
              )}
            </div>
          </button>
        ))}
      </div>
    </div>
  );
};

// ------------------------------------------------------------------
// Bottom tab bar — native-style navigation
// ------------------------------------------------------------------
const TabBar = ({ screen, onNavigate, onLock, prepState, closingState, broadcasts, trainingCompletions, currentStaff }) => {
  // Resolve prep items with any target/priority overrides the admin set,
  // and only count items actually assigned tonight (target > 0).
  let overrides = {};
  try { overrides = JSON.parse(localStorage.getItem('snap-prep-overrides') || '{}'); } catch {}
  const prepItems = (window.SAMPLE_PREP_ITEMS || [])
    .map(it => {
      const o = overrides[it.id];
      return o ? { ...it, target: o.target ?? it.target, priority: o.priority ?? it.priority } : it;
    })
    .filter(it => (it.target ?? 0) > 0);
  const prepDone = prepItems.filter(it => {
    const total = (prepState?.[it.id] || []).reduce((a, e) => a + e.qty, 0);
    return total >= it.target;
  }).length;
  const prepBadge = prepItems.length > 0 ? Math.max(0, prepItems.length - prepDone) : 0;

  // Broadcasts with NO acknowledgements yet — once anyone acks, it's cleared
  const bcBadge = (broadcasts || []).filter(b => (b.acks || []).length === 0).length;

  // Training badge — show count of NEW items across ALL staff (since the
  // iPad is shared and there's no logged-in user). This nudges someone to
  // open it; once they pick themselves they'll see their personal count.
  let trainingBadge = 0;
  const completions = trainingCompletions || {};
  (window.SAMPLE_TRAINING_ITEMS || []).forEach(item => {
    (window.SAMPLE_STAFF || []).forEach(s => {
      if (!window.isAssignedTraining(item, s)) return;
      if (window.hasCompletedTraining(item, s, completions)) return;
      trainingBadge += 1;
    });
  });

  const tabs = [
    { key: 'prep', label: 'Prep', icon: 'clipboard', badge: prepBadge },
    { key: 'ordering', label: 'Truck Order', icon: 'truck', badge: 0 },
    { key: 'training', label: 'Training', icon: 'sparkle', badge: trainingBadge },
    { key: 'broadcasts', label: 'Broadcasts', icon: 'megaphone', badge: bcBadge, highlight: bcBadge > 0 },
    { key: '__lock', label: 'Lock', icon: 'lock', badge: 0, action: 'lock' },
  ];

  return (
    <div style={{
      height: 72,
      background: 'rgba(255,255,255,0.94)',
      backdropFilter: 'saturate(180%) blur(20px)',
      WebkitBackdropFilter: 'saturate(180%) blur(20px)',
      borderTop: '1px solid var(--border-1)',
      display: 'grid',
      gridTemplateColumns: `repeat(${tabs.length}, 1fr)`,
      padding: '6px 4px 10px',
      flexShrink: 0,
    }}>
      {tabs.map(t => {
        const active = !t.action && screen === t.key;
        const handleTap = () => {
          if (t.action === 'lock') { onLock && onLock(); return; }
          onNavigate(t.key);
        };
        return (
          <button key={t.key} onClick={handleTap} style={{
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
            gap: 3,
            background: 'transparent',
            position: 'relative',
            padding: '4px 2px',
            transition: 'transform 120ms var(--ease-snap)',
          }}
          onMouseDown={e => e.currentTarget.style.transform = 'scale(0.94)'}
          onMouseUp={e => e.currentTarget.style.transform = ''}
          onMouseLeave={e => e.currentTarget.style.transform = ''}
          >
            <div style={{ position: 'relative' }}>
              <Icon
                name={t.icon}
                size={24}
                color={active ? 'var(--fg-1)' : 'var(--fg-3)'}
                strokeWidth={active ? 2 : 1.6}
              />
              {t.badge > 0 && (
                <div style={{
                  position: 'absolute', top: -5, right: -9,
                  minWidth: 16, height: 16, padding: '0 4px',
                  borderRadius: 999,
                  background: t.highlight ? '#DC2626' : '#2563EB',
                  color: '#fff',
                  fontSize: 10, fontWeight: 600,
                  fontFamily: 'var(--font-num)',
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  border: '2px solid #fff',
                  lineHeight: 1,
                  animation: t.highlight ? 'bcPulse 1.4s ease-in-out infinite' : 'none',
                }}>
                  {t.badge > 99 ? '99+' : t.badge}
                </div>
              )}
            </div>
            <div style={{
              fontSize: 11,
              fontWeight: active ? 600 : 500,
              color: active ? 'var(--fg-1)' : 'var(--fg-3)',
              letterSpacing: '-0.005em',
            }}>
              {t.label}
            </div>
          </button>
        );
      })}
      <style>{`
        @keyframes bcPulse {
          0%, 100% { transform: scale(1); }
          50% { transform: scale(1.2); }
        }
      `}</style>
    </div>
  );
};

Object.assign(window, {
  IPadFrame, StatusStrip, LockScreen, HomeScreen, TabBar,
});
