/* =========================================================
   Root app
   ========================================================= */
const { useState, useEffect } = React;
const {
  Icon, MonsteraLeaf, Toast, CoupleMark,
  PersonStep, ConditionsStep, ScheduleStep, TripModeSwitch, TripStep,
  ResultScreen, CalendarScreen, MemoryDetail,
  Onboarding, ProposalsPanel
} = window;

const SETTINGS_KEY = 'sojeong_settings_v1';
const SETTINGS_DEFAULT = { theme:'forest', radius:'soft', textScale:1, opacity:1 };
function loadSettings(){
  try { const s = JSON.parse(localStorage.getItem(SETTINGS_KEY)); if (s) return { ...SETTINGS_DEFAULT, ...s }; } catch(e){}
  return { ...SETTINGS_DEFAULT };
}

const DRAFT_KEY = 'sojeong_draft_v2';
const HIST_KEY  = 'sojeong_history_v1';
const clone = (o) => JSON.parse(JSON.stringify(o));

function flowFor(mode){
  return mode === 'together'
    ? [{ key:'trip', label:'경로' }, { key:'cond', label:'조건' }, { key:'date', label:'일정' }, { key:'result', label:'결과' }]
    : [{ key:'j', label:'준영' }, { key:'s', label:'소정' }, { key:'cond', label:'조건' }, { key:'date', label:'일정' }, { key:'result', label:'결과' }];
}

function loadDraft(){
  try { const d = JSON.parse(localStorage.getItem(DRAFT_KEY)); if (d) return d; } catch(e){}
  return {
    step:0,
    tripMode: window.SEED.tripMode,
    trip: clone(window.SEED.trip),
    people: clone(window.SEED.people),
    conditions: clone(window.SEED.conditions),
    meet: clone(window.SEED.meet),
    picks: [], memo:'', photos:[]
  };
}
function freshDraft(){
  return {
    step:0,
    tripMode: window.SEED.tripMode,
    trip: clone(window.SEED.trip),
    people: clone(window.SEED.people),
    conditions: clone(window.SEED.conditions),
    meet: clone(window.SEED.meet),
    picks: [], memo:'', photos:[]
  };
}
function loadHistory(){
  try { const h = JSON.parse(localStorage.getItem(HIST_KEY)); if (Array.isArray(h)) return h; } catch(e){}
  return [];
}

function App(){
  const [tab, setTab] = useState('plan');
  const [draft, setDraft] = useState(loadDraft);
  const [history, setHistory] = useState(loadHistory);
  const [detail, setDetail] = useState(null);
  const [toast, setToast] = useState('');
  const [identity, setIdentity] = useState(window.loadIdentity ? window.loadIdentity() : null);
  const [proposals, setProposals] = useState(null);
  const cloudOn = !!(identity && window.Cloud && window.Cloud.ready());
  const pendingCount = proposals ? proposals.filter(p => p.status === 'pending' && identity && p.from_name !== identity.name).length : 0;

  const [settings, setSettings] = useState(loadSettings);
  const [settingsOpen, setSettingsOpen] = useState(false);
  useEffect(() => {
    try { localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings)); } catch(e){}
    window.applyTheme(settings.theme, settings.radius, settings.textScale, settings.opacity);
  }, [settings]);
  const setS = (k, v) => setSettings(s => ({ ...s, [k]: v }));

  const step = draft.step;
  const flow = flowFor(draft.tripMode);
  const resultIdx = flow.length - 1;
  const lastInput = resultIdx - 1;
  const condIdx = flow.findIndex(f => f.key === 'cond');
  const curKey = flow[step] ? flow[step].key : 'result';

  // persist
  useEffect(() => { try { localStorage.setItem(DRAFT_KEY, JSON.stringify(draft)); } catch(e){} }, [draft]);
  useEffect(() => { try { localStorage.setItem(HIST_KEY, JSON.stringify(history)); } catch(e){} }, [history]);

  const prevPropsRef = React.useRef(null);
  const refreshCloud = async () => {
    if (!cloudOn) return;
    const [mems, props] = await Promise.all([window.Cloud.listMemories(identity.code), window.Cloud.listProposals(identity.code)]);
    if (mems) setHistory(mems);
    if (props) {
      // 내가 보낸 제안이 새로 응답되면 토스트 알림
      const prev = prevPropsRef.current;
      if (prev) {
        const other = identity.name === '준영' ? '소정' : '준영';
        props.forEach(p => {
          const was = prev[p.id];
          if (p.from_name === identity.name && was === 'pending' && p.status !== 'pending') {
            fireToast(p.status === 'accepted' ? other + '이 "여기 가자"고 답했어 💚' : other + '이 "다음에" 라고 했어 🥲');
          }
        });
      }
      const map = {}; props.forEach(p => { map[p.id] = p.status; });
      prevPropsRef.current = map;
      setProposals(props);
    }
  };
  useEffect(() => {
    if (!cloudOn) return;
    let ch = null;
    refreshCloud();
    window.Cloud.subscribe(identity.code, () => refreshCloud()).then(c => { ch = c; });
    return () => { try { ch && ch.unsubscribe && ch.unsubscribe(); } catch(e){} };
  }, [cloudOn, identity && identity.code]);

  const patch = (p) => setDraft(d => ({ ...d, ...p }));
  const patchPerson = (key, p) => setDraft(d => ({ ...d, people: { ...d.people, [key]: { ...d.people[key], ...p } } }));
  const clearPerson = (key) => setDraft(d => ({ ...d, people: { ...d.people, [key]: {
    ...d.people[key], start:'', waypoint:'', waypointNone:false, dest:'', home:'' } } }));
  const patchCond = (p) => setDraft(d => ({ ...d, conditions: { ...d.conditions, ...p } }));
  const patchMeet = (p) => setDraft(d => ({ ...d, meet: { ...d.meet, ...p } }));
  const patchTrip = (p) => setDraft(d => ({ ...d, trip: { ...d.trip, ...p } }));
  const clearTrip = () => setDraft(d => ({ ...d, trip: { ...d.trip, start:'', waypoint:'', waypointNone:false, dest:'' } }));
  const setTripMode = (m) => setDraft(d => ({ ...d, tripMode:m, step:0 }));

  const goTo = (s) => { setDraft(d => ({ ...d, step:s })); window.scrollTo({ top:0, behavior:'smooth' }); };

  const fireToast = (m) => { setToast(m); setTimeout(() => setToast(''), 2600); };

  const saveMemory = async (kind) => {
    kind = kind || 'memory';
    const together = draft.tripMode === 'together';
    const destQuery = (together ? draft.trip.dest : (draft.people.j.dest || draft.people.s.dest)) || '영통역';
    const people = {
      j: { name:draft.people.j.name, start:draft.people.j.start, dest:draft.people.j.dest, mode:draft.people.j.mode },
      s: { name:draft.people.s.name, start:draft.people.s.start, dest:draft.people.s.dest, mode:draft.people.s.mode }
    };
    const mem = {
      author: identity ? identity.name : null,
      date: draft.meet.date, time: draft.meet.time, kind,
      tripMode: draft.tripMode, destQuery,
      trip: together ? { start:draft.trip.start, dest:draft.trip.dest, mode:draft.trip.mode } : null,
      people, picks: draft.picks, memo: draft.memo, photos: kind === 'plan' ? [] : draft.photos
    };
    const okMsg = kind === 'plan' ? '플랜 저장 완료 📅 달력에 콕!' : '우리 추억, 저장 완료 💕';
    if (cloudOn) {
      fireToast(kind === 'plan' ? '플랜 저장 중…' : '추억 저장 중…');
      // 스키마 변경 없이 kind 보존: people.__kind 에 동봉
      const payload = { ...mem, people: { ...people, __kind: kind } };
      const saved = await window.Cloud.addMemory(identity.code, payload);
      await refreshCloud();
      fireToast(saved ? okMsg : '저장 실패 — 잠시 후 다시');
    } else {
      setHistory(h => [{ ...mem, id:'m'+Date.now(), savedAt:Date.now() }, ...h]);
      fireToast(okMsg);
    }
    setTab('calendar');
    window.scrollTo({ top:0, behavior:'smooth' });
  };
  const savePlan = () => saveMemory('plan');

  const logout = () => {
    window.clearIdentity();
    setProposals(null);
    setHistory([]);
    setIdentity(null);
    setSettingsOpen(false);
    setTab('plan');
  };

  const deleteMemory = async (id) => {
    if (cloudOn) { await window.Cloud.delMemory(id); await refreshCloud(); }
    else setHistory(h => h.filter(m => m.id !== id));
    setDetail(null);
  };

  const sendProposal = async () => {
    if (!cloudOn) { fireToast('커플 연결 후 보낼 수 있어요'); return; }
    const together = draft.tripMode === 'together';
    const destQuery = (together ? draft.trip.dest : (draft.people.j.dest || draft.people.s.dest)) || '영통역';
    const pr = window.RESTAURANTS.find(x => x.id === draft.picks[0]);
    const sent = await window.Cloud.addProposal(identity.code, {
      from: identity.name, title: destQuery + ' 어때?',
      payload: { dest: destQuery, date: draft.meet.date, time: draft.meet.time, place: pr ? pr.name : null }
    });
    await refreshCloud();
    fireToast(sent ? '상대에게 보냈어요 💌' : '전송 실패 — Supabase 설정 확인 필요');
  };
  const respondProposal = async (id, status, reply) => {
    if (!cloudOn) return;
    await window.Cloud.respondProposal(id, status, reply);
    await refreshCloud();
    fireToast(status === 'accepted' ? '여기 가자고 답했어요 💚' : '답장 보냈어요');
  };

  const restartPlan = () => {
    setDraft(freshDraft());
    window.scrollTo({ top:0, behavior:'smooth' });
  };

  /* ---------- render plan content ---------- */
  let content;
  if (tab === 'calendar') {
    content = <CalendarScreen history={history} plannedDate={draft.meet.date} onOpen={setDetail} />;
  } else if (tab === 'inbox') {
    content = (
      <div className="cal-wrap fadein">
        <div className="step-head">
          <div className="eyebrow">우리 사이</div>
          <h2>주고받은 제안 💌</h2>
          <p>“여기 어때?” 보내고 답하기.</p>
        </div>
        <div className="card" style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:10, marginBottom:8 }}>
          <div>
            <div className="role">연결 코드 (둘이 같아야 함)</div>
            <div style={{ fontWeight:900, color:'var(--green-800)', fontSize:'1.02rem' }}>{identity ? identity.code : ''}</div>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={() => { window.clearIdentity(); setIdentity(null); }}>코드 변경</button>
        </div>
        <ProposalsPanel proposals={proposals} myName={identity ? identity.name : ''} onRespond={respondProposal} />
      </div>
    );
  } else if (curKey === 'j') {
    content = <PersonStep person={draft.people.j} onChange={p => patchPerson('j', p)} onClearAll={() => clearPerson('j')} />;
  } else if (curKey === 's') {
    content = <PersonStep person={draft.people.s} onChange={p => patchPerson('s', p)} onClearAll={() => clearPerson('s')} />;
  } else if (curKey === 'trip') {
    content = <TripStep trip={draft.trip} onChange={patchTrip} onClearAll={clearTrip} />;
  } else if (curKey === 'cond') {
    content = <ConditionsStep conditions={draft.conditions} onChange={patchCond} />;
  } else if (curKey === 'date') {
    content = <ScheduleStep meet={draft.meet} onChange={patchMeet} />;
  } else {
    content = <ResultScreen state={draft} onPatch={patch} onSave={() => saveMemory('memory')} onSavePlan={savePlan} onSend={cloudOn ? sendProposal : null} />;
  }

  /* ---------- footer nav ---------- */
  let footer = null;
  if (tab !== 'plan') {
    footer = (
      <div className="footnav">
        <button className="btn btn-primary btn-full" onClick={() => { setTab('plan'); goTo(0); }}>
          <Icon name="plus" />새 데이트 짜기
        </button>
      </div>
    );
  } else if (step < lastInput) {
    footer = (
      <div className="footnav">
        {step > 0 && <button className="btn btn-back" onClick={() => goTo(step - 1)}><Icon name="back" /></button>}
        <button className="btn btn-primary" onClick={() => goTo(step + 1)}>
          다음<Icon name="arrowR" />
        </button>
      </div>
    );
  } else if (step === lastInput) {
    footer = (
      <div className="footnav">
        <button className="btn btn-back" onClick={() => goTo(step - 1)}><Icon name="back" /></button>
        <button className="btn btn-primary" onClick={() => goTo(resultIdx)}>
          <Icon name="sparkle" />추천 결과 보기
        </button>
      </div>
    );
  } else {
    footer = (
      <div className="footnav" style={{ gap:7 }}>
        <button className="btn btn-ghost btn-sm" style={{ flex:1 }} onClick={restartPlan}><Icon name="spark2" />전체변경</button>
        <button className="btn btn-ghost btn-sm" style={{ flex:1 }} onClick={() => goTo(0)}><Icon name="route" />경로변경</button>
        <button className="btn btn-ghost btn-sm" style={{ flex:1 }} onClick={() => goTo(condIdx)}><Icon name="filter" />조건변경</button>
      </div>
    );
  }

  const showProgress = tab === 'plan';

  if (window.Cloud && window.Cloud.ready() && !identity) {
    return <Onboarding onDone={(i) => setIdentity(i)} />;
  }

  return (
    <div className="app">
      {/* TOP BAR */}
      <div className="topbar">
        <div className="topbar-row">
          <div className="brand">
            <CoupleMark size={26} />
            <span className="nm">소정아, 여기 어때?</span>
          </div>
          <div className="tabs">
            <button className={tab === 'plan' ? 'on' : ''} onClick={() => setTab('plan')}>플랜</button>
            <button className={tab === 'calendar' ? 'on' : ''} onClick={() => setTab('calendar')}>달력</button>
            {cloudOn && (
              <button className={'bell ' + (tab === 'inbox' ? 'on' : '')} onClick={() => setTab('inbox')}>
                요청{pendingCount > 0 && <span className="dot-n">{pendingCount}</span>}
              </button>
            )}
          </div>
        </div>
        {showProgress && (
          <div className="progress">
            <div className="steps">
              {flow.map((s, i) => (
                <div key={i} className={'seg' + (i < step ? ' done' : '') + (i === step ? ' cur' : '')}><i></i></div>
              ))}
            </div>
            <div className="lbl">
              {flow.map((s, i) => <span key={i} className={i === step ? 'on' : ''}>{s.label}</span>)}
            </div>
          </div>
        )}
      </div>

      {/* MAIN */}
      <div className="app-main">
        {tab === 'plan' && step === 0 && (
          <TripModeSwitch value={draft.tripMode} onChange={setTripMode} />
        )}
        {content}
      </div>

      {footer}
      <Toast msg={toast} />
      {detail && <MemoryDetail data={detail} plannedDate={draft.meet.date} onClose={() => setDetail(null)} onDelete={deleteMemory} />}

      {!settingsOpen && (
        <button className="fab-settings" onClick={() => setSettingsOpen(true)} aria-label="화면 설정">
          <Icon name="sliders" />
        </button>
      )}

      {settingsOpen && (
        <div className="scrim" onClick={() => setSettingsOpen(false)}>
          <div className="sheet" onClick={e => e.stopPropagation()}>
            <div className="sheet-grip"></div>
            <div className="sheet-head">
              <h3>화면 설정 🎨</h3>
              <button className="x" onClick={() => setSettingsOpen(false)}><Icon name="x" /></button>
            </div>
            <div className="sheet-body">
              <div className="set-sec">색상 테마</div>
              <div className="theme-swatches">
                {Object.entries(window.THEMES).map(([k, th]) => (
                  <button key={k} className={'theme-swatch' + (settings.theme === k ? ' on' : '')}
                    style={{ border: settings.theme === k ? '2px solid ' + th.sw : '2px solid var(--line)' }}
                    onClick={() => setS('theme', k)}>
                    <span className="ring" style={{ background: th.sw }}></span>
                    <span className="nm">{th.label}</span>
                  </button>
                ))}
              </div>

              <div className="set-sec">모서리 둥글기</div>
              <div className="radius-seg">
                {[['round','동글'],['soft','기본'],['sharp','각진']].map(([k, l]) => (
                  <button key={k} className={settings.radius === k ? 'on' : ''} onClick={() => setS('radius', k)}>{l}</button>
                ))}
              </div>

              <div className="set-sec">글자 크기</div>
              <div className="set-slider-head"><span>크기</span><b>{Math.round(settings.textScale * 100)}%</b></div>
              <input type="range" min="0.9" max="1.2" step="0.05" value={settings.textScale}
                onChange={e => setS('textScale', parseFloat(e.target.value))} />

              <div className="set-sec">투명도</div>
              <div className="set-slider-head"><span>불투명도</span><b>{Math.round(settings.opacity * 100)}%</b></div>
              <input type="range" min="0.5" max="1" step="0.05" value={settings.opacity}
                onChange={e => setS('opacity', parseFloat(e.target.value))} />

              {identity && (
                <React.Fragment>
                  <div className="set-sec">계정</div>
                  <div className="logout-row">
                    <div>
                      <div className="lr-label">연결된 커플 코드</div>
                      <div className="lr-code">{identity.code} · {identity.name}</div>
                    </div>
                    <button className="btn btn-ghost btn-sm" onClick={logout}>
                      <Icon name="back" />로그아웃
                    </button>
                  </div>
                </React.Fragment>
              )}

              <div style={{ height:6 }}></div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
