/* P24 · Capstone · Análisis multi-TF + report editor (60/40 split) */

function P24_Capstone(props = {}) {
  const ticker = props.ticker || 'AAPL';
  const tickerName = props.tickerName || 'Apple Inc.';

  // Series
  const monthlyBars = React.useMemo(() => window.synthetic.makeSeries({ seed: 21, n: 200, drift: 0.0024, vol: 0.018, cycles: 1.5, regime: 'uptrend' }), []);
  const weeklyBars = React.useMemo(() => window.synthetic.makeSeries({ seed: 31, n: 156, drift: 0.0015, vol: 0.014, cycles: 2.5, regime: 'uptrend', start: 130 }), []);
  const dailyBars = React.useMemo(() => window.synthetic.makeSeries({ seed: 41, n: 220, drift: 0.0008, vol: 0.011, cycles: 4, regime: 'uptrend', start: 170 }), []);

  const sections = [
    { id: 'primary', label: 'Tendencia primaria identificada', tf: 'monthly', words: 84, target: 100 },
    { id: 'secondary', label: 'Tendencia secundaria', tf: 'weekly', words: 71, target: 100 },
    { id: 'current', label: 'Estructura actual y oportunidad', tf: 'daily', words: 58, target: 100 },
    { id: 'levels', label: 'Niveles S/R y zonas de retroceso medidas', tf: null, words: 42, target: 100 },
    { id: 'scenarios', label: 'Escenarios probabilísticos y anti-tesis', tf: null, words: 95, target: 100 },
  ];

  const [activeSection, setActiveSection] = React.useState('current');
  const [text, setText] = React.useState({
    primary: 'Tendencia primaria alcista desde el origen de la serie. Estructura HH/HL preservada con ChoCh en barra 110 y BoS en 130. La trendline ascendente principal acumula 5 toques. Históricamente, en este régimen el ~70% de los retrocesos al 50% Dow han sido seguidos por continuación.',
    secondary: 'En weekly, la corrección reciente se ancla en el 50% del impulso anterior. Aparece una trendline secundaria con 4 toques, paralela a la primaria, dentro del canal del monthly.',
    current: 'En daily, el precio se aproxima a la zona de soporte secundario. Volumen decreciente sugiere agotamiento del retroceso, no impulso bajista institucional. Es probable que el rebote tienda al 38.2 del impulso previo.',
    levels: 'Soporte primario weekly: 112.4-114.0 (zona, no línea). Resistencia próxima: 122.0. Retrocesos Dow 33/50/66 marcados.',
    scenarios: 'Escenario base (60%): rebote a 122 y prueba de la resistencia. Escenario alternativo (30%): ruptura del soporte 112 y vuelta a la trendline primaria del weekly. Anti-tesis: si rompe 109 con volumen, la tendencia secundaria estaría inválida y debería esperar a re-anchor.',
  });

  // Linter de lenguaje categórico (R21)
  const flaggedWords = ['va a', 'siempre', 'nunca', 'garantizado', 'seguro', 'obvio', 'imposible que'];
  const lintIssues = React.useMemo(() => {
    const out = {};
    for (const k in text) {
      const issues = [];
      for (const w of flaggedWords) {
        const re = new RegExp('\\b' + w + '\\b', 'gi');
        let m;
        while ((m = re.exec(text[k]))) {
          issues.push({ word: w, at: m.index });
        }
      }
      if (issues.length) out[k] = issues;
    }
    return out;
  }, [text]);

  // Word count total
  const totalWords = Object.values(text).reduce((s, t) => s + wordCount(t), 0);

  function wordCount(s) {
    return s.trim().split(/\s+/).filter(Boolean).length;
  }

  return (
    <div className="shell-main" style={{ height: '100%' }}>
      <div className="lab-header">
        <div>
          <div className="lab-header-id">CAPSTONE · ANÁLISIS COMPLETO MULTI-TF</div>
          <div className="lab-header-title">{tickerName} · {ticker} — Informe técnico de 500 palabras estructurado en 5 secciones.</div>
        </div>
        <div className="lab-header-counter">
          <div className="counter-pill"><span className="label">Palabras</span>{totalWords}<span style={{ color: 'var(--text-muted)' }}>/500</span></div>
          <div className="counter-pill"><span className="label">Linter</span>
            <span style={{ color: Object.keys(lintIssues).length === 0 ? 'var(--signal-pass)' : 'var(--signal-warning)', marginLeft: 4 }}>
              {Object.keys(lintIssues).length === 0 ? '✓ limpio' : `⚠ ${Object.values(lintIssues).flat().length} categóricos`}
            </span>
          </div>
          <button className={`btn ${totalWords >= 500 && Object.keys(lintIssues).length === 0 ? 'btn-pass' : ''}`} disabled={totalWords < 350}>
            Continuar a grabación
          </button>
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '60% 40%', minHeight: 0, flex: 1, overflow: 'hidden' }}>
        {/* Izquierda: Multi-TF mini-view */}
        <div style={{ padding: 12, display: 'flex', flexDirection: 'column', gap: 6, background: 'var(--surface-0)', borderRight: '1px solid var(--border-subtle)', overflow: 'auto' }}>
          <CapstoneTFChart bars={monthlyBars} tf="monthly" tfLabel="Monthly · Primaria" ticker={ticker}
            drawings={drawingsForTF('monthly', monthlyBars)} markers={[{ index: 110, kind: 'choch', price: monthlyBars[110].h }, { index: 130, kind: 'bos', price: monthlyBars[130].l }]}
            active={activeSection === 'primary'} />
          <CapstoneTFChart bars={weeklyBars} tf="weekly" tfLabel="Weekly · Secundaria" ticker={ticker}
            drawings={drawingsForTF('weekly', weeklyBars)} markers={[]} active={activeSection === 'secondary'} />
          <CapstoneTFChart bars={dailyBars} tf="daily" tfLabel="Daily · Entrada" ticker={ticker}
            drawings={drawingsForTF('daily', dailyBars)} markers={[]} active={activeSection === 'current'} />
          <button className="btn" style={{ alignSelf: 'flex-start', marginTop: 4, fontSize: 11 }}>
            ↗ Capturar drawings actuales para informe
          </button>
        </div>

        {/* Derecha: report editor */}
        <div style={{ display: 'flex', flexDirection: 'column', minHeight: 0, background: 'var(--surface-1)' }}>
          {/* Tabs / secciones */}
          <div style={{ display: 'flex', flexDirection: 'column', overflow: 'auto', flex: 1 }}>
            {sections.map((s, i) => {
              const wc = wordCount(text[s.id]);
              const sectionIssues = lintIssues[s.id] || [];
              const isActive = activeSection === s.id;
              return (
                <div key={s.id} style={{ borderBottom: '1px solid var(--border-subtle)' }}>
                  <button onClick={() => setActiveSection(s.id)} style={{
                    width: '100%', padding: '10px 14px',
                    background: isActive ? 'var(--surface-2)' : 'transparent',
                    border: 'none', borderLeft: `3px solid ${isActive ? (s.tf === 'monthly' ? '#C6A1FF' : s.tf === 'weekly' ? '#6BA3FF' : s.tf === 'daily' ? '#F0B86E' : 'var(--text-primary)') : 'transparent'}`,
                    textAlign: 'left', color: 'var(--text-primary)', cursor: 'pointer',
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                    fontFamily: 'inherit',
                  }}>
                    <div>
                      <div style={{ fontSize: 10, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 2 }}>{i + 1} · {s.tf || 'COMBINADO'}</div>
                      <div style={{ fontSize: 13, fontWeight: 600 }}>{s.label}</div>
                    </div>
                    <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
                      {sectionIssues.length > 0 && <span className="chip chip-warn">⚠ {sectionIssues.length}</span>}
                      <span className="chip chip-mono">{wc}/{s.target}</span>
                    </div>
                  </button>
                  {isActive && (
                    <div style={{ padding: '8px 14px 14px' }}>
                      <textarea
                        value={text[s.id]}
                        onChange={(e) => setText({ ...text, [s.id]: e.target.value })}
                        style={{
                          width: '100%', minHeight: 110,
                          background: 'var(--surface-0)', border: '1px solid var(--border-default)',
                          borderRadius: 'var(--radius-sm)', padding: '10px 12px',
                          color: 'var(--text-primary)', fontFamily: 'inherit', fontSize: 13, lineHeight: 1.55, resize: 'vertical',
                        }}
                      />
                      {sectionIssues.length > 0 && (
                        <div style={{ marginTop: 8, padding: 8, background: 'var(--signal-warning-soft)', borderRadius: 'var(--radius-sm)', fontSize: 11, color: 'var(--signal-warning)' }}>
                          ⚠ Lenguaje categórico detectado: {sectionIssues.map(i => `"${i.word}"`).join(', ')}.{' '}
                          Sugerencia: "es probable que", "tiende a", "históricamente ~70% de las veces".
                        </div>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      </div>

      <div className="lab-footer">
        <FeedbackBanner
          kind="neutral"
          message="Lenguaje probabilístico activo. Linter rechaza modalidad categórica. Tras envío: peer review (2 compañeros) + signoff de tutor."
        />
      </div>
    </div>
  );

  function drawingsForTF(tf, b) {
    const piv = window.synthetic.findPivots(b, tf === 'monthly' ? 8 : 6);
    const lows = piv.filter(p => p.kind === 'low');
    if (lows.length < 2) return [];
    return [{
      type: 'trendline',
      points: [{ x: lows[Math.floor(lows.length / 2)].index, y: lows[Math.floor(lows.length / 2)].price }, { x: lows[lows.length - 1].index, y: lows[lows.length - 1].price }],
      touches: tf === 'monthly' ? 5 : 4, state: 'valid',
    }];
  }
}

function CapstoneTFChart({ bars, tf, tfLabel, ticker, drawings, markers, active }) {
  const tfColor = tf === 'monthly' ? '#C6A1FF' : tf === 'weekly' ? '#6BA3FF' : '#F0B86E';
  return (
    <div style={{ position: 'relative', height: 196, borderRadius: 'var(--radius-sm)', overflow: 'hidden', outline: active ? `2px solid ${tfColor}` : 'none' }}>
      <ChartCanvas
        bars={bars}
        width={760}
        height={196}
        ticker={ticker}
        tfBadge={tf}
        drawings={drawings}
        markers={markers}
        anonymized={false}
        showVolume
        volumeRatio={0.18}
        padding={{ top: 14, right: 56, bottom: 22, left: 12 }}
      />
      <div style={{
        position: 'absolute', top: 6, left: 12,
        fontSize: 11, fontFamily: 'var(--font-sans)', fontWeight: 600, letterSpacing: '0.05em',
        color: tfColor, textTransform: 'uppercase',
      }}>{tfLabel}</div>
    </div>
  );
}

window.P24_Capstone = P24_Capstone;
