// 共用组件：区域卡片、星标、投票、便签
// 挂到 window 供其他 babel script 使用

const { useState, useEffect, useMemo, useRef } = React;

// -------- localStorage helpers --------
function useLocalStorage(key, initial) {
  const [v, setV] = useState(() => {
    try {
      const s = localStorage.getItem(key);
      return s ? JSON.parse(s) : initial;
    } catch { return initial; }
  });
  useEffect(() => {
    try { localStorage.setItem(key, JSON.stringify(v)); } catch {}
  }, [key, v]);
  return [v, setV];
}

// -------- 星标组件 --------
function StarRow({ value, onChange, max = 5, size = 18 }) {
  return (
    <span className="star-row" style={{ fontSize: size }}>
      {Array.from({ length: max }).map((_, i) => (
        <span
          key={i}
          className={'star' + (i < value ? ' on' : '')}
          onClick={(e) => {
            e.stopPropagation();
            onChange(i + 1 === value ? 0 : i + 1);
          }}
          style={{ fontSize: size }}
        >★</span>
      ))}
    </span>
  );
}

// -------- 拥挤度条 --------
function CrowdMeter({ level = 1 }) {
  const dots = [1,2,3,4,5];
  return (
    <span style={{ display: 'inline-flex', gap: 3, alignItems: 'center' }}>
      {dots.map(d => (
        <span key={d} style={{
          width: 8, height: 8, borderRadius: '50%',
          background: d <= level ? (level >= 4 ? 'var(--red-pen)' : level >= 3 ? 'var(--orange-pen)' : 'var(--green-pen)') : 'transparent',
          border: '1px solid var(--ink-soft)',
        }} />
      ))}
    </span>
  );
}

// -------- Tier Badge --------
function TierBadge({ tier, label }) {
  return <span className={'badge ' + tier}>{label}</span>;
}

// -------- 标签 --------
function Tags({ items }) {
  return (
    <div style={{ marginTop: 4 }}>
      {(items || []).map(t => <span key={t} className="tag-chip">#{t}</span>)}
    </div>
  );
}

// -------- 投票信息 (多朋友) --------
// 数据结构：{ [regionId]: { [friendName]: score 0-5 } }
function useVotes() {
  return useLocalStorage('mayday_votes_v1', {});
}
function useFriends() {
  return useLocalStorage('mayday_friends_v1', ['我']);
}

function avgScore(regionVotes) {
  if (!regionVotes) return 0;
  const vals = Object.values(regionVotes).filter(n => n > 0);
  if (!vals.length) return 0;
  return vals.reduce((a,b) => a+b, 0) / vals.length;
}

// -------- 区域详情便签 --------
function RegionDetail({ region, currentFriend, votes, setVotes, onClose }) {
  if (!region) return null;
  const rVotes = votes[region.id] || {};
  const myScore = rVotes[currentFriend] || 0;

  const setMyScore = (v) => {
    setVotes({
      ...votes,
      [region.id]: { ...(votes[region.id] || {}), [currentFriend]: v }
    });
  };

  return (
    <div className="sticky yellow" style={{ padding: 20, maxWidth: 520 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'start', gap: 10 }}>
        <div>
          <div style={{ fontSize: 11, opacity: 0.6, marginBottom: 2 }}>{region.province}</div>
          <div className="title-hand" style={{ fontSize: 26, lineHeight: 1.1 }}>{region.name}</div>
          <div style={{ marginTop: 6, display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
            <TierBadge tier={region.tier} label={region.tierLabel} />
            <span className="mono-hand soft" style={{ fontSize: 13 }}>{region.distance} · {region.drive}</span>
          </div>
        </div>
        {onClose && <button className="btn-hand sm" onClick={onClose}>×</button>}
      </div>

      <hr className="hr-hand" />

      {region.tier === 'avoid' ? (
        <div>
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 6, color: 'var(--red-pen)' }}>
            ⚠ {region.oneLiner}
          </div>
          <div style={{ marginTop: 4 }}>
            <span className="muted" style={{ fontSize: 12 }}>五一拥挤度：</span>
            <CrowdMeter level={region.crowd} /> <span className="soft" style={{ fontSize: 13 }}>{region.crowdLabel}</span>
            {region.days && <span className="mono-hand soft" style={{ fontSize: 12, marginLeft: 8 }}>· {region.days}</span>}
          </div>
          <Tags items={region.tags} />

          {region.whyAvoid && (
            <div style={{ marginTop: 12, padding: '10px 12px', background: 'var(--accent-warn)', border: '1px dashed var(--red-pen)', borderRadius: 3, fontSize: 13, lineHeight: 1.5 }}>
              <div className="mono-hand" style={{ fontSize: 11, color: 'var(--red-pen)', marginBottom: 4 }}>为什么五一劝退</div>
              {region.whyAvoid}
            </div>
          )}

          <div className="region-detail-grid" style={{ display: 'grid', gridTemplateColumns: '100px 1fr', rowGap: 6, columnGap: 8, fontSize: 13, marginTop: 10 }}>
            {region.playways && (<><div className="muted label-cell">正确打开</div><div>{region.playways}</div></>)}
            {region.stay && (<><div className="muted label-cell">住宿</div><div>{region.stay}</div></>)}
            {region.food && (<><div className="muted">吃</div><div>{region.food}</div></>)}
            {region.rainy && (<><div className="muted">雨天</div><div>{region.rainy}</div></>)}
            {region.audience && (<><div className="muted">适合谁</div><div>{region.audience}</div></>)}
          </div>

          {(region.pros || region.cons) && (
            <div className="region-detail-proscons" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginTop: 10 }}>
              {region.pros && (
                <div>
                  <div className="mono-hand muted" style={{ fontSize: 11 }}>+ 还有的好</div>
                  <ul style={{ margin: '4px 0', paddingLeft: 18, fontSize: 13 }}>
                    {region.pros.map(p => <li key={p}>{p}</li>)}
                  </ul>
                </div>
              )}
              {region.cons && (
                <div>
                  <div className="mono-hand muted" style={{ fontSize: 11 }}>− 雷点</div>
                  <ul style={{ margin: '4px 0', paddingLeft: 18, fontSize: 13 }}>
                    {region.cons.map(p => <li key={p}>{p}</li>)}
                  </ul>
                </div>
              )}
            </div>
          )}

          {region.alt && (() => {
            const altR = (window.REGIONS || []).find(x => x.id === region.alt);
            if (!altR) return null;
            return (
              <div style={{ marginTop: 12, padding: '10px 12px', background: 'rgba(216,236,212,0.5)', border: '1.5px solid #2e7d5b', borderRadius: 3, fontSize: 13 }}>
                <div className="mono-hand" style={{ fontSize: 11, color: '#2e7d5b', marginBottom: 4 }}>→ 推荐替代</div>
                <div style={{ fontWeight: 600, fontSize: 14 }}>{altR.name}</div>
                {region.altReason && <div style={{ marginTop: 3, lineHeight: 1.5 }}>{region.altReason}</div>}
              </div>
            );
          })()}
        </div>
      ) : (
        <>
          <div style={{ fontSize: 15, fontWeight: 600, marginBottom: 6 }}>
            <span className="highlight-green">{region.oneLiner}</span>
          </div>

          {region.whyPick && (() => {
            const isTop = region.tier === 'top';
            const bg = isTop ? 'rgba(216,236,212,0.5)' : 'rgba(247,231,193,0.55)';
            const border = isTop ? '1.5px solid #2e7d5b' : '1.5px dashed #c08835';
            const label = isTop ? '为什么值得专门去' : '为什么可以考虑（挑路线）';
            const color = isTop ? '#2e7d5b' : '#8a5a1a';
            return (
              <div style={{ marginTop: 10, padding: '10px 12px', background: bg, border, borderRadius: 3, fontSize: 13, lineHeight: 1.5 }}>
                <div className="mono-hand" style={{ fontSize: 11, color, marginBottom: 4 }}>{label}</div>
                {region.whyPick}
              </div>
            );
          })()}

          <div className="region-detail-grid" style={{ display: 'grid', gridTemplateColumns: '100px 1fr', rowGap: 6, columnGap: 8, fontSize: 13, marginTop: 10 }}>
            <div className="muted label-cell">推荐天数</div><div>{region.days}</div>
            <div className="muted label-cell">五一拥挤</div><div><CrowdMeter level={region.crowd} /> <span className="soft">{region.crowdLabel}</span></div>
            <div className="muted label-cell">玩法</div><div>{region.playways}</div>
            {region.stops && (<><div className="muted label-cell">具体点位</div><div>{region.stops}</div></>)}
            {region.timing && (<><div className="muted label-cell">时段建议</div><div>{region.timing}</div></>)}
            <div className="muted label-cell">住宿</div><div>{region.stay}</div>
            <div className="muted label-cell">吃</div><div>{region.food}</div>
            <div className="muted label-cell">雨天备选</div><div>{region.rainy}</div>
            <div className="muted label-cell">适合</div><div>{region.audience}</div>
          </div>

          {region.warning && (
            <div style={{ marginTop: 10, padding: '8px 12px', background: 'rgba(247,224,194,0.4)', borderLeft: '3px solid #c08835', fontSize: 12.5, lineHeight: 1.5 }}>
              <span className="mono-hand" style={{ color: '#8a5a1a', marginRight: 6 }}>注意：</span>{region.warning}
            </div>
          )}

          <div style={{ marginTop: 10 }}>
            <Tags items={region.tags} />
          </div>

          <div className="region-detail-proscons" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginTop: 12 }}>
            <div>
              <div className="mono-hand muted" style={{ fontSize: 11 }}>+ 优点</div>
              <ul style={{ margin: '4px 0', paddingLeft: 18, fontSize: 13 }}>
                {region.pros.map(p => <li key={p}>{p}</li>)}
              </ul>
            </div>
            <div>
              <div className="mono-hand muted" style={{ fontSize: 11 }}>− 注意</div>
              <ul style={{ margin: '4px 0', paddingLeft: 18, fontSize: 13 }}>
                {region.cons.map(p => <li key={p}>{p}</li>)}
              </ul>
            </div>
          </div>

          <hr className="hr-hand" />

          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div className="muted" style={{ fontSize: 12 }}>{currentFriend} 打分</div>
              <StarRow value={myScore} onChange={setMyScore} />
            </div>
            <div style={{ textAlign: 'right' }}>
              <div className="muted" style={{ fontSize: 12 }}>团队平均</div>
              <div style={{ fontSize: 18, fontWeight: 700 }}>
                {avgScore(rVotes).toFixed(1)} <span className="muted" style={{ fontSize: 12 }}>/5</span>
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// -------- 出发返程时段 & 订房 tips --------
function TipsCard() {
  const t = window.DEPART_TIPS;
  return (
    <div className="paper-card" style={{ maxWidth: 320 }}>
      <div className="title-hand" style={{ fontSize: 20 }}>🚗 出发 & 返程</div>
      <div style={{ fontSize: 13, marginTop: 6 }}>
        <div><b>最佳出发：</b></div>
        <ul style={{ margin: '2px 0', paddingLeft: 18 }}>
          {t.best_out.map(x => <li key={x}><span className="highlight-green">{x}</span></li>)}
        </ul>
        <div style={{ marginTop: 4 }}><b>次优出发：</b> {t.second_out.join(' / ')}</div>
        <div style={{ marginTop: 6 }}><b>返程首选：</b></div>
        <ul style={{ margin: '2px 0', paddingLeft: 18 }}>
          {t.best_back.map(x => <li key={x}><span className="highlight">{x}</span></li>)}
        </ul>
      </div>
      <hr className="hr-hand" />
      <div className="title-hand" style={{ fontSize: 20 }}>🛏️ 订房策略</div>
      <ul style={{ margin: '4px 0', paddingLeft: 18, fontSize: 13 }}>
        {window.BOOKING_TIPS.map((x,i) => <li key={i}>{x}</li>)}
      </ul>
    </div>
  );
}

// -------- 行程模板 --------
function TripTemplates() {
  const { twoDay, threeDay } = window.TRIP_TEMPLATES;
  const [tab, setTab] = useState('2');
  const active = tab === '2' ? twoDay : threeDay;
  return (
    <div className="paper-card">
      <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
        <button className={'btn-hand sm ' + (tab==='2'?'active':'')} onClick={() => setTab('2')}>2 天 1 夜</button>
        <button className={'btn-hand sm ' + (tab==='3'?'active':'')} onClick={() => setTab('3')}>3 天 2 夜</button>
      </div>
      <div className="title-hand" style={{ fontSize: 18 }}>{active.title}</div>
      <div className="muted" style={{ fontSize: 12, marginBottom: 6 }}>适合：{active.best_for.join(' / ')}</div>
      <div style={{ display: 'grid', gridTemplateColumns: '110px 1fr', rowGap: 5, fontSize: 13 }}>
        {active.schedule.map((s, i) => (
          <React.Fragment key={i}>
            <div className="mono-hand soft">{s.day}</div>
            <div>{s.what}</div>
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

// -------- 朋友管理 --------
function FriendBar({ friends, setFriends, currentFriend, setCurrentFriend }) {
  const add = () => {
    const name = prompt('朋友的名字？');
    if (name && !friends.includes(name)) setFriends([...friends, name]);
  };
  return (
    <div style={{ display: 'flex', gap: 6, alignItems: 'center', flexWrap: 'wrap' }}>
      <span className="muted mono-hand" style={{ fontSize: 12 }}>你是：</span>
      {friends.map(f => (
        <button
          key={f}
          className={'btn-hand sm ' + (f === currentFriend ? 'active' : '')}
          onClick={() => setCurrentFriend(f)}
        >{f}</button>
      ))}
      <button className="btn-hand sm" onClick={add}>+ 加朋友</button>
    </div>
  );
}

// -------- 过滤器 --------
function FilterBar({ filters, setFilters }) {
  const toggle = (key, val) => {
    const cur = filters[key] || [];
    setFilters({
      ...filters,
      [key]: cur.includes(val) ? cur.filter(x => x !== val) : [...cur, val]
    });
  };
  const isOn = (key, val) => (filters[key] || []).includes(val);
  const driveOpts = [['under2', '<2h'], ['2to3', '2-3h'], ['3to4', '3-4h'], ['over4', '4h+']];
  const tierOpts = [['top', '最值得'], ['good', '可以去'], ['avoid', '踩雷热区']];
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center' }}>
      <span className="muted mono-hand" style={{ fontSize: 12 }}>车程：</span>
      {driveOpts.map(([k,l]) => (
        <button key={k} className={'btn-hand sm ' + (isOn('drive',k)?'active':'')}
          onClick={() => toggle('drive', k)}>{l}</button>
      ))}
      <span className="muted mono-hand" style={{ fontSize: 12, marginLeft: 8 }}>推荐度：</span>
      {tierOpts.map(([k,l]) => (
        <button key={k} className={'btn-hand sm ' + (isOn('tier',k)?'active':'')}
          onClick={() => toggle('tier', k)}>{l}</button>
      ))}
    </div>
  );
}

function passesFilter(r, filters) {
  const d = filters.drive || [];
  const t = filters.tier || [];
  if (t.length && !t.includes(r.tier)) return false;
  if (d.length) {
    const h = parseFloat(r.drive);
    const bucket =
      h < 2 ? 'under2' :
      h < 3 ? '2to3' :
      h < 4 ? '3to4' : 'over4';
    if (!d.includes(bucket)) return false;
  }
  return true;
}

// 默认排序：按 tier 再按车程
function sortRegions(regions, mode) {
  const arr = [...regions];
  if (mode === 'sparse') arr.sort((a,b) => (a.rankSparse||99) - (b.rankSparse||99));
  else if (mode === 'drive') arr.sort((a,b) => (a.rankDrive||99) - (b.rankDrive||99));
  else if (mode === 'worth') arr.sort((a,b) => (a.rankWorth||99) - (b.rankWorth||99));
  else arr.sort((a,b) => {
    const tierOrder = { top: 0, good: 1, avoid: 2 };
    if (tierOrder[a.tier] !== tierOrder[b.tier]) return tierOrder[a.tier] - tierOrder[b.tier];
    return parseFloat(a.drive) - parseFloat(b.drive);
  });
  return arr;
}

Object.assign(window, {
  useLocalStorage, useVotes, useFriends, avgScore,
  StarRow, CrowdMeter, TierBadge, Tags,
  RegionDetail, TipsCard, TripTemplates, FriendBar, FilterBar,
  passesFilter, sortRegions
});
