(() => {
const DS = window.LeonardoSousaBJJDesignSystem_2cc6b8;
const { Card, Avatar, BeltBadge, Button, IconButton, Dialog, Select, Input, Tabs, Badge, KpiCard, Icon, Checkbox, SegmentedControl, Alert, EmptyState } = DS;
const A = window.LSAdmin;
const BELT_NAME = { branca: 'Branca', cinza: 'Cinza', amarela: 'Amarela', laranja: 'Laranja', verde: 'Verde', azul: 'Azul', roxa: 'Roxa', marrom: 'Marrom', preta: 'Preta' };
const beltLabel = (b, g, kids) => `Faixa ${BELT_NAME[b]}${kids ? ' e branca' : ''}${g ? ` · ${g}º grau` : ''}`;

const Arrow = ({ p }) => (
  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
    <BeltBadge belt={p.de[0]} stripes={p.de[1]} kidsStripe={p.kids} size="sm" /><Icon name="arrow-right" size={14} color="var(--text-subtle)" /><BeltBadge belt={p.para[0]} stripes={p.para[1]} kidsStripe={p.kids} size="sm" />
  </span>
);

// Certificate artwork — A4 landscape proportions. Original logo only.
function Certificate({ g, scale = 1 }) {
  return (
    <div id="ls-certificate" style={{ width: 842 * scale, height: 595 * scale, background: '#fff', position: 'relative', boxShadow: 'var(--shadow-md)', borderRadius: 4, overflow: 'hidden', fontFamily: 'var(--font-body)', flexShrink: 0 }}>
      <div style={{ position: 'absolute', inset: 18 * scale, border: `${2 * scale}px solid var(--ls-black)` }} />
      <div style={{ position: 'absolute', inset: 26 * scale, border: `${1 * scale}px solid var(--gray-300)` }} />
      <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 10 * scale, background: 'var(--ls-black)' }}><span style={{ position: 'absolute', right: 80 * scale, top: 0, bottom: 0, width: 90 * scale, background: 'var(--brand-primary)' }} /></div>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', padding: `0 ${80 * scale}px`, gap: 10 * scale }}>
        <img src="../../assets/logo.png" alt="Leonardo Sousa BJJ" style={{ height: 96 * scale }} />
        <div style={{ fontSize: 11 * scale, lineHeight: 1.4, whiteSpace: 'nowrap', fontWeight: 600, letterSpacing: '.24em', textTransform: 'uppercase', color: 'var(--text-muted)', marginTop: 6 * scale }}>Certificado de graduação</div>
        <div style={{ fontSize: 14 * scale, lineHeight: 1.4, color: 'var(--text-body)', marginTop: 8 * scale }}>Certificamos que</div>
        <div style={{ fontFamily: 'var(--font-display)', fontSize: 36 * scale, lineHeight: 1.15, fontWeight: 700, color: 'var(--text-strong)', letterSpacing: '-.01em' }}>{g.nome}</div>
        <div style={{ fontSize: 14 * scale, color: 'var(--text-body)', maxWidth: 560 * scale, lineHeight: 1.5 }}>foi avaliado(a) e promovido(a) em Brazilian Jiu-Jitsu para</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 * scale, marginTop: 4 * scale }}>
          <BeltBadge belt={g.para[0]} stripes={g.para[1]} kidsStripe={g.kids} size={scale >= 0.9 ? 'lg' : 'md'} />
          <span style={{ fontFamily: 'var(--font-display)', fontSize: 20 * scale, lineHeight: 1.3, fontWeight: 600, color: 'var(--text-strong)' }}>{beltLabel(g.para[0], g.para[1], g.kids)}</span>
        </div>
        <div style={{ display: 'flex', gap: 80 * scale, marginTop: 30 * scale }}>
          {[[`Prof. ${g.prof || 'Leonardo Sousa'}`, 'Professor avaliador'], [g.data || '10 out 2026', 'Data da graduação']].map(([a, b]) => (
            <div key={b} style={{ width: 200 * scale }}>
              <div style={{ fontSize: 14 * scale, lineHeight: 1.4, fontWeight: 600, color: 'var(--text-strong)', paddingBottom: 6 * scale, borderBottom: `${1 * scale}px solid var(--ls-black)` }}>{a}</div>
              <div style={{ fontSize: 11 * scale, lineHeight: 1.4, color: 'var(--text-muted)', marginTop: 6 * scale }}>{b}</div>
            </div>
          ))}
        </div>
        <div style={{ fontSize: 10 * scale, lineHeight: 1.4, color: 'var(--text-subtle)', marginTop: 14 * scale }}>Leonardo Sousa Brazilian Jiu Jitsu · Nº {g.cert || 'LS-2026-0142'}</div>
      </div>
    </div>
  );
}

function printCertificate() {
  const el = document.getElementById('ls-certificate');
  if (!el) return;
  const w = window.open('', '_blank');
  if (!w) return;
  w.document.write(`<!DOCTYPE html><html><head><base href="${location.href}"><link rel="stylesheet" href="../../styles.css"><style>@page{size:A4 landscape;margin:0}body{margin:0;display:flex;align-items:center;justify-content:center;height:100vh}#ls-certificate{box-shadow:none!important;transform-origin:center}</style></head><body>${el.outerHTML}<script>setTimeout(()=>window.print(),600)<\/script></body></html>`);
  w.document.close();
}

function CertificateDialog({ g, onClose, toast }) {
  return (
    <Dialog open title="Certificado de graduação" description={`${g.nome} · ${beltLabel(g.para[0], g.para[1], g.kids)}`} onClose={onClose} width={720}
      footer={<><Button variant="secondary" onClick={onClose}>Fechar</Button><Button variant="secondary" iconLeft="send" onClick={() => { toast(`Certificado enviado para ${g.nome}`); onClose(); }}>Enviar pelo app</Button><Button iconLeft="download" onClick={printCertificate}>Baixar PDF</Button></>}>
      <div style={{ display: 'flex', justifyContent: 'center', padding: 12, borderRadius: 12, background: 'var(--surface-sunken)', overflow: 'hidden' }}>
        <Certificate g={g} scale={0.74} />
      </div>
    </Dialog>
  );
}

const ADULT = ['branca', 'azul', 'roxa', 'marrom', 'preta'];
const KIDS = ['branca', 'cinza', 'amarela', 'laranja', 'verde'];
const maxG = (b) => (b === 'preta' ? 6 : 4);
const calcPara = (de, mode, n, belt) => (mode === 'grau' ? [de[0], Math.min(maxG(de[0]), de[1] + n)] : [belt, 0]);

// Professor escolhe: dar graus (+1…) ou trocar de faixa.
function PromotionPicker({ de, kids, mode, setMode, n, setN, belt, setBelt }) {
  const room = maxG(de[0]) - de[1];
  const order = kids ? KIDS : ADULT;
  const next = order.slice(order.indexOf(de[0]) + 1);
  const para = calcPara(de, mode, n, belt);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <SegmentedControl fullWidth options={[{ value: 'grau', label: 'Dar graus', icon: 'plus' }, { value: 'faixa', label: 'Nova faixa', icon: 'award' }]} value={mode} onChange={setMode} />
      {mode === 'grau' ? (
        room > 0 ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-strong)' }}>Quantos graus?</span>
            <SegmentedControl fullWidth options={Array.from({ length: room }, (_, i) => ({ value: String(i + 1), label: `+${i + 1} grau${i ? 's' : ''}` }))} value={String(Math.min(n, room))} onChange={(v) => setN(Number(v))} />
          </div>
        ) : <Alert tone="info" title="Graus completos">O aluno já tem todos os graus desta faixa. Escolha "Nova faixa".</Alert>
      ) : (
        next.length ? <Select label="Nova faixa" options={next.map((b) => ({ value: b, label: `Faixa ${b}` }))} value={belt} onChange={setBelt} /> : <Alert tone="info">Faixa máxima do programa.</Alert>
      )}
      <div style={{ padding: 16, borderRadius: 12, background: 'var(--surface-sunken)', display: 'flex', justifyContent: 'center' }}><Arrow p={{ de, para, kids: kids && para[0] !== 'branca' ? 'branca' : undefined }} /></div>
    </div>
  );
}

function usePromo(de, kids, init) {
  const order = kids ? KIDS : ADULT;
  const nextBelt = order[order.indexOf(de[0]) + 1] || de[0];
  const startMode = init && init[0] !== de[0] ? 'faixa' : maxG(de[0]) - de[1] > 0 ? 'grau' : 'faixa';
  const [mode, setMode] = React.useState(startMode);
  const [n, setN] = React.useState(init && init[0] === de[0] ? Math.max(1, init[1] - de[1]) : 1);
  const [belt, setBelt] = React.useState(init && init[0] !== de[0] ? init[0] : nextBelt);
  return { mode, setMode, n, setN, belt, setBelt, para: calcPara(de, mode, n, belt) };
}

function GradDialog({ g, prof, setProf, genCert, setGenCert, notify, setNotify, onClose, onConfirm }) {
  const pr = usePromo(g.de, !!g.kids, g.para);
  return (
    <Dialog open title="Graduar aluno" description={`${g.nome} · avaliação do professor`} onClose={onClose} width={540}
      footer={<><Button variant="secondary" onClick={onClose}>Cancelar</Button><Button iconLeft="award" onClick={() => onConfirm({ ...g, para: pr.para, kids: g.kids && pr.para[0] !== 'branca' ? 'branca' : g.kids })}>{genCert ? 'Graduar e gerar certificado' : 'Confirmar graduação'}</Button></>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <PromotionPicker de={g.de} kids={!!g.kids} {...pr} />
        <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: 12 }}>
          <Select label="Professor avaliador" options={A.instructors.map((i) => i.nome)} value={prof} onChange={setProf} />
          <Input label="Data" type="date" defaultValue="2026-10-10" />
        </div>
        <Input label="Avaliação do professor (opcional)" multiline rows={2} placeholder="Ex.: ótima evolução na passagem de guarda" />
        <Checkbox checked={genCert} onChange={setGenCert} label="Gerar certificado de graduação" description="PDF com a logo da academia, pronto para imprimir ou enviar." />
        <Checkbox checked={notify} onChange={setNotify} label="Avisar aluno pelo app" description={g.kids ? 'O responsável também será notificado.' : undefined} />
      </div>
    </Dialog>
  );
}

function IndicateDialog({ taken, onClose, onSave }) {
  const opts = A.students.filter((s) => !taken.includes(s.nome));
  const [sid, setSid] = React.useState(opts[0] ? String(opts[0].id) : '');
  const [prof, setProf] = React.useState('Leonardo Sousa');
  const [cer, setCer] = React.useState('atual');
  const s = opts.find((x) => String(x.id) === sid);
  if (!s) return <Dialog open title="Indicar aluno" onClose={onClose}><EmptyState compact title="Todos os alunos já estão indicados" /></Dialog>;
  return <IndicateInner key={sid} s={s} opts={opts} sid={sid} setSid={setSid} prof={prof} setProf={setProf} cer={cer} setCer={setCer} onClose={onClose} onSave={onSave} />;
}
function IndicateInner({ s, opts, sid, setSid, prof, setProf, cer, setCer, onClose, onSave }) {
  const kids = s.turma.startsWith('Kids');
  const de = [s.faixa, s.g];
  const pr = usePromo(de, kids);
  return (
    <Dialog open title="Indicar aluno para graduação" description="O aluno entra na lista da cerimônia escolhida." onClose={onClose} width={560}
      footer={<><Button variant="secondary" onClick={onClose}>Cancelar</Button><Button iconLeft="user-check" onClick={() => onSave({ id: 'pr' + Date.now(), nome: s.nome, de, para: pr.para, kids: kids && pr.para[0] !== 'branca' ? 'branca' : s.kids, indicado: prof, cer })}>Indicar</Button></>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr)', gap: 12 }}>
          <Select label="Aluno" options={opts.map((o) => ({ value: String(o.id), label: `${o.nome} · ${A.dojoName(o.dojo)}` }))} value={sid} onChange={setSid} style={{ gridColumn: 'span 2' }} />
          <Select label="Professor que indica" options={A.instructors.map((i) => i.nome)} value={prof} onChange={setProf} />
          <Select label="Cerimônia" options={A.ceremonies.map((c) => ({ value: c.id, label: c.label }))} value={cer} onChange={setCer} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 13, color: 'var(--text-muted)' }}>Faixa atual <BeltBadge belt={s.faixa} stripes={s.g} kidsStripe={s.kids} size="sm" showLabel /></div>
        <PromotionPicker de={de} kids={kids} {...pr} />
        <Input label="Motivo da indicação (opcional)" multiline rows={2} placeholder="Ex.: domínio da guarda fechada e boa postura no rola" />
      </div>
    </Dialog>
  );
}

function GraduationsPage({ toast }) {
  const [tab, setTab] = React.useState('indicados');
  const [list, setList] = React.useState(A.promotions);
  const [grad, setGrad] = React.useState(null);
  const [cert, setCert] = React.useState(null);
  const [done, setDone] = React.useState([]);
  const [ind, setInd] = React.useState(false);
  const [rm, setRm] = React.useState(null);
  const [notify, setNotify] = React.useState(true);
  const [genCert, setGenCert] = React.useState(true);
  const [prof, setProf] = React.useState('Leonardo Sousa');
  const sync = (l) => { A.promotions = l; setList(l); };
  const move = (p, cer) => { sync(list.map((x) => (x.id === p.id ? { ...x, cer } : x))); toast(cer === 'prox' ? `${p.nome} adiado para a cerimônia de 12/12` : `${p.nome} voltou para a cerimônia de 10/10`); };
  const remove = () => { sync(list.filter((x) => x.id !== rm.id)); toast(`${rm.nome} retirado dos indicados`); setRm(null); };
  const confirm = (g) => {
    const h = { ...g, data: '10 out 2026', prof, novo: true };
    setDone((d) => [h, ...d]); sync(list.filter((x) => x.id !== g.id)); setGrad(null);
    toast(`${g.nome} graduado`);
    if (genCert) setCert(h);
  };
  const hist = [...done, ...A.gradHistory];
  const Row = ({ p, i, n }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '14px 0', borderBottom: i < n - 1 ? '1px solid var(--border-subtle)' : 0, flexWrap: 'wrap' }}>
      <Avatar name={p.nome} size={40} />
      <div style={{ width: 170 }}><div style={{ fontWeight: 600, color: 'var(--text-strong)' }}>{p.nome}</div><div style={{ fontSize: 12, color: 'var(--text-muted)' }}>Indicado por Prof. {p.indicado}</div></div>
      <Arrow p={p} />
      <div style={{ flex: 1 }} />
      <div style={{ display: 'flex', gap: 8, marginLeft: 'auto', alignItems: 'center' }}>
        {p.cer === 'atual' ? <Button variant="secondary" size="sm" iconLeft="calendar-clock" onClick={() => move(p, 'prox')}>Adiar para 12/12</Button> : <Button variant="secondary" size="sm" iconLeft="undo-2" onClick={() => move(p, 'atual')}>Trazer para 10/10</Button>}
        <IconButton icon="user-x" label="Tirar dos indicados" variant="outline" size="sm" onClick={() => setRm(p)} />
        <Button size="sm" iconLeft="award" onClick={() => setGrad(p)}>Graduar</Button>
      </div>
    </div>
  );
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <Grid cols="repeat(auto-fit, minmax(170px, 1fr))">
        <KpiCard label="Indicados para 10/10" value={list.filter((p) => p.cer === 'atual').length} icon="award" variant="dark" />
        <KpiCard label="Adiados para 12/12" value={list.filter((p) => p.cer === 'prox').length} icon="calendar-clock" />
        <KpiCard label="Graduações em 2026" value={38 + done.length} icon="trending-up" delta="+9" trend="up" hint="vs. 2025" />
        <KpiCard label="Certificados emitidos" value={36 + done.length} icon="file-badge" hint="em 2026" />
      </Grid>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 12 }}>
        <Tabs items={[{ value: 'indicados', label: 'Indicados', count: list.length }, { value: 'hist', label: 'Histórico e certificados' }]} value={tab} onChange={setTab} style={{ flex: 1 }} />
        <Button iconLeft="user-plus" onClick={() => setInd(true)} style={{ marginBottom: 8 }}>Indicar aluno</Button>
      </div>
      {tab === 'indicados' ? (
        A.ceremonies.map((c) => {
          const items = list.filter((p) => p.cer === c.id);
          return (
            <Card key={c.id} title={c.label} subtitle={c.id === 'atual' ? 'Sábado, após o seminário' : 'Próxima cerimônia'} padding="18px 20px 4px" action={<Badge tone={c.id === 'atual' ? 'brand' : 'neutral'}>{items.length} aluno{items.length === 1 ? '' : 's'}</Badge>}>
              {items.length === 0 ? <div style={{ padding: '8px 0 18px', fontSize: 13, color: 'var(--text-muted)' }}>{c.id === 'atual' ? 'Nenhum aluno indicado. Use "Indicar aluno".' : 'Nenhum aluno adiado.'}</div> : items.map((p, i) => <Row key={p.id} p={p} i={i} n={items.length} />)}
            </Card>
          );
        })
      ) : (
        <Card padding="4px 20px">
          {hist.map((h, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '12px 0', borderBottom: i < hist.length - 1 ? '1px solid var(--border-subtle)' : 0, flexWrap: 'wrap' }}>
              <Avatar name={h.nome} size={36} />
              <div style={{ width: 170, fontWeight: 600, color: 'var(--text-strong)' }}>{h.nome}{h.novo ? <Badge size="sm" tone="success" style={{ marginLeft: 8 }}>Novo</Badge> : null}</div>
              <Arrow p={h} />
              <div style={{ flex: 1 }} />
              <span style={{ fontSize: 13, color: 'var(--text-muted)' }}>Prof. {h.prof}</span>
              <span style={{ width: 96, textAlign: 'right', fontSize: 13, fontWeight: 600, color: 'var(--text-strong)' }}>{h.data}</span>
              <Button size="sm" variant="ghost" iconLeft="file-badge" onClick={() => setCert(h)}>Certificado</Button>
            </div>
          ))}
        </Card>
      )}
      {grad ? <GradDialog g={grad} prof={prof} setProf={setProf} genCert={genCert} setGenCert={setGenCert} notify={notify} setNotify={setNotify} onClose={() => setGrad(null)} onConfirm={confirm} /> : null}
      {ind ? <IndicateDialog taken={list.map((p) => p.nome)} onClose={() => setInd(false)} onSave={(p) => { sync([...list, p]); setInd(false); setTab('indicados'); toast(`${p.nome} indicado para ${p.cer === 'atual' ? '10/10' : '12/12'}`); }} /> : null}
      {rm ? (
        <Dialog open title="Tirar dos indicados?" description={`${rm.nome} sai da lista de graduação. Você pode indicá-lo de novo depois.`} onClose={() => setRm(null)} width={440}
          footer={<><Button variant="secondary" onClick={() => setRm(null)}>Cancelar</Button><Button iconLeft="user-x" onClick={remove}>Tirar dos indicados</Button></>} />
      ) : null}
      {cert ? <CertificateDialog g={cert} onClose={() => setCert(null)} toast={toast} /> : null}
    </div>
  );
}

Object.assign(window, { GraduationsPage, Certificate, CertificateDialog });
})();
