// Records.jsx — phone login + 预约记录 (booking history), localStorage-backed.

const PHONE_KEY = 'museum_last_phone_v1';

function genCode() { return 'YCM-' + Math.random().toString(36).slice(2, 8).toUpperCase(); }
function digits(p) { return (p || '').replace(/\D/g, ''); }
function fmtPhone(p) {
  const d = digits(p);
  const a = d.slice(0, 3), b = d.slice(3, 7), c = d.slice(7, 11);
  return [a, b, c].filter(Boolean).join(' ');
}
function addRecord(rec) { if (rec.phone) localStorage.setItem(PHONE_KEY, digits(rec.phone)); }
function lastPhone() { return localStorage.getItem(PHONE_KEY) || ''; }

// ── local icons ──
const R_ICONS = {
  phone: <path d="M13.5 2a2 2 0 0 1 2 1.7l.3 1.8a2 2 0 0 1-.5 1.7l-1 1a11 11 0 0 0 4.5 4.5l1-1a2 2 0 0 1 1.7-.5l1.8.3a2 2 0 0 1 1.7 2V18a2 2 0 0 1-2 2A16 16 0 0 1 4 5a2 2 0 0 1 2-2Z" />,
  'log-out': <g><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><path d="M16 17l5-5-5-5M21 12H9" /></g>,
  inbox: <g><path d="M22 12h-6l-2 3h-4l-2-3H2" /><path d="M5.5 5.5 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.5-6.5A2 2 0 0 0 16.8 4H7.2a2 2 0 0 0-1.7 1.5Z" /></g>,
  users: <g><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M22 21v-2a4 4 0 0 0-3-3.87" /><path d="M16 3.13a4 4 0 0 1 0 7.75" /></g>,
};
function RIcon({ name, size = 20, color = 'currentColor', strokeWidth = 1.5, style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color}
      strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'inline-block', verticalAlign: 'middle', flex: 'none', ...style }}>
      {R_ICONS[name]}
    </svg>
  );
}

// ── Phone field (shared) ──
function PhoneField({ value, onChange, autoFocus, label }) {
  const [focus, setFocus] = React.useState(false);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {label && <label style={{ fontSize: 13, fontWeight: 500, color: 'var(--fg-1)' }}>{label}</label>}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, background: '#fff',
        border: `1px solid ${focus ? 'var(--action)' : 'var(--border-1)'}`,
        boxShadow: focus ? '0 0 0 2px var(--action-ring)' : 'none',
        borderRadius: 12, padding: '0 14px', height: 50,
        transition: 'all var(--dur-fast) var(--ease-out)',
      }}>
        <RIcon name="phone" size={18} color="var(--brass-500)" />
        <input
          value={fmtPhone(value)}
          onChange={e => onChange(digits(e.target.value).slice(0, 11))}
          onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
          autoFocus={autoFocus} inputMode="numeric" placeholder="手机号码"
          style={{
            flex: 1, border: 'none', outline: 'none', background: 'transparent',
            fontFamily: 'var(--font-mono)', fontSize: 15, letterSpacing: '.04em',
            color: 'var(--fg-1)', minWidth: 0,
          }}
        />
      </div>
    </div>
  );
}

// ── Login (enter phone to view records) ──
function LoginScreen({ onBack, onAuthed }) {
  const [phone, setPhone] = React.useState(lastPhone());
  const valid = digits(phone).length === 11;
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <AppHeader title="预约记录"
        leading={<button onClick={onBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, color: '#fff', display: 'flex' }}><Icon name="chevron-left" size={22} color="#fff" /></button>} />
      <div style={{ flex: 1, overflowY: 'auto', padding: '20px 20px 24px', display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', padding: '14px 0 6px' }}>
          <div style={{ width: 64, height: 64, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundImage: 'linear-gradient(135deg, #0C7164 0%, #3A9A8C 100%)', boxShadow: '0 8px 20px rgba(12,113,100,0.28)' }}>
            <Icon name="user-round" size={30} color="#fff" />
          </div>
          <h1 style={{ margin: '16px 0 0', fontFamily: 'var(--font-sans)', fontWeight: 600, fontSize: 25, color: 'var(--fg-1)' }}>查看我的预约</h1>
          <p style={{ margin: '8px 0 0', fontSize: 14, color: 'var(--fg-2)', lineHeight: 1.55, maxWidth: 280 }}>输入预约时填写的手机号，即可查看预约记录与状态。</p>
        </div>
        <div style={{ marginTop: 24, display: 'flex', flexDirection: 'column', gap: 14 }}>
          <PhoneField value={phone} onChange={setPhone} autoFocus label="手机号" />
          <Button variant="primary" size="lg" full disabled={!valid} onClick={() => { localStorage.setItem(PHONE_KEY, digits(phone)); onAuthed(digits(phone)); }}>查看预约记录</Button>
        </div>
      </div>
    </div>
  );
}

// ── Records list ──
function RecordCard({ r, onCancel }) {
  const range = r.range || (r.slot && r.slot.range) || '';
  const period = r.period || (r.slot && r.slot.period) || '';
  const isCancelled = r.status === '已取消';
  return (
    <div style={{
      background: '#fff', border: '1px solid var(--border-1)', borderRadius: 14, padding: 12,
      display: 'flex', flexDirection: 'column', gap: 8,
      opacity: isCancelled ? 0.6 : 1,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          {!isCancelled && <Pill kind="external">已预约</Pill>}
          {isCancelled && <Pill kind="secondary">已取消</Pill>}
        </div>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg-3)' }}>{r.code}</span>
      </div>
      <div style={{ fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 16, lineHeight: 1.25, color: 'var(--fg-1)', fontVariationSettings: '"opsz" 36' }}>{r.title}</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, color: 'var(--fg-2)' }}>
          <Icon name="calendar" size={13} color="var(--brass-500)" /><span>{r.dateLabel}</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, color: 'var(--fg-2)' }}>
          <Icon name="clock" size={13} color="var(--brass-500)" />
          <span style={{ fontFamily: 'var(--font-mono)', fontVariantNumeric: 'tabular-nums' }}>{range}</span>
          <span style={{ color: 'var(--fg-4)' }}>·</span><span>{period}</span>
          <span style={{ color: 'var(--fg-4)' }}>·</span>
          <RIcon name="users" size={13} color="var(--brass-500)" /><span>{r.party} 人</span>
        </div>
      </div>
      {!isCancelled && (
        <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
          <button
            onClick={() => onCancel && onCancel(r.id)}
            style={{
              fontSize: 12, color: 'var(--danger)', background: 'transparent', border: 'none',
              cursor: 'pointer', padding: '4px 8px', borderRadius: 4,
            }}
          >取消预约</button>
        </div>
      )}
    </div>
  );
}

function RecordsScreen({ phone, onBack, onBook, onSwitch }) {
  const [recs, setRecs] = React.useState([]);
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    async function load() {
      setLoading(true);
      try {
        const res = await fetch(`/api/appointments?phone=${encodeURIComponent(phone)}`);
        const json = await res.json().catch(() => ({}));
        setRecs((json.data || []).map(r => ({
          id: r.id,
          phone: r.phone,
          code: r.code,
          title: r.title,
          dateLabel: r.dateLabel,
          range: r.slotRange,
          period: r.period,
          party: r.party,
          status: r.status,
          createdAt: r.clientCreatedAt || Date.now(),
        })));
      } catch (e) {
        console.error(e);
        setRecs([]);
      }
      setLoading(false);
    }
    load();
  }, [phone]);

  async function handleCancel(id) {
    if (!confirm('确定取消该预约？')) return;
    try {
      const res = await fetch(`/api/appointments/${id}/cancel-by-phone`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ phone }),
      });
      const json = await res.json().catch(() => ({}));
      if (json.success) {
        setRecs(prev => prev.map(r => r.id === id ? { ...r, status: '已取消' } : r));
      } else {
        alert(json.message || '取消失败');
      }
    } catch (e) { alert('取消失败'); }
  }

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <AppHeader title="我的预约"
        leading={<button onClick={onBack} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, color: '#fff', display: 'flex' }}><Icon name="chevron-left" size={22} color="#fff" /></button>}
        trailing={<button onClick={onSwitch} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 2, color: '#fff', display: 'flex' }}><RIcon name="log-out" size={18} color="#fff" /></button>} />
      <div style={{ flex: 1, overflowY: 'auto', padding: '6px 16px 20px' }}>
        {/* logged-in phone */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px', background: 'var(--action-soft)', border: '1px solid var(--action-soft-border)', borderRadius: 14, color: 'var(--fg-1)', marginBottom: 16 }}>
          <div style={{ width: 32, height: 32, borderRadius: '50%', background: '#fff', border: '1px solid var(--action-soft-border)', display: 'flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}><Icon name="user-round" size={18} color="var(--action)" /></div>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--action)' }}>已登录</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 14, letterSpacing: '.04em', marginTop: 2, color: 'var(--fg-1)', whiteSpace: 'nowrap' }}>{fmtPhone(phone)}</div>
          </div>
        </div>

        {loading && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '24px 0', justifyContent: 'center', color: 'var(--fg-3)' }}>
            <span className="spin" style={{ width: 16, height: 16, borderRadius: '50%', border: '2px solid var(--stone-200)', borderTopColor: 'var(--brass-400)', display: 'inline-block' }} />
            <span style={{ fontSize: 13 }}>加载中…</span>
          </div>
        )}

        {!loading && recs.length > 0 && (
          <>
            <SectionHeader>{`共 ${recs.length} 条预约`}</SectionHeader>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {recs.map((r, i) => <RecordCard key={r.code + i} r={r} onCancel={handleCancel} />)}
            </div>
          </>
        )}

        {!loading && recs.length === 0 && (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', padding: '48px 24px' }}>
            <div style={{ width: 56, height: 56, borderRadius: '50%', background: 'var(--bg-muted)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <RIcon name="inbox" size={26} color="var(--fg-3)" />
            </div>
            <div style={{ marginTop: 16, fontFamily: 'var(--font-sans)', fontWeight: 500, fontSize: 17, color: 'var(--fg-1)' }}>暂无预约记录</div>
            <p style={{ margin: '6px 0 16px', fontSize: 12, color: 'var(--fg-2)', lineHeight: 1.55 }}>该手机号下还没有预约。点「立即预约」开始预约讲解。</p>
            <Button variant="primary" size="md" onClick={onBook}>去预约</Button>
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { genCode, addRecord, lastPhone, fmtPhone, digits, PhoneField, LoginScreen, RecordsScreen });
