/* ============================================================
   Dashboard: Login, layout y panel
   ============================================================ */

function Login({ go, onSignIn }) {
  const [email, setEmail] = React.useState('');
  const [pass, setPass] = React.useState('');
  const [error, setError] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [resetSent, setResetSent] = React.useState(false);
  const [resetError, setResetError] = React.useState('');

  const submit = async (e) => {
    e.preventDefault();
    setError('');
    setBusy(true);
    try {
      await onSignIn(email, pass);
    } catch (err) {
      console.error(err);
      setError('No se pudo iniciar sesión. Revisa el usuario en Supabase Auth.');
    } finally {
      setBusy(false);
    }
  };

  const handleReset = async (e) => {
    e.preventDefault();
    setResetError('');
    if (!email) { setResetError('Escribe tu email primero'); return; }
    try {
      await window.MPM_DB.resetPassword(email);
      setResetSent(true);
    } catch (err) {
      console.error(err);
      setResetError('No se pudo enviar el correo. Intenta de nuevo.');
    }
  };

  return (
    <div style={{ minHeight: '100vh', display: 'grid', gridTemplateColumns: '1fr 1fr' }} className="login-wrap">
      <div className="login-art" style={{ position: 'relative', overflow: 'hidden', background: 'linear-gradient(150deg, var(--rose-tint), var(--sky-tint) 55%, var(--sand-tint))' }}>
        <div style={{ position: 'absolute', top: -90, right: -60, width: 360, height: 360, borderRadius: '50%', background: 'radial-gradient(circle, var(--rose-soft), transparent 70%)' }} />
        <div style={{ position: 'absolute', bottom: -70, left: -50, width: 320, height: 320, borderRadius: '50%', background: 'radial-gradient(circle, var(--sky-soft), transparent 70%)' }} />
        <Sparkle size={26} color="var(--rose)" style={{ position: 'absolute', top: '22%', left: '20%' }} />
        <Sparkle size={18} color="var(--sand)" delay={1} style={{ position: 'absolute', top: '60%', right: '24%' }} />
        <Sparkle size={14} color="var(--sky)" delay={2} style={{ position: 'absolute', bottom: '20%', left: '34%' }} />
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: 56 }}>
          <Signature text="Maria Paula Muriel" size={64} color="var(--ink)" />
          <p className="eyebrow" style={{ marginTop: 8, marginLeft: 6 }}>Photography - Panel privado</p>
          <p className="serif" style={{ marginTop: 'auto', fontSize: 30, fontStyle: 'italic', fontWeight: 500, lineHeight: 1.25, color: 'var(--ink)', maxWidth: 380 }}>
            "Tu archivo visual, en un solo lugar."
          </p>
        </div>
      </div>

      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 40, background: 'var(--bg)' }}>
        <form onSubmit={submit} className="animate-fadeUp" style={{ width: '100%', maxWidth: 380 }}>
          <div className="login-mark" style={{ display: 'none', textAlign: 'center', marginBottom: 24 }}><Signature text="Maria Paula Muriel" size={44} /></div>
          <h1 className="serif" style={{ margin: 0, fontSize: 40, fontWeight: 500, color: 'var(--ink)' }}>Iniciar sesión</h1>
          <p style={{ margin: '8px 0 32px', color: 'var(--ink-2)', fontSize: 15 }}>Bienvenida de nuevo, María Paula.</p>
          <div style={{ marginBottom: 18 }}>
            <label className="field-label" htmlFor="login-email">Email</label>
            <div style={{ position: 'relative' }}>
              <Icon name="mail" size={17} style={{ position: 'absolute', left: 14, top: 14, color: 'var(--ink-3)' }} />
              <input id="login-email" className="input" style={{ paddingLeft: 42 }} value={email} onChange={e => setEmail(e.target.value)} type="email" placeholder="ejemplo@gmail.com" />
            </div>
          </div>
          <div style={{ marginBottom: 10 }}>
            <label className="field-label" htmlFor="login-pass">Contraseña</label>
            <div style={{ position: 'relative' }}>
              <Icon name="lock" size={17} style={{ position: 'absolute', left: 14, top: 14, color: 'var(--ink-3)' }} />
              <input id="login-pass" className="input" style={{ paddingLeft: 42 }} value={pass} onChange={e => setPass(e.target.value)} type="password" placeholder="contraseña" />
            </div>
          </div>
          <div style={{ textAlign: 'right', marginBottom: 22 }}>
            {resetSent
              ? <span style={{ fontSize: 13, color: 'var(--green-deep)' }}>Revisa tu email para restablecer la contraseña.</span>
              : <button type="button" onClick={handleReset} style={{ background: 'none', border: 'none', padding: 0, fontSize: 13, color: 'var(--ink-3)', cursor: 'pointer', textDecoration: 'underline' }}>¿Olvidaste tu contraseña?</button>
            }
            {resetError && <p style={{ margin: '4px 0 0', fontSize: 12, color: 'var(--danger-text)' }}>{resetError}</p>}
          </div>
          {error && <p style={{ margin: '0 0 14px', color: 'var(--danger-text)', fontSize: 13 }}>{error}</p>}
          <button className="btn btn-primary btn-block btn-lg" type="submit" disabled={busy}>{busy ? 'Entrando...' : 'Iniciar sesión'}</button>
          <button type="button" onClick={() => go('home')} className="btn btn-soft btn-block" style={{ marginTop: 12 }}>
            <Icon name="arrowLeft" size={15} /> Volver al sitio
          </button>
          <p style={{ textAlign: 'center', marginTop: 24, fontSize: 12.5, color: 'var(--ink-3)' }}>Acceso exclusivo para administración del archivo</p>
        </form>
      </div>
    </div>
  );
}

function DashLayout({ go, route, children, title, sub, action, onSignOut }) {
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    if (!open) return;
    const scrollY = window.scrollY || window.pageYOffset || 0;
    const previousOverflow = document.body.style.overflow;
    const previousPosition = document.body.style.position;
    const previousTop = document.body.style.top;
    const previousWidth = document.body.style.width;
    document.body.style.overflow = 'hidden';
    document.body.style.position = 'fixed';
    document.body.style.top = `-${scrollY}px`;
    document.body.style.width = '100%';
    return () => {
      document.body.style.overflow = previousOverflow;
      document.body.style.position = previousPosition;
      document.body.style.top = previousTop;
      document.body.style.width = previousWidth;
      window.scrollTo(0, scrollY);
    };
  }, [open]);
  const nav = [
    { id: 'dash',       label: 'Panel',        icon: 'grid'   },
    { id: 'manage',     label: 'Fotografías',  icon: 'photos' },
    { id: 'upload',     label: 'Subir foto',   icon: 'upload' },
    { id: 'catalog',    label: 'Organización', icon: 'layers' },
    { id: 'about-edit', label: 'Sobre mí',     icon: 'user'   },
  ];
  return (
    <div style={{ minHeight: '100vh', display: 'flex', background: 'var(--surface-2)' }}>
      <aside className={`dash-sidebar ${open ? 'open' : ''}`} style={{ width: 248, flexShrink: 0, background: 'var(--surface)', borderRight: '1px solid var(--line)', display: 'flex', flexDirection: 'column', position: 'sticky', top: 0, height: '100vh' }}>
        <div className="dash-sidebar-head" style={{ padding: '26px 24px 20px', borderBottom: '1px solid var(--line)' }}>
          <Signature text="Maria Paula Muriel" size={30} color="var(--ink)" />
          <div className="eyebrow" style={{ fontSize: 9, marginTop: 2 }}>Panel privado</div>
        </div>
        <nav className="dash-sidebar-nav" style={{ padding: 14, flex: 1 }}>
          {nav.map(n => {
            const active = route === n.id;
            return (
              <button key={n.id} onClick={() => { go(n.id); setOpen(false); }} style={{
                width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '12px 14px', borderRadius: 'var(--r-sm)',
                border: 'none', marginBottom: 4, fontSize: 14.5, fontWeight: 600, transition: 'all .2s',
                background: active ? 'var(--rose-tint)' : 'transparent', color: active ? 'var(--rose-deep)' : 'var(--ink-2)' }}>
                <Icon name={n.icon} size={19} stroke={active ? 1.9 : 1.7} /> {n.label}
              </button>
            );
          })}
        </nav>
        <div className="dash-sidebar-actions" style={{ padding: 14, borderTop: '1px solid var(--line)' }}>
          <button onClick={() => { go('home'); setOpen(false); }} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px', borderRadius: 'var(--r-sm)', border: 'none', background: 'transparent', color: 'var(--ink-2)', fontSize: 14, fontWeight: 500 }}>
            <Icon name="gallery" size={18} /> Ver sitio público
          </button>
          <button onClick={() => { setOpen(false); onSignOut ? onSignOut() : window.__mpmSignOut ? window.__mpmSignOut() : go('login'); }} style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px', borderRadius: 'var(--r-sm)', border: 'none', background: 'transparent', color: 'var(--danger-text)', fontSize: 14, fontWeight: 500 }}>
            <Icon name="logout" size={18} /> Cerrar sesión
          </button>
        </div>
      </aside>
      {open && <div onClick={() => setOpen(false)} onTouchMove={e => e.preventDefault()} onWheel={e => e.preventDefault()} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.3)', zIndex: 49, touchAction: 'none' }} className="dash-overlay" />}

      <main style={{ flex: 1, minWidth: 0 }}>
        <header style={{ position: 'sticky', top: 0, zIndex: 30, background: 'rgba(247,242,239,.85)', backdropFilter: 'blur(12px)', borderBottom: '1px solid var(--line)', padding: '18px 32px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <button className="dash-burger" onClick={() => setOpen(true)} style={{ display: 'none', background: 'none', border: 'none', color: 'var(--ink)' }}><Icon name="menu" size={24} /></button>
            <div>
              <h1 className="serif" style={{ margin: 0, fontSize: 28, fontWeight: 500, color: 'var(--ink)', lineHeight: 1.1 }}>{title}</h1>
              {sub && <p style={{ margin: '2px 0 0', fontSize: 13.5, color: 'var(--ink-3)' }}>{sub}</p>}
            </div>
          </div>
          {action}
        </header>
        <div style={{ padding: '28px 32px 60px' }}>{children}</div>
      </main>
    </div>
  );
}

function DashboardHome({ go, photos = window.PHOTOS, loadingData, onRefresh }) {
  const [syncing, setSyncing] = React.useState(false);
  const [lastSync, setLastSync] = React.useState(new Date());
  const [, setTick] = React.useState(0);
  const syncingRef = React.useRef(false);

  React.useEffect(() => {
    const t = setInterval(() => setTick(n => n + 1), 1000);
    return () => clearInterval(t);
  }, []);

  const doRefresh = React.useCallback(async () => {
    if (!onRefresh || !window.MPM_DB?.enabled || syncingRef.current) return;
    syncingRef.current = true;
    setSyncing(true);
    try {
      await onRefresh();
      setLastSync(new Date());
    } finally {
      syncingRef.current = false;
      setSyncing(false);
    }
  }, [onRefresh]);

  React.useEffect(() => {
    if (!window.MPM_DB?.enabled) return;
    const t = setInterval(doRefresh, 30000);
    return () => clearInterval(t);
  }, [doRefresh]);

  const published   = photos.filter(p => p.status === 'published').length;
  const drafts      = photos.filter(p => p.status === 'draft').length;
  const collections = new Set(photos.map(p => p.col).filter(Boolean)).size;
  const favorites   = photos.filter(p => p.fav).length;
  const total       = photos.length;

  const totalKb    = photos.reduce((acc, p) => acc + (Number(p.kb) || 0), 0);
  const usedMb     = totalKb / 1024;
  const usedGb     = usedMb / 1024;
  const R2_GB      = 10;
  const pct        = Math.min(100, (usedGb / R2_GB) * 100);
  const avgKb      = total > 0 ? Math.round(totalKb / total) : 0;
  const storageLabel = totalKb < 1024 ? `${totalKb} KB`
    : usedMb < 1024 ? `${usedMb.toFixed(0)} MB`
    : `${usedGb.toFixed(3)} GB`;
  const gaugeColor = pct < 50 ? 'var(--green)' : pct < 80 ? 'var(--sand)' : 'var(--rose)';

  const byCat = window.CATEGORIES
    .map(c => ({ ...c, count: photos.filter(p => p.cat === c.id).length }))
    .filter(c => c.count > 0)
    .sort((a, b) => b.count - a.count);
  const maxCat = Math.max(...byCat.map(c => c.count), 1);

  const recent  = photos.slice().sort((a, b) => String(b.date).localeCompare(String(a.date))).slice(0, 4);
  const lastPub = photos.filter(p => p.status === 'published')
    .sort((a, b) => String(b.date).localeCompare(String(a.date)))[0];

  function timeAgo(date) {
    const s = Math.floor((new Date() - date) / 1000);
    if (s < 60) return `hace ${s}s`;
    if (s < 3600) return `hace ${Math.floor(s / 60)}m`;
    return `hace ${Math.floor(s / 3600)}h`;
  }

  const statCards = [
    { icon: 'check', label: 'Publicadas',  value: published,   tone: 'var(--published)', bg: 'var(--published-soft)' },
    { icon: 'edit',  label: 'Borradores',  value: drafts,      tone: 'var(--draft)',      bg: 'var(--draft-soft)'     },
    { icon: 'layers',label: 'Colecciones', value: collections, tone: 'var(--rose-deep)', bg: 'var(--rose-soft)'      },
    { icon: 'heart', label: 'Favoritas',   value: favorites,   tone: 'var(--rose)',       bg: 'var(--rose-soft)'      },
    { icon: 'image', label: 'Total fotos', value: total,       tone: 'var(--sky-deep)',   bg: 'var(--sky-soft)'       },
  ];

  return (
    <DashLayout go={go} route="dash" title="Panel" sub="Resumen de tu archivo visual"
      action={<button className="btn btn-primary" onClick={() => go('upload')}><Icon name="plus" size={17} /> Subir nueva foto</button>}>

      {/* Sync banner */}
      <div className="card" style={{ padding: '12px 18px', marginBottom: 22, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, background: 'var(--sky-tint)', borderColor: 'var(--sky-soft)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Icon name={syncing ? 'replace' : 'check'} size={18} style={{ color: syncing ? 'var(--sand)' : 'var(--sky-text)', flexShrink: 0, animation: syncing ? 'spin .8s linear infinite' : 'none' }} stroke={2} />
          <p style={{ margin: 0, fontSize: 13.5, color: 'var(--ink-2)' }}>
            {loadingData
              ? 'Conectando con Supabase...'
              : syncing
              ? 'Actualizando datos...'
              : window.MPM_DB?.enabled
              ? `Sincronizado con Supabase · Actualizado ${timeAgo(lastSync)}`
              : 'Configura Supabase para guardar los cambios de forma permanente.'}
          </p>
        </div>
        {window.MPM_DB?.enabled && !loadingData && (
          <button onClick={doRefresh} disabled={syncing}
            style={{ display: 'flex', alignItems: 'center', gap: 6, background: 'none', border: '1px solid var(--line-2)', borderRadius: 'var(--r-sm)', padding: '6px 12px', fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', cursor: syncing ? 'not-allowed' : 'pointer', whiteSpace: 'nowrap', opacity: syncing ? 0.5 : 1 }}>
            <Icon name="replace" size={14} /> Actualizar
          </button>
        )}
      </div>

      {/* Stats cards */}
      <div className="dash-stat-grid" style={{ display: 'grid', gap: 14 }}>
        {statCards.map((st, i) => (
          <div key={st.label} className="card stag" style={{ padding: 20, '--d': `${i*.06}s` }}>
            <div style={{ width: 38, height: 38, borderRadius: 'var(--r-sm)', background: st.bg, display: 'grid', placeItems: 'center', marginBottom: 14 }}>
              <Icon name={st.icon} size={18} style={{ color: st.tone }} stroke={2} />
            </div>
            <div className="serif" style={{ fontSize: 36, fontWeight: 600, color: 'var(--ink)', lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>{st.value}</div>
            <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 6 }}>{st.label}</div>
          </div>
        ))}
      </div>

      {/* Storage + last published */}
      <div className="dash-cols" style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 18, marginTop: 18 }}>
        <div className="card" style={{ padding: 24 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: 'var(--ink)' }}>Almacenamiento R2</h3>
            <span style={{ fontSize: 12, color: 'var(--ink-3)', background: 'var(--surface-2)', padding: '4px 10px', borderRadius: 99 }}>Plan gratis · 10 GB</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
            <span className="serif" style={{ fontSize: 34, fontWeight: 600, color: 'var(--ink)', fontVariantNumeric: 'tabular-nums' }}>{storageLabel}</span>
            <span style={{ color: 'var(--ink-3)', fontSize: 14 }}>de {R2_GB} GB</span>
            <span style={{ marginLeft: 'auto', fontSize: 14, fontWeight: 700, color: gaugeColor, fontVariantNumeric: 'tabular-nums' }}>{pct.toFixed(1)}%</span>
          </div>
          <div style={{ height: 10, borderRadius: 99, background: 'var(--surface-3)', marginTop: 12, overflow: 'hidden' }}>
            <div style={{ width: '100%', height: '100%', borderRadius: 99, background: `linear-gradient(90deg, var(--rose), ${gaugeColor})`, transform: `scaleX(${pct / 100})`, transformOrigin: 'left center', transition: 'transform .6s' }} />
          </div>
          <div style={{ display: 'flex', gap: 20, marginTop: 14, fontSize: 12.5, color: 'var(--ink-3)', flexWrap: 'wrap' }}>
            <span><strong style={{ color: 'var(--ink)' }}>{total}</strong> fotos en R2</span>
            <span>Promedio <strong style={{ color: 'var(--ink)' }}>{avgKb >= 1024 ? `${(avgKb/1024).toFixed(1)} MB` : `${avgKb} KB`}</strong>/foto</span>
            <span>Libre <strong style={{ color: 'var(--ink)' }}>{(R2_GB - usedGb).toFixed(2)} GB</strong></span>
          </div>
        </div>

        <div className="card" style={{ padding: 24, display: 'flex', flexDirection: 'column' }}>
          <h3 style={{ margin: '0 0 16px', fontSize: 16, fontWeight: 700, color: 'var(--ink)' }}>Última publicación</h3>
          {lastPub ? (
            <div style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
              <PhotoFrame photo={lastPub} ratio="1/1" label={false} wm={false} temp={false} rounded="var(--r-sm)" style={{ width: 72, flexShrink: 0 }} />
              <div style={{ minWidth: 0 }}>
                <div className="serif" style={{ fontSize: 18, fontStyle: 'italic', color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{lastPub.title}</div>
                <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 4 }}>{lastPub.date}</div>
                <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{lastPub.res} · {lastPub.kb} KB</div>
              </div>
            </div>
          ) : (
            <p style={{ color: 'var(--ink-3)', fontSize: 13.5 }}>Aún no hay fotos publicadas.</p>
          )}
          <button className="btn btn-soft btn-sm" style={{ marginTop: 'auto', alignSelf: 'flex-start' }} onClick={() => go('manage')}>
            Gestionar <Icon name="arrowRight" size={14} />
          </button>
        </div>
      </div>

      {/* Category breakdown */}
      {byCat.length > 0 && (
        <div className="card" style={{ padding: 24, marginTop: 18 }}>
          <h3 style={{ margin: '0 0 18px', fontSize: 16, fontWeight: 700, color: 'var(--ink)' }}>Por categoría</h3>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {byCat.map(c => (
              <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <span style={{ width: 90, fontSize: 13, color: 'var(--ink-2)', textAlign: 'right', flexShrink: 0 }}>{c.label}</span>
                <div style={{ flex: 1, height: 8, background: 'var(--surface-3)', borderRadius: 99, overflow: 'hidden' }}>
                  <div style={{ width: '100%', height: '100%', background: toneVar(c.tone), borderRadius: 99, transform: `scaleX(${c.count / maxCat})`, transformOrigin: 'left center', transition: 'transform .5s' }} />
                </div>
                <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--ink)', width: 28, textAlign: 'right' }}>{c.count}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Recent photos */}
      {recent.length > 0 && (
        <>
          <div style={{ marginTop: 26, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <h3 style={{ margin: 0, fontSize: 17, fontWeight: 700, color: 'var(--ink)' }}>Últimas fotos subidas</h3>
            <button className="btn btn-soft btn-sm" onClick={() => go('manage')}>Ver todas</button>
          </div>
          <div className="recent-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 16, marginTop: 16 }}>
            {recent.map(p => (
              <div key={p.id} className="card" style={{ overflow: 'hidden' }}>
                <PhotoFrame photo={p} ratio="4/3" label={false} temp={false} wmStyle="white" rounded="0" />
                <div style={{ padding: '12px 14px' }}>
                  <span className="serif" style={{ fontSize: 15, fontStyle: 'italic', color: 'var(--ink)', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.title}</span>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 8 }}>
                    <StatusBadge status={p.status} />
                    <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{p.kb} KB</span>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </>
      )}
    </DashLayout>
  );
}

Object.assign(window, { Login, DashLayout, DashboardHome });
