// Strategy create + edit modal — overlays the detail (or list) view with a
// dimmed backdrop, matches the ProfileModal pattern from components.jsx.
//
// Used in two ways:
//   - List view "+ New strategy" button → modal opens empty
//   - Detail view "Edit" button → modal opens pre-filled with current values

window.StrategyEditModal = function StrategyEditModal({ existing, onClose, onSaved }) {
  const { useState } = React;
  const isEdit = !!existing;
  const [form, setForm] = useState(() => ({
    name: existing?.name || '',
    description: existing?.description || '',
    mode: existing?.mode || 'filter',
    ticker_list: (existing?.ticker_list || []).join(', '),  // textarea convenience
    fmp_filters: existing?.fmp_filters || { marketCapMoreThan: 500000000 },
    custom_filters: existing?.custom_filters || {},
    rerun_price_pct: (existing?.rerun_price_pct ?? 0.20),
    rerun_days: existing?.rerun_days ?? 120,
    schedule_cron: existing?.schedule_cron || '0 6 * * 1-5',
    max_analyses_per_screen: existing?.max_analyses_per_screen ?? 5,
  }));
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(null);

  const setField = (k) => (v) => setForm(f => ({ ...f, [k]: v }));
  const setNum = (k, parser = parseFloat) => (e) => setField(k)(parser(e.target.value));

  const onSubmit = async (e) => {
    e.preventDefault();
    setBusy(true); setError(null);
    try {
      const tickers = (form.ticker_list || '')
        .split(/[,\n]/).map(t => t.trim()).filter(Boolean);
      const body = {
        name: form.name,
        description: form.description || null,
        mode: form.mode,
        ticker_list: form.mode === 'watchlist' ? tickers : [],
        fmp_filters: form.mode === 'filter' ? form.fmp_filters : {},
        custom_filters: form.mode === 'filter' ? form.custom_filters : {},
        rerun_price_pct: Number(form.rerun_price_pct),
        rerun_days: Number(form.rerun_days),
        schedule_cron: form.schedule_cron,
        max_analyses_per_screen: Number(form.max_analyses_per_screen),
      };
      const saved = isEdit
        ? await window.EQ_API.updateStrategy(existing.id, body)
        : await window.EQ_API.createStrategy(body);
      onSaved(saved);
    } catch (err) {
      setError(err.message || 'Save failed');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div onClick={(e) => { if (e.target === e.currentTarget) onClose(); }} style={{
      position: 'fixed', inset: 0, zIndex: 60,
      background: 'rgba(10,22,40,0.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <form onSubmit={onSubmit} style={{
        width: 640, maxWidth: '92vw', maxHeight: '90vh',
        background: 'var(--paper)', borderRadius: 14,
        border: '1px solid var(--ink-150)', boxShadow: '0 24px 60px rgba(10,22,40,0.22)',
        display: 'flex', flexDirection: 'column',
      }}>
        <ModalHead title={isEdit ? 'Edit strategy' : 'New strategy'} onClose={onClose}/>

        <div style={{ padding: '18px 22px', overflowY: 'auto', flex: 1, display: 'flex', flexDirection: 'column', gap: 16 }}>
          {error && <window.ErrorBanner error={{ message: error }}/>}

          <FormSection title="Identity">
            <Field label="Name"><input required value={form.name} onChange={e => setField('name')(e.target.value)} style={inputStyle}/></Field>
            <Field label="Description"><textarea rows={2} value={form.description} onChange={e => setField('description')(e.target.value)} style={{ ...inputStyle, resize: 'vertical' }}/></Field>
          </FormSection>

          <FormSection title="Selection mode">
            <div style={{ display: 'flex', gap: 8 }}>
              <ModeRadio selected={form.mode === 'filter'} onClick={() => setField('mode')('filter')}
                label="Filter mode" desc="FMP screener with market-cap + technical filters. Universe varies each run."/>
              <ModeRadio selected={form.mode === 'watchlist'} onClick={() => setField('mode')('watchlist')}
                label="Watchlist mode" desc="Fixed ticker list (≤20). Same names every run."/>
            </div>
          </FormSection>

          {form.mode === 'filter' ? (
            <FormSection title="Filter criteria — all optional, blank = ignore">
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, alignItems: 'end' }}>
                <FilterNumField label="Min market cap (USD)" obj={form.fmp_filters} k="marketCapMoreThan" set={setField('fmp_filters')} step="1000000"/>
                <FilterNumField label="Max market cap (USD)" obj={form.fmp_filters} k="marketCapLowerThan" set={setField('fmp_filters')} step="1000000"/>
                <TextField label="Sector (exact FMP name)" obj={form.fmp_filters} k="sector" set={setField('fmp_filters')}/>
                <TextField label="Industry (exact FMP name)" obj={form.fmp_filters} k="industry" set={setField('fmp_filters')}/>
                <FilterNumField label="Max YTD return (e.g. -0.30 = down 30%)" obj={form.custom_filters} k="ytd_return_max" set={setField('custom_filters')} step="0.01"/>
                <FilterNumField label="Max % of 6-mo high (e.g. 0.70)" obj={form.custom_filters} k="pct_of_6mo_high_max" set={setField('custom_filters')} step="0.01"/>
                <FilterNumField label="Max 5-day z-score" obj={form.custom_filters} k="z_score_5d_max" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Max EV/EBITDA" obj={form.custom_filters} k="ev_ebitda_max" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Min EV/EBITDA" obj={form.custom_filters} k="ev_ebitda_min" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Max P/E" obj={form.custom_filters} k="pe_max" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Min P/E" obj={form.custom_filters} k="pe_min" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Max P/B" obj={form.custom_filters} k="pb_max" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Min P/B" obj={form.custom_filters} k="pb_min" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Max Debt/Equity" obj={form.custom_filters} k="debt_equity_max" set={setField('custom_filters')} step="0.1"/>
                <FilterNumField label="Min ROE (e.g. 0.10 = 10%)" obj={form.custom_filters} k="roe_min" set={setField('custom_filters')} step="0.01"/>
                <FilterNumField label="Min dividend yield (e.g. 0.02)" obj={form.custom_filters} k="dividend_yield_min" set={setField('custom_filters')} step="0.005"/>
                <FilterNumField label="Max dividend yield" obj={form.custom_filters} k="dividend_yield_max" set={setField('custom_filters')} step="0.005"/>
              </div>
              <label style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 10, fontSize: 12.5 }}>
                <input type="checkbox" checked={!!form.custom_filters.fcf_positive}
                  onChange={e => setField('custom_filters')({ ...form.custom_filters, fcf_positive: e.target.checked || undefined })}/>
                Free cash flow positive
              </label>
            </FormSection>
          ) : (
            <FormSection title="Watchlist tickers">
              <Field label="Tickers (comma or newline-separated, max 20)">
                <textarea rows={3} value={form.ticker_list}
                  onChange={e => setField('ticker_list')(e.target.value)}
                  placeholder="AAPL, MSFT, NVDA, GOOGL..."
                  style={{ ...inputStyle, fontFamily: 'var(--font-mono)', resize: 'vertical' }}/>
              </Field>
            </FormSection>
          )}

          <FormSection title="Schedule">
            <window.SchedulePicker value={form.schedule_cron} onChange={setField('schedule_cron')}/>
          </FormSection>

          <FormSection title="Re-run rules">
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, alignItems: 'end' }}>
              <Field label="Price move threshold (% as fraction, e.g. 0.20 = 20%)">
                <input type="number" step="0.01" value={form.rerun_price_pct}
                  onChange={setNum('rerun_price_pct')} style={inputStyle}/>
              </Field>
              <Field label="Re-run after (days)">
                <input type="number" value={form.rerun_days}
                  onChange={setNum('rerun_days', v => parseInt(v) || 0)} style={inputStyle}/>
              </Field>
            </div>
          </FormSection>

          <FormSection title="Per-screen analysis cap">
            <Field label="Max analyses launched per screen (1–10)">
              <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
                <input
                  type="range" min={1} max={10} step={1}
                  value={form.max_analyses_per_screen}
                  onChange={e => setField('max_analyses_per_screen')(Number(e.target.value))}
                  style={{ flex: 1, accentColor: 'var(--onni-primary)' }}
                />
                <input
                  type="number" min={1} max={10} step={1}
                  value={form.max_analyses_per_screen}
                  onChange={e => {
                    const n = Math.max(1, Math.min(10, parseInt(e.target.value) || 1));
                    setField('max_analyses_per_screen')(n);
                  }}
                  style={{ ...inputStyle, width: 64, textAlign: 'center' }}
                />
              </div>
            </Field>
            <div style={{ fontSize: 11.5, color: 'var(--ink-500)' }}>
              Caps how many analyses one screen can launch — extra matches roll over to the next screen.
              Applies to filter and watchlist modes. Global concurrency is also limited to 10 running at once.
            </div>
          </FormSection>
        </div>

        <div style={{
          padding: '12px 20px', borderTop: '1px solid var(--ink-150)',
          background: 'var(--ink-50)',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8,
        }}>
          <div style={{ fontSize: 11.5, color: 'var(--ink-500)' }}>
            {isEdit ? 'Saving re-registers the cron job · effective on next fire' : 'Creating activates the strategy immediately'}
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button type="button" onClick={onClose} style={btnGhost}>Cancel</button>
            <button type="submit" disabled={busy} style={{ ...btnPrimary, opacity: busy ? 0.6 : 1 }}>
              {busy ? 'Saving…' : (isEdit ? 'Save changes' : 'Create strategy')}
            </button>
          </div>
        </div>
      </form>
    </div>
  );
};

function ModalHead({ title, onClose }) {
  return (
    <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--ink-150)',
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
      <div style={{ fontSize: 13, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--ink-900)' }}>{title}</div>
      <button type="button" onClick={onClose} style={{ width: 26, height: 26, borderRadius: 6, background: 'transparent', border: 'none', color: 'var(--ink-500)', cursor: 'pointer' }}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6l-12 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>
      </button>
    </div>
  );
}

function FormSection({ title, children }) {
  return (
    <div style={{ background: 'var(--paper)', border: '1px solid var(--ink-150)', borderRadius: 10, padding: '14px 16px' }}>
      <div style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 12 }}>{title}</div>
      {children}
    </div>
  );
}

function Field({ label, children }) {
  return (
    <label style={{ display: 'block', marginBottom: 10 }}>
      <div style={{ fontSize: 11, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 500, marginBottom: 5 }}>{label}</div>
      {children}
    </label>
  );
}

// Renamed from NumField to avoid a global-scope collision: every .jsx is loaded
// as a <script type="text/babel"> sharing one global scope, and settings.jsx also
// declares a top-level `NumField` (a different {value,onChange} component). It
// loads after this file, so its declaration clobbered ours and the modal rendered
// settings' NumField — which calls onChange() unconditionally, throwing
// "_onChange is not a function" on every keystroke. Hence: unique name.
function FilterNumField({ label, obj, k, set }) {
  const { useState } = React;
  // Keep the raw typed string in local state. A controlled type="number" input
  // whose value is re-derived from Number(raw) on every keystroke collapses
  // in-progress values — the "." in "0.30" and the "-" in "-0.30" get stripped
  // immediately, making decimal/negative filters impossible to type. We hold the
  // string here and only push a parsed Number to the form once it's valid; blank
  // or mid-typing ("-", "0.") removes the key so the filter is ignored.
  const [str, setStr] = useState(() => {
    const v = obj[k];
    return v === undefined || v === null ? '' : String(v);
  });
  return (
    <Field label={label}>
      <input type="text" inputMode="decimal" value={str}
        onChange={e => {
          const raw = e.target.value;
          setStr(raw);
          const next = { ...obj };
          const num = Number(raw);
          if (raw.trim() === '' || Number.isNaN(num)) delete next[k];
          else next[k] = num;
          set(next);
        }}
        style={inputStyle}/>
    </Field>
  );
}

function TextField({ label, obj, k, set }) {
  const v = obj[k];
  return (
    <Field label={label}>
      <input type="text" value={v ?? ''}
        onChange={e => {
          const raw = e.target.value.trim();
          const next = { ...obj };
          if (raw === '') delete next[k];
          else next[k] = raw;
          set(next);
        }}
        style={inputStyle}/>
    </Field>
  );
}

function ModeRadio({ selected, onClick, label, desc }) {
  return (
    <button type="button" onClick={onClick} style={{
      flex: 1, padding: '10px 12px',
      border: '1px solid ' + (selected ? 'var(--onni-primary)' : 'var(--ink-200)'),
      borderRadius: 8,
      background: selected ? 'var(--onni-primary-light)' : 'var(--paper)',
      display: 'flex', flexDirection: 'column', gap: 4,
      cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
    }}>
      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink-900)', display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ width: 14, height: 14, borderRadius: '50%',
                       border: '1.5px solid ' + (selected ? 'var(--onni-primary)' : 'var(--ink-300)'),
                       background: selected ? 'radial-gradient(var(--onni-primary) 50%, transparent 51%)' : 'transparent',
                       flexShrink: 0 }}/>
        {label}
      </div>
      <div style={{ fontSize: 11.5, color: 'var(--ink-500)', paddingLeft: 22 }}>{desc}</div>
    </button>
  );
}

const inputStyle = {
  width: '100%', padding: '8px 12px', fontSize: 13,
  background: 'var(--ink-100)', border: '1px solid var(--ink-200)',
  borderRadius: 7, outline: 'none', color: 'var(--ink-900)',
  fontFamily: 'inherit', boxSizing: 'border-box',
};
const btnPrimary = {
  padding: '8px 14px', fontSize: 12.5, fontWeight: 500,
  background: 'var(--ink-900)', color: 'white',
  border: 'none', borderRadius: 7, cursor: 'pointer',
  fontFamily: 'inherit',
};
const btnGhost = {
  padding: '8px 14px', fontSize: 12.5, fontWeight: 500,
  background: 'var(--ink-100)', color: 'var(--ink-700)',
  border: '1px solid var(--ink-200)', borderRadius: 7, cursor: 'pointer',
  fontFamily: 'inherit',
};
