/* Target builder: gender × age + exposure time/placement settings.
   Pure-controlled component, uses state at app level.
*/

const { useState: useStateTB } = React;

function GenderAgeBlock({ value, onChange }) {
  const ages = window.SimEngine.AGES;
  const v = value;

  function toggleAge(i) {
    const next = new Set(v.ages);
    if (next.has(i)) next.delete(i); else next.add(i);
    onChange({ ...v, ages: [...next].sort((a, b) => a - b) });
  }

  return (
    <div className="ga-block">
      <div className="ga-row">
        <span className="label" style={{ width: 60 }}>성별</span>
        <div className="seg-control">
          <button aria-pressed={v.gender === 'all'} onClick={() => onChange({ ...v, gender: 'all' })}>전체</button>
          <button aria-pressed={v.gender === 'F'} onClick={() => onChange({ ...v, gender: 'F' })}>여성</button>
          <button aria-pressed={v.gender === 'M'} onClick={() => onChange({ ...v, gender: 'M' })}>남성</button>
          <button aria-pressed={v.gender === 'X'} onClick={() => onChange({ ...v, gender: 'X' })}
                  title="성별 데이터가 없는 사용자(비로그인·OTP 등) 포함">비해당</button>
        </div>
        <label className="tog" style={{ marginLeft: 10 }} title="성별 데이터가 없는 사용자도 도달 범위에 포함합니다">
          <input type="checkbox" checked={!!v.includeUnknownGender}
                 onChange={e => onChange({ ...v, includeUnknownGender: e.target.checked })} />
          <span className="box"></span>
          <span style={{ fontSize: 11 }}>성별 비해당자 포함</span>
        </label>
      </div>
      <div className="ga-row" style={{ alignItems: 'flex-start' }}>
        <span className="label" style={{ width: 60, marginTop: 6 }}>연령</span>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, flex: 1 }}>
          {ages.map((a, i) => (
            <button
              key={a}
              onClick={() => toggleAge(i)}
              className={'age-pill' + (v.ages.includes(i) ? ' on' : '') + (a === '비해당' ? ' is-unknown' : '')}
              title={a === '비해당' ? '연령 데이터가 없는 사용자' : ''}
            >{a}</button>
          ))}
        </div>
      </div>
      <div className="ga-helper">
        <span className="label">선택 요약</span>
        <span className="mono" style={{ fontSize: 11, color: 'var(--text-dim)' }}>
          {summarize(v, ages)}
        </span>
      </div>
      <style>{`
        .ga-block { display: flex; flex-direction: column; gap: 12px; }
        .ga-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
        .age-pill {
          padding: 5px 10px;
          background: var(--ink-100);
          border: 1px solid var(--border-strong);
          color: var(--text-dim);
          font-family: var(--font-mono);
          font-size: 11px;
          cursor: pointer;
        }
        .age-pill:hover { color: var(--text); }
        .age-pill.on {
          background: var(--signal);
          border-color: var(--signal);
          color: var(--ink-000);
        }
        .age-pill.is-unknown {
          border-style: dashed;
        }
        .age-pill.is-unknown.on {
          background: var(--cyan);
          border-color: var(--cyan);
          border-style: solid;
        }
        .ga-helper {
          display: flex; gap: 10px; align-items: center;
          padding: 8px 10px;
          background: rgba(255,240,220,0.04);
          border-left: 2px solid var(--cyan);
        }
      `}</style>
    </div>
  );
}

function summarize(v, ages) {
  const g = v.gender === 'all' ? '전체' : v.gender === 'F' ? '여성' : v.gender === 'M' ? '남성' : '비해당';
  const ageSel = v.ages.length ? v.ages.map(i => ages[i]).join(', ') : '전체';
  const inclG = v.includeUnknownGender ? '+ 성별 비해당자' : '';
  return `${g}${inclG ? ' ' + inclG : ''} · 연령: ${ageSel}`;
}

function ExposurePanel({ value, onChange }) {
  const v = value;
  const placements = window.SimEngine.PLACEMENTS;
  const times = window.SimEngine.TIME_BINS;

  // Creative specs required by selected placements
  const CREATIVE_SPECS = {
    feed:      [{ id: 'sq', label: '정사각 1:1 (1080×1080)', size: '< 10MB · JPG/PNG' }, { id: 'cp', label: '카피 40자', size: '제목 25자' }],
    smartcast: [{ id: 'pano', label: '와이드 16:9 (1920×1080)', size: '동영상 15초 권장' }],
    banner:    [{ id: '728', label: '리더보드 728×90', size: '< 200KB' }, { id: '300', label: 'MR 300×250', size: '< 150KB' }],
    shopping:  [{ id: 'prod', label: '상품 이미지 800×800', size: '+ 가격 메타' }],
    content:   [{ id: 'art', label: '아티클 썸네일 600×400', size: '제목 30자' }],
    video:     [{ id: 'vid15', label: '인스트림 15초', size: 'MP4 · < 30MB' }, { id: 'vid6', label: '범퍼 6초', size: 'MP4 · < 10MB' }],
  };
  const requiredSpecs = v.placements.flatMap(pid => (CREATIVE_SPECS[pid] || []).map(s => ({ ...s, placement: pid })));

  // Audience targets (preset)
  const AUDIENCES = [
    { id: 'aud_rt',    label: '내 사이트 재방문', desc: '30일 내 방문 사용자' },
    { id: 'aud_conv',  label: '구매 전환 리타게팅', desc: '장바구니/결제 진입 사용자' },
    { id: 'aud_view',  label: '동영상 75% 시청자', desc: '소재 75% 이상 시청' },
    { id: 'aud_look1', label: '유사 잠재고객 1%', desc: '전환 고객과 유사도 상위 1%' },
    { id: 'aud_look5', label: '유사 잠재고객 5%', desc: '전환 고객과 유사도 상위 5%' },
    { id: 'aud_excl',  label: '기구매자 제외',    desc: '구매 완료 30일 내 제외' },
  ];

  function togglePlace(id) {
    const next = new Set(v.placements);
    if (next.has(id)) next.delete(id); else next.add(id);
    onChange({ ...v, placements: [...next] });
  }
  function toggleTime(id) {
    const next = new Set(v.times);
    if (next.has(id)) next.delete(id); else next.add(id);
    onChange({ ...v, times: [...next] });
  }
  function toggleAudience(id) {
    const next = new Set(v.audiences || []);
    if (next.has(id)) next.delete(id); else next.add(id);
    onChange({ ...v, audiences: [...next] });
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <Section title="잠재고객 타겟" hint="자사 데이터·전환 픽셀 기반 오디언스">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          {AUDIENCES.map(a => {
            const on = (v.audiences || []).includes(a.id);
            return (
              <div key={a.id} className="place-row" onClick={() => toggleAudience(a.id)}>
                <span className={'place-tick ' + (on ? 'on' : '')}>{on ? '■' : '▢'}</span>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 12, color: on ? 'var(--text)' : 'var(--text-dim)' }}>{a.label}</div>
                  <div style={{ fontSize: 10, color: 'var(--text-mute)' }}>{a.desc}</div>
                </div>
              </div>
            );
          })}
        </div>
      </Section>

      <Section title="노출 지면" hint="다중 선택 — 지면에 따라 필요 소재가 자동 산출">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          {placements.map(p => {
            const on = v.placements.includes(p.id);
            return (
              <div key={p.id} className="place-row" onClick={() => togglePlace(p.id)}>
                <span className={'place-tick ' + (on ? 'on' : '')}>{on ? '■' : '▢'}</span>
                <span style={{ flex: 1, fontSize: 12, color: on ? 'var(--text)' : 'var(--text-dim)' }}>
                  {p.label}
                </span>
                <span className="mono mute" style={{ fontSize: 10 }}>
                  도달 {(p.pop * 100).toFixed(0)}%
                </span>
              </div>
            );
          })}
        </div>
      </Section>

      {requiredSpecs.length > 0 && (
        <Section title="필요 소재 규격" hint={`선택된 지면 기준 ${requiredSpecs.length}종 필요`}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            {requiredSpecs.map((s, i) => (
              <div key={i} className="spec-row">
                <span className="spec-dot" />
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 12 }}>{s.label}</div>
                  <div style={{ fontSize: 10, color: 'var(--text-mute)' }}>
                    {window.SimEngine.PLACEMENTS.find(p => p.id === s.placement)?.label} · {s.size}
                  </div>
                </div>
              </div>
            ))}
          </div>
        </Section>
      )}

      <Section title="노출 시간대" hint="ON/OFF만 — 가중치 없음">
        <div style={{ display: 'flex', gap: 4 }}>
          {times.map(t => {
            const on = v.times.includes(t.id);
            return (
              <button key={t.id} onClick={() => toggleTime(t.id)} className={'time-bin ' + (on ? 'on' : '')}>
                <strong>{t.label}</strong>
                <small>{t.mood}</small>
                <span className="time-onoff">{on ? 'ON' : 'OFF'}</span>
              </button>
            );
          })}
        </div>
      </Section>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <Section title="일 예산 한도">
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <input
              type="range" className="range"
              min={50000} max={5000000} step={50000}
              value={v.budget}
              onChange={e => onChange({ ...v, budget: +e.target.value })}
            />
            <span className="mono" style={{ minWidth: 80, textAlign: 'right', fontSize: 12 }}>
              ₩{v.budget.toLocaleString()}
            </span>
          </div>
        </Section>
        <Section title="입찰가 한도">
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <input
              type="range" className="range"
              min={500} max={20000} step={100}
              value={v.maxBid || 3000}
              onChange={e => onChange({ ...v, maxBid: +e.target.value })}
            />
            <span className="mono" style={{ minWidth: 80, textAlign: 'right', fontSize: 12 }}>
              ₩{(v.maxBid || 3000).toLocaleString()}
            </span>
          </div>
        </Section>
      </div>

      <Section title="입찰 전략">
        <div className="seg-control" style={{ width: '100%' }}>
          {['CPM', 'CPC', 'oCPM'].map(s => (
            <button key={s} aria-pressed={v.bid === s} onClick={() => onChange({ ...v, bid: s })} style={{ flex: 1 }}>
              {s}
            </button>
          ))}
        </div>
      </Section>

      <Section title="노출 빈도 한도" hint="그룹/소재 단위 1인당 노출 횟수">
        <div className="freq-row">
          {[1, 2, 3, 4, 5].map(n => {
            const on = v.freqCap === n;
            return (
              <button key={n} onClick={() => onChange({ ...v, freqCap: n })} className={'freq-pill' + (on ? ' on' : '')}>
                {n}회
              </button>
            );
          })}
          <button onClick={() => onChange({ ...v, freqCap: 'ai' })}
                  className={'freq-pill' + (v.freqCap === 'ai' ? ' on signal' : '')}
                  style={{ flex: 1.5 }}>
            ✦ AI 자동
          </button>
        </div>
        <div style={{ fontSize: 11, color: 'var(--text-mute)', marginTop: 6 }}>
          {v.freqCap === 'ai'
            ? 'AI가 학습 데이터를 기반으로 페르소나별 최적 빈도를 자동 결정합니다.'
            : `1명당 동일 그룹·소재에 최대 ${v.freqCap}회 노출됩니다.`}
        </div>
      </Section>

      <style>{`
        .place-row {
          display: flex; align-items: center; gap: 10px;
          padding: 7px 8px;
          cursor: pointer;
          border: 1px solid var(--border);
          background: rgba(255,240,220,0.02);
          transition: background 0.12s;
        }
        .place-row:hover { background: rgba(255,240,220,0.06); }
        .place-tick {
          font-family: var(--font-mono);
          font-size: 13px;
          color: var(--text-mute);
        }
        .place-tick.on { color: var(--signal); }
        .time-bin {
          flex: 1;
          background: rgba(255,240,220,0.04);
          border: 1px solid var(--border-strong);
          color: var(--text-dim);
          padding: 10px 4px 6px;
          cursor: pointer;
          display: flex; flex-direction: column; align-items: center; gap: 3px;
          position: relative;
        }
        .time-bin strong {
          font-family: var(--font-mono);
          font-size: 12px;
          font-weight: 500;
        }
        .time-bin small {
          font-size: 10px;
          color: var(--text-mute);
        }
        .time-bin .time-onoff {
          font-family: var(--font-mono);
          font-size: 9px;
          color: var(--text-mute);
          margin-top: 2px;
          letter-spacing: 0.06em;
        }
        .time-bin.on {
          background: oklch(0.78 0.12 220 / 0.18);
          border-color: var(--cyan);
          color: var(--cyan);
        }
        .time-bin.on strong, .time-bin.on small, .time-bin.on .time-onoff { color: var(--cyan); }
        .spec-row {
          display: flex; align-items: center; gap: 10px;
          padding: 6px 8px;
          background: rgba(255,240,220,0.02);
          border: 1px solid var(--border);
        }
        .spec-dot {
          width: 6px; height: 6px;
          background: var(--signal);
          border-radius: 50%;
          box-shadow: 0 0 6px var(--signal);
        }
        .freq-row {
          display: flex; gap: 4px;
        }
        .freq-pill {
          flex: 1;
          padding: 8px 4px;
          background: rgba(255,240,220,0.04);
          border: 1px solid var(--border-strong);
          color: var(--text-dim);
          font-family: var(--font-mono);
          font-size: 12px;
          cursor: pointer;
        }
        .freq-pill.on {
          background: oklch(0.78 0.12 220 / 0.20);
          border-color: var(--cyan);
          color: var(--cyan);
        }
        .freq-pill.on.signal {
          background: oklch(0.80 0.14 72 / 0.20);
          border-color: var(--signal);
          color: var(--signal);
        }
      `}</style>
    </div>
  );
}

function Section({ title, hint, children }) {
  return (
    <div>
      <div style={{ marginBottom: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <div className="label" style={{ fontSize: 12 }}>{title}</div>
        {hint && <div style={{ fontSize: 10, color: 'var(--text-mute)' }}>{hint}</div>}
      </div>
      {children}
    </div>
  );
}

Object.assign(window, { GenderAgeBlock, ExposurePanel });
