const GNG_W = { valor: 15, distancia: 10, margem: 20, maoObra: 15, docs: 15, equip: 10, exp: 15 };
const GNG_EQ = { proprio: ['Próprios', 1], locacao: ['Locação', 0.6], nenhum: ['Indisponível', 0] };
const GNG_EX = { similar: ['Atestado similar', 1], parcial: ['Parcial', 0.5], nenhuma: ['Nenhuma', 0] };
const GNG_PRESETS = [
  { id: 'cps', label: 'Concorrência 012/2026 — Campinas', v: { valor: 3.5, distancia: 95, margem: 14, maoObra: 76, docs: 8, equip: 'proprio', exp: 'similar' } },
  { id: 'rp', label: 'Pregão 045/2026 — Ribeirão Preto', v: { valor: 1.2, distancia: 320, margem: 12, maoObra: 55, docs: 9, equip: 'locacao', exp: 'parcial' } },
  { id: 'bau', label: 'Concorrência 031/2026 — Bauru', v: { valor: 9.8, distancia: 350, margem: 8, maoObra: 30, docs: 6, equip: 'nenhum', exp: 'nenhuma' } },
];
const GNG_CLS = {
  g: { label: 'Verde · Participar', tone: 'success', border: 'rgba(52,211,153,0.4)', text: 'Critérios favoráveis. Siga para a proposta.' },
  y: { label: 'Amarelo · Avaliar', tone: 'warning', border: 'rgba(251,191,36,0.4)', text: 'Há pontos fracos. Discuta com a diretoria antes de seguir.' },
  r: { label: 'Vermelho · Não participar', tone: 'danger', border: 'rgba(248,113,113,0.4)', text: 'Risco alto ou inviável com os recursos atuais.' },
};
function gngCompute(v) {
  const n = { valor: v.valor < 0.3 ? 0.4 : v.valor <= 6 ? 1 : Math.max(0.3, 1 - (v.valor - 6) / 12), distancia: Math.max(0, 1 - v.distancia / 600), margem: Math.min(1, v.margem / 25), maoObra: Math.min(1, v.maoObra / 80), docs: v.docs / 9, equip: GNG_EQ[v.equip][1], exp: GNG_EX[v.exp][1] };
  const pts = Object.fromEntries(Object.keys(GNG_W).map(k => [k, n[k] * GNG_W[k]]));
  let score = Math.round(Object.values(pts).reduce((a, b) => a + b, 0));
  const alerts = [];
  if (v.docs < 7) { score = Math.min(score, 39); alerts.push('Bloqueio: menos de 7 dos 9 documentos válidos. Score limitado a 39.'); }
  if (v.margem < 5) { score = Math.min(score, 44); alerts.push('Bloqueio: margem abaixo de 5%. Score limitado a 44.'); }
  return { pts, score, alerts, inputs: { ...v } };
}
function GoNoGoScreen({ params = {} }) {
  const { PageHeader, Card, Slider, SegmentedControl, Gauge, Badge, Button, ProgressBar, Table, Toast, Alert } = window.VRticeDesignSystem_d763eb;
  const [preset, setPreset] = React.useState('cps');
  const [v, setV] = React.useState({ ...GNG_PRESETS[0].v });
  const [toast, setToast] = React.useState('');
  const [pipeline, setPipeline] = React.useState(null), [pipelineLoading, setPipelineLoading] = React.useState(false), [decisionId, setDecisionId] = React.useState(null);
  // Histórico desta sessão (o histórico gravado fica em opportunity_assessments); nada fictício.
  const [hist, setHist] = React.useState([]);
  const set = (k, x) => setV(s => ({ ...s, [k]: x }));
  React.useEffect(() => { let alive = true; if (!params.id || !window.VxOpportunityRuntime) return; setPipelineLoading(true); window.VxOpportunityRuntime.loadAssessment(params.id).then(r => { if (!alive) return; setPipeline(r.error ? { error:r.error } : r.data); setDecisionId(r.data?.assessment?.id || null); setPipelineLoading(false); }).catch(e => { if (alive) { setPipeline({ error:e.message || 'Falha ao carregar oportunidade.' }); setPipelineLoading(false); } }); return () => { alive = false; }; }, [params.id]);
  const { pts, score, alerts } = gngCompute(v);
  const clsOf = s => (s >= 70 ? 'g' : s >= 45 ? 'y' : 'r');
  const c = GNG_CLS[clsOf(score)];
  const P = k => pts[k].toFixed(1).replace('.', ',') + ' / ' + GNG_W[k];
  const brl = n => 'R$ ' + n.toFixed(1).replace('.', ',') + ' mi';
  const LBL = { valor: 'Valor', distancia: 'Distância', margem: 'Margem', maoObra: 'Mão de obra', docs: 'Documentos', equip: 'Equipamentos', exp: 'Experiência' };
  const lot = GNG_PRESETS.find(p => p.id === preset);
  return (
    <BlockGrid.Auto id="go-no-go">
      {pipelineLoading && <Card variant="flat" padding={16}><span style={{color:'var(--text-muted)',fontSize:13}}>Carregando oportunidade, capacidade e avaliação…</span></Card>}
      {pipeline?.error && <Card variant="flat" padding={16}><span style={{color:'var(--status-danger)',fontSize:13}}>{pipeline.error}</span></Card>}
      {pipeline?.bid && <Card variant="analysis" padding={20} gap={12}><div style={{display:'flex',justifyContent:'space-between',gap:16,alignItems:'center',flexWrap:'wrap'}}><div><span style={{fontSize:11,letterSpacing:'0.14em',color:'var(--text-muted)'}}>OPORTUNIDADE PNCP</span><div style={{fontSize:18,fontWeight:600,marginTop:4}}>{pipeline.bid.title}</div><div style={{fontSize:13,color:'var(--text-secondary)',marginTop:4}}>{pipeline.bid.licitacao?.id_contratacao_pncp || pipeline.bid.licitacao?.id_compra || 'PNCP sem chave'}</div></div>{pipeline.match && <Badge tone={pipeline.match.decision==='MATCH_FORTE'?'success':pipeline.match.decision==='NO_MATCH'?'danger':'warning'}>{pipeline.match.decision} · {pipeline.match.score}</Badge>}</div><div style={{fontSize:13,color:'var(--text-secondary)'}}>Capability: <strong>{pipeline.capability?.name || 'nenhuma selecionada'}</strong>{pipeline.match?.blockers?.length ? ' · Bloqueios: '+pipeline.match.blockers.join(', ') : ''}</div></Card>}
      <PageHeader eyebrow="Score Go/No-Go" title="Vale a pena participar?" description="Ajuste os sete critérios. Cada um vale até o seu peso; a soma dá o score de 0 a 100 e a recomendação." actions={
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>{GNG_PRESETS.map(p => { const on = p.id === preset; return <button key={p.id} onClick={() => { setPreset(p.id); setV({ ...p.v }); }} style={{ cursor: 'pointer', fontFamily: 'inherit', fontSize: 13, padding: '9px 14px', borderRadius: 999, color: on ? 'var(--text-primary)' : 'var(--text-secondary)', background: on ? 'rgba(37,99,235,0.18)' : 'transparent', border: '1px solid ' + (on ? 'rgba(59,130,246,0.5)' : 'var(--overlay-10)') }}>{p.label}</button>; })}</div>} />
      {params.id ? <Alert tone="warning" title="Ajuste os critérios antes de registrar">Os controles começam com os valores do exemplo selecionado. Informe os dados reais desta oportunidade; a decisão registrada usa exatamente o que estiver aqui.</Alert> : <Alert tone="info" title="Simulação">Sem uma oportunidade aberta, a análise não é gravada. Para registrar, abra a oportunidade em Oportunidades.</Alert>}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 24, alignItems: 'flex-start' }}>
        <Card variant="analysis" padding={32} gap={28} style={{ flex: '999 1 520px' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}><span style={{ fontSize: 12, letterSpacing: '0.16em', color: 'var(--text-muted)' }}>ENTRADAS</span><span style={{ fontSize: 20, fontWeight: 600, letterSpacing: '-0.01em' }}>{lot ? lot.label : 'Análise manual'}</span></div>
          <Slider label="Valor estimado" valueLabel={brl(v.valor)} hint="Faixa ideal: R$ 0,3 mi a R$ 6 mi" points={P('valor')} min={0.1} max={15} step={0.1} value={v.valor} onChange={x => set('valor', x)} />
          <Slider label="Distância da base" valueLabel={v.distancia + ' km'} hint="Perde pontos até zerar em 600 km" points={P('distancia')} min={0} max={800} step={5} value={v.distancia} onChange={x => set('distancia', x)} />
          <Slider label="Margem estimada" valueLabel={v.margem + '%'} hint="25% ou mais vale a nota cheia" points={P('margem')} min={0} max={40} value={v.margem} onChange={x => set('margem', x)} />
          <Slider label="Mão de obra disponível" valueLabel={v.maoObra + '%'} hint="80% ou mais vale a nota cheia" points={P('maoObra')} min={0} max={100} value={v.maoObra} onChange={x => set('maoObra', x)} />
          <Slider label="Documentos válidos" valueLabel={v.docs + ' / 9'} hint="Menos de 7 bloqueia a participação" points={P('docs')} min={0} max={9} value={v.docs} onChange={x => set('docs', x)} />
          {[['equip', 'Equipamentos', GNG_EQ], ['exp', 'Experiência comprovada', GNG_EX]].map(([k, l, map]) => (
            <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}><span style={{ fontSize: 15, fontWeight: 600 }}>{l}</span><span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text-muted)' }}>{P(k)}</span></div>
              <SegmentedControl variant="fill" value={v[k]} onChange={x => set(k, x)} options={Object.entries(map).map(([id, [lb]]) => ({ value: id, label: lb }))} />
            </div>
          ))}
        </Card>
        <div style={{ flex: '1 1 360px', minWidth: 0, display: 'flex', flexDirection: 'column', gap: 24, position: 'sticky', top: 24 }}>
          <Card variant="analysis" padding={28} gap={16} style={{ alignItems: 'center', borderColor: c.border }}>
            <span style={{ alignSelf: 'flex-start', fontSize: 12, letterSpacing: '0.16em', color: 'var(--text-muted)' }}>RESULTADO</span>
            <Gauge value={score} />
            <Badge variant="result" tone={c.tone}>{c.label}</Badge>
            <span style={{ fontSize: 14, color: 'var(--text-secondary)', textAlign: 'center', maxWidth: '36ch' }}>{c.text}</span>
            {alerts.map(a => <span key={a} style={{ alignSelf: 'stretch', fontSize: 13, lineHeight: 1.5, color: '#fecaca', background: 'rgba(248,113,113,0.1)', border: '1px solid rgba(248,113,113,0.3)', borderRadius: 12, padding: '10px 14px' }}>{a}</span>)}
            <Button block onClick={async () => { if (pipeline?.bid?.id && pipeline?.capability?.id && window.VxOpportunityRuntime) { const saved = await window.VxOpportunityRuntime.saveDecision({ bidId: pipeline.bid.id, capabilityId: pipeline.capability.id, matchResult: pipeline.match, goNoGo: { score, decision: score >= 70 ? 'PARTICIPAR' : score >= 45 ? 'AVALIAR' : 'NAO_PARTICIPAR', alerts, inputs: v } }); if (saved.error) { setToast(saved.error); return; } setDecisionId(saved.data?.id || null); if (saved.data?.id) { const final = score >= 70 ? 'PARTICIPAR' : score >= 45 ? 'AVALIAR' : 'NAO_PARTICIPAR'; const committed = await window.VxOpportunityRuntime.finalizeDecision(saved.data.id, final); if (committed.error) { setToast(committed.error); return; } } } const persisted = !!(pipeline?.bid?.id && pipeline?.capability?.id); setHist(h => [{ date: new Date().toLocaleDateString('pt-BR'), lot: (pipeline?.bid?.title || (lot ? lot.label : 'Análise manual')) + (persisted ? '' : ' (simulação)'), score, who: (window.VXData.user || {}).name || '—' }, ...h]); setToast(persisted ? 'Decisão gravada na oportunidade' : 'Simulação: nada foi gravado. Abra uma oportunidade para registrar a decisão.'); setTimeout(() => setToast(''), 2400); }}>Registrar decisão</Button>
          </Card>
          <Card variant="flat" radius="lg" padding={28} gap={16}>
            <span style={{ fontSize: 12, letterSpacing: '0.16em', color: 'var(--text-muted)' }}>COMPOSIÇÃO DO SCORE</span>
            {Object.keys(GNG_W).map(k => (
              <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}><span style={{ color: 'var(--text-secondary)' }}>{LBL[k]}</span><span style={{ fontFamily: 'var(--font-mono)' }}>{P(k)}</span></div>
                <ProgressBar value={pts[k] / GNG_W[k] * 100} height={6} />
              </div>
            ))}
          </Card>
        </div>
      </div>
      <Card variant="flat" radius="lg" gap={16}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}><span style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.01em' }}>Histórico de decisões</span><span style={{ fontSize: 13, color: 'var(--text-muted)' }}>{hist.length} decisões</span></div>
        <Table cellX={0} rowY={14} columns={[
          { key: 'date', label: 'Data', width: '110px', mono: true }, { key: 'lot', label: 'Licitação', width: 'minmax(220px,1fr)' },
          { key: 'score', label: 'Score', width: '80px', render: r => <span style={{ fontFamily: 'var(--font-mono)' }}>{r.score}</span> },
          { key: 'd', label: 'Decisão', width: '150px', render: r => { const k = GNG_CLS[clsOf(r.score)]; return <Badge tone={k.tone}>{k.label.split(' · ')[1]}</Badge>; } },
          { key: 'who', label: 'Responsável', width: '120px', muted: true },
        ]} rows={hist} />
      </Card>
      {toast && <Toast>{toast}</Toast>}
    </BlockGrid.Auto>
  );
}
window.GoNoGoScreen = GoNoGoScreen;
