// Surface — Courses home (org dashboard with course grid)
//
// The course grid is REAL: rows come from GET /v1/courses (org-scoped by the
// signed-in user's token via RLS). Opening a card hands the row to
// app.jsx's openCourse; the demo course keeps its narrative sample content,
// every other course authors from a blank base.

function SurfaceHome({ orgId, activeCourseId, onOpenCourse, onNewCourse, onCourseDeleted, onSwitchOrg }) {
  const org = window.SAMPLE_ORGS.find(o => o.id === orgId) || window.SAMPLE_ORGS[0];
  const [courses, setCourses] = React.useState(null); // null = loading
  const [error, setError] = React.useState(null);
  const [nonce, setNonce] = React.useState(0);        // bump to re-fetch
  // Delete flow: the course pending confirmation, plus in-flight / error state.
  const [confirmDelete, setConfirmDelete] = React.useState(null);
  const [deleting, setDeleting] = React.useState(false);
  const [deleteError, setDeleteError] = React.useState(null);

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      setError(null);
      try {
        const token = await window.dynamoGetAccessToken();
        const res = await fetch(window.DYNAMO_ENV.gatewayBase + '/v1/courses', {
          headers: { Authorization: 'Bearer ' + token },
        });
        if (!res.ok) throw new Error('HTTP ' + res.status);
        const body = await res.json();
        if (cancelled) return;
        const rows = (body.courses || []).slice().sort((a, b) =>
          String(b.createdAt || '').localeCompare(String(a.createdAt || '')));
        setCourses(rows);
      } catch (e) {
        if (!cancelled) { setError(String((e && e.message) || e)); setCourses([]); }
      }
    })();
    return () => { cancelled = true; };
  }, [nonce]);

  // Permanently delete a course (DELETE /v1/courses/:id). On success, drop it
  // from the grid and notify app.jsx (which switches away if it was open).
  const doDelete = React.useCallback(async () => {
    const target = confirmDelete;
    if (!target || deleting) return;   // ignore a second click while in flight
    setDeleting(true);
    setDeleteError(null);
    try {
      const token = await window.dynamoGetAccessToken();
      const res = await fetch(
        `${window.DYNAMO_ENV.gatewayBase}/v1/courses/${target.id}`,
        { method: 'DELETE', headers: { Authorization: 'Bearer ' + token } });
      if (!res.ok) {
        let msg = '';
        try { msg = (await res.json()).message || ''; } catch { /* not JSON */ }
        throw new Error(`HTTP ${res.status}${msg ? `: ${msg}` : ''}`);
      }
      setCourses(cs => (cs || []).filter(c => c.id !== target.id));
      setConfirmDelete(null);
      if (onCourseDeleted) onCourseDeleted(target);
    } catch (e) {
      setDeleteError(String((e && e.message) || e));
    } finally {
      setDeleting(false);
    }
  }, [confirmDelete, deleting, onCourseDeleted]);

  return (
    <div style={{ height: '100%', background: 'var(--bg)', overflowY: 'auto' }}
         data-screen-label="Home · Courses overview">
      {/* Org banner */}
      <OrgBanner org={org} onSwitch={onSwitchOrg} />

      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '24px 28px 40px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
          <h2 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>Courses</h2>
          {courses && <span style={{ fontSize: 11, color: 'var(--text-faint)',
            fontFamily: 'var(--font-mono)' }}>{courses.length}</span>}
          <div style={{ flex: 1 }} />
          <button className="btn sm primary" onClick={onNewCourse}><I.Plus size={12} />New course</button>
        </div>

        {error && (
          <div style={{
            padding: '12px 14px', marginBottom: 14, background: 'var(--error-bg)',
            border: '1px solid var(--error)', borderRadius: 'var(--radius-md)',
            display: 'flex', alignItems: 'center', gap: 10, fontSize: 12.5,
            color: 'var(--error-text)',
          }}>
            <I.AlertCircle size={14} />
            <span style={{ flex: 1 }}>Couldn’t load your courses ({error}).</span>
            <button className="btn sm" onClick={() => { setCourses(null); setNonce(n => n + 1); }}>Retry</button>
          </div>
        )}

        {courses === null ? (
          <div style={{ padding: '48px 0', textAlign: 'center', fontSize: 13,
            color: 'var(--text-muted)' }}>Loading your courses…</div>
        ) : (
          <div style={{
            display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 14,
          }}>
            {courses.map(c => <CourseCard key={c.id} course={c} org={org}
              isActive={c.id === activeCourseId}
              onOpen={() => onOpenCourse(c)}
              onRequestDelete={() => { setDeleteError(null); setConfirmDelete(c); }} />)}
            <NewCourseCard onClick={onNewCourse} />
          </div>
        )}
      </div>

      {confirmDelete && window.ConfirmDialog && (
        <window.ConfirmDialog icon="Trash" tone="danger"
          title={`Delete “${confirmDelete.title}”?`}
          body={deleteError
            ? `Couldn’t delete this course (${deleteError}). Try again.`
            : 'This permanently deletes the course, all its modules and layouts, every saved version, and its uploaded media. This can’t be undone.'}
          confirmLabel={deleting ? 'Deleting…' : 'Delete course'}
          onConfirm={doDelete}
          onCancel={() => { if (!deleting) { setConfirmDelete(null); setDeleteError(null); } }} />
      )}
    </div>
  );
}

// ── OrgBanner ──────────────────────────────────────────────────────────────
function OrgBanner({ org, onSwitch }) {
  return (
    <div style={{
      background: `linear-gradient(135deg, ${org.color[0]} 0%, ${org.color[1]} 100%)`,
      color: '#fff', padding: '28px 0',
      position: 'relative', overflow: 'hidden',
    }}>
      {/* subtle pattern */}
      <svg style={{ position: 'absolute', right: -40, top: -40, opacity: 0.07 }}
           width="320" height="320" viewBox="0 0 100 100">
        <defs>
          <pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse">
            <path d="M 10 0 L 0 0 0 10" fill="none" stroke="white" strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect width="100" height="100" fill="url(#grid)"/>
      </svg>
      <div style={{ maxWidth: 1280, margin: '0 auto', padding: '0 28px',
        display: 'flex', alignItems: 'center', gap: 20 }}>
        <OrgGlyph org={org} size={56} />
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '.08em',
            textTransform: 'uppercase', opacity: 0.7, marginBottom: 4 }}>
            Organization
          </div>
          <h1 style={{ margin: 0, fontSize: 26, fontWeight: 600, letterSpacing: '-.01em' }}>
            {org.full}
          </h1>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, alignItems: 'flex-end' }}>
          <span style={{
            padding: '3px 8px', fontSize: 11, fontWeight: 600,
            background: 'rgba(255,255,255,0.18)', borderRadius: 4,
            letterSpacing: '.04em', textTransform: 'uppercase',
          }}>You · Senior Editor</span>
          <span style={{ fontSize: 12, opacity: 0.8 }}>Lisa Park · lisa@{org.id}.com</span>
        </div>
      </div>
    </div>
  );
}

function OrgGlyph({ org, size = 36 }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: size > 40 ? 12 : 8,
      background: `linear-gradient(135deg, ${org.color[0]}, ${org.color[1]})`,
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      color: '#fff', fontWeight: 700, fontSize: size > 40 ? 22 : 13,
      letterSpacing: org.glyph.length > 1 ? '-.02em' : 0,
      boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.2), 0 1px 3px rgba(0,0,0,0.2)',
    }}>{org.glyph}</div>
  );
}

function Stat({ label, value }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <span style={{ fontSize: 17, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{value}</span>
      <span style={{ fontSize: 10.5, opacity: 0.65, letterSpacing: '.04em',
        textTransform: 'uppercase', fontWeight: 600 }}>{label}</span>
    </div>
  );
}

function StatCard({ icon, label, value, sub, tone }) {
  const Icon = window.I[icon] || window.I.Hash;
  const toneColor = tone === 'warning' ? 'var(--warning)'
    : tone === 'accent' ? 'var(--accent)' : 'var(--text-muted)';
  const toneBg = tone === 'warning' ? 'var(--warning-bg)'
    : tone === 'accent' ? 'var(--accent-bg)' : 'var(--surface-inset)';
  return (
    <div className="card" style={{ padding: 14, background: 'var(--surface)' }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
        <span style={{
          width: 32, height: 32, borderRadius: 8, background: toneBg,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          color: toneColor,
        }}><Icon size={16} /></span>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>{label}</div>
          <div style={{ fontSize: 22, fontWeight: 600, lineHeight: 1.1,
            fontVariantNumeric: 'tabular-nums', color: 'var(--text)' }}>{value}</div>
          <div style={{ fontSize: 11, color: 'var(--text-faint)' }}>{sub}</div>
        </div>
      </div>
    </div>
  );
}

// ── CourseCard ─────────────────────────────────────────────────────────────
// Renders a REAL course row (GET /v1/courses): id, title, topic, enabledLangs,
// defaultLang, createdAt. Module/layout counts aren't in the row — the card
// shows topic + creation date instead.
function CourseCard({ course: c, org, isActive, onOpen, onRequestDelete }) {
  const KebabMenu = window.KebabMenu;
  const langs = c.enabledLangs || [];
  const created = c.createdAt
    ? new Date(c.createdAt).toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric' })
    : '';
  const isDemo = c.id === window.DEMO_COURSE_ID;
  // role=button (not <button>) so the kebab's own <button> can nest without
  // invalid-DOM nesting; Enter/Space still open the course.
  return (
    <div role="button" tabIndex={0} className="focusable"
      onClick={onOpen}
      onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(); } }}
      style={{
        display: 'block', width: '100%', textAlign: 'left',
        background: 'var(--surface)',
        border: '1px solid', borderColor: isActive ? 'var(--accent)' : 'var(--border)',
        borderRadius: 'var(--radius-md)', overflow: 'hidden',
        cursor: 'default', fontFamily: 'inherit', color: 'var(--text)',
        padding: 0, transition: 'border-color 150ms, box-shadow 150ms, transform 150ms',
      }}
      onMouseOver={e => { e.currentTarget.style.borderColor = 'var(--border-strong)';
        e.currentTarget.style.boxShadow = 'var(--shadow-md)'; }}
      onMouseOut={e => { e.currentTarget.style.borderColor = isActive ? 'var(--accent)' : 'var(--border)';
        e.currentTarget.style.boxShadow = 'none'; }}>
      <CourseCover course={c} org={org} />
      <div style={{ padding: '12px 14px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <h3 className="truncate" style={{ margin: 0, fontSize: 14.5, fontWeight: 600,
            color: 'var(--text)', lineHeight: 1.3, flex: 1 }}>{c.title}</h3>
          {isDemo && <span className="pill" style={{ fontSize: 10 }}>sample</span>}
          {isActive && <span className="pill accepted" style={{ fontSize: 10 }}>open</span>}
          {/* The seeded sample course is not deletable — it's the shared demo
              content the app falls back to. Real courses get the delete kebab. */}
          {!isDemo && KebabMenu && (
            <div onClick={e => e.stopPropagation()}
              onKeyDown={e => e.stopPropagation()}
              style={{ marginTop: -4, marginRight: -6 }}>
              <KebabMenu items={[
                { label: 'Delete course', icon: 'Trash', danger: true,
                  hint: 'Permanently removes the course and its media',
                  onSelect: onRequestDelete },
              ]} />
            </div>
          )}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8,
          marginTop: 10, fontSize: 11.5, color: 'var(--text-muted)' }}>
          <span className="truncate">{c.topic || '—'}</span>
          <div style={{ flex: 1 }} />
          {created && <span style={{ color: 'var(--text-faint)' }}>{created}</span>}
          <span style={{ display: 'inline-flex', gap: 1, fontSize: 13 }}>
            {langs.slice(0, 4).map(l => (
              <span key={l} style={{ lineHeight: 1 }}>{LANG_FLAGS[l] || l.toUpperCase()}</span>
            ))}
            {langs.length > 4 && <span style={{ fontSize: 10, color: 'var(--text-faint)',
              alignSelf: 'center', marginLeft: 2 }}>+{langs.length - 4}</span>}
          </span>
        </div>
      </div>
    </div>
  );
}

function CourseCover({ course: c, org }) {
  // Uniform org-colored thumbnail. Minimal — just the org glyph + brand strip.
  return (
    <div style={{
      height: 80, position: 'relative', overflow: 'hidden',
      background: `linear-gradient(135deg, ${org.color[0]} 0%, ${org.color[1]} 100%)`,
      color: 'rgba(255,255,255,.9)',
    }}>
      <div style={{ position: 'absolute', top: 12, left: 14,
        display: 'flex', alignItems: 'center', gap: 8 }}>
        <OrgGlyph org={org} size={24} />
        <span style={{ fontSize: 11, fontWeight: 600, letterSpacing: '.06em',
          textTransform: 'uppercase', opacity: 0.9 }}>{org.name}</span>
      </div>
    </div>
  );
}

// ── NewCourseCard ──────────────────────────────────────────────────────────
function NewCourseCard({ onClick }) {
  return (
    <button onClick={onClick}
      style={{
        background: 'transparent',
        border: '1px dashed var(--border-strong)',
        borderRadius: 'var(--radius-md)',
        padding: 0,
        cursor: 'default', fontFamily: 'inherit', color: 'var(--text-muted)',
        minHeight: 224, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center', gap: 8,
      }}
      onMouseOver={e => { e.currentTarget.style.borderColor = 'var(--accent)';
        e.currentTarget.style.color = 'var(--accent-text)';
        e.currentTarget.style.background = 'var(--accent-bg)'; }}
      onMouseOut={e => { e.currentTarget.style.borderColor = 'var(--border-strong)';
        e.currentTarget.style.color = 'var(--text-muted)';
        e.currentTarget.style.background = 'transparent'; }}>
      <I.Plus size={22} />
      <span style={{ fontSize: 13, fontWeight: 500 }}>New course</span>
      <span style={{ fontSize: 11, color: 'var(--text-faint)' }}>
        Start from a template or upload sources
      </span>
    </button>
  );
}

// ── Activity feed ──────────────────────────────────────────────────────────
function ActivityFeed({ org }) {
  const events = [
    { who: 'Lisa Park', what: 'edited M2-L3 in', target: 'Difficult Interactions', when: '2 min ago', icon: 'PenLine', tint: 'var(--accent)' },
    { who: 'Marco Rossi', what: 'shipped', target: 'Code of Conduct v3.4', when: '2 days ago', icon: 'Package', tint: 'var(--success)' },
    { who: 'AI · Gemini', what: 'generated cover image for', target: 'Cybersecurity Foundations', when: '32 min ago', icon: 'Sparkle', tint: 'var(--ai-text)' },
    { who: 'Akira Sato', what: 'archived', target: 'Service Excellence (legacy)', when: '6 weeks ago', icon: 'History', tint: 'var(--text-muted)' },
    { who: 'Lisa Park', what: 'added Italian translations to', target: 'Guest Privacy & GDPR', when: '1 hr ago', icon: 'Globe', tint: 'var(--accent)' },
  ];
  return (
    <div className="card" style={{ padding: 4 }}>
      {events.map((e, i) => {
        const Icon = window.I[e.icon] || window.I.Activity;
        return (
          <div key={i} style={{
            display: 'grid', gridTemplateColumns: '28px 1fr auto', gap: 12, alignItems: 'center',
            padding: '10px 14px',
            borderBottom: i < events.length - 1 ? '1px solid var(--border-faint)' : 'none',
          }}>
            <span style={{
              width: 24, height: 24, borderRadius: 6, background: 'var(--surface-inset)',
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              color: e.tint,
            }}><Icon size={13} /></span>
            <div style={{ fontSize: 13, color: 'var(--text)' }}>
              <span style={{ fontWeight: 600 }}>{e.who}</span>
              <span style={{ color: 'var(--text-muted)' }}> {e.what} </span>
              <span style={{ fontWeight: 500 }}>{e.target}</span>
            </div>
            <span style={{ fontSize: 11, color: 'var(--text-faint)' }}>{e.when}</span>
          </div>
        );
      })}
    </div>
  );
}

Object.assign(window, { SurfaceHome, OrgGlyph });
