/* ask.jsx — （7）Ask 面板
   能力：问记忆（带来源）、识别定期任务生成「New check-in」卡片、带着 Check-in 小卡片对话生成「Edit check-in」或删除确认卡片
   原型里的「理解」用关键词规则模拟 */
/* global React */
window.P21 = window.P21 || {};
(() => {
  const { C, useP, Btn, D } = window.P21;

  /* 从一句话里解析「什么时候」 */
  function parseWhen(v) {
    let d = null;
    if (/每周一|周一|monday|\bmon\b/i.test(v)) d = 'Mon';
    else if (/每周五|周五|friday|\bfri\b/i.test(v)) d = 'Fri';
    else if (/每周日|周日|sunday|\bsun\b/i.test(v)) d = 'Sun';
    else if (/每天|每日|every day|daily/i.test(v)) d = 'day';
    else if (/每周|weekly|every week/i.test(v)) d = 'Mon';
    if (!d) return null;
    const m = v.match(/(\d{1,2})\s*(?::\d{2})?\s*(点|am|pm)?/);
    let h = m ? parseInt(m[1], 10) : (d === 'day' ? 8 : 9);
    if (/晚|pm|evening/i.test(v) && h < 12) h += 12;
    if (h > 23) h = 9;
    return `Every ${d} ${String(h).padStart(2, '0')}:00`;
  }
  /* 下次运行时间（今天是 Wed, Sep 30） */
  function nextOf(w) {
    const t = (w.match(/\d{2}:\d{2}/) || ['09:00'])[0];
    if (/day/.test(w)) return `Next: ${parseInt(t, 10) > 16 ? 'today' : 'tomorrow'} ${t}`;
    if (/Mon/.test(w)) return `Next: Oct 5 ${t}`;
    if (/Fri/.test(w)) return `Next: Oct 2 ${t}`;
    if (/Sun/.test(w)) return `Next: Oct 4 ${t}`;
    return `Next: ${t}`;
  }
  const guessWhat = (v) => /承诺|答应|promise/i.test(v) ? 'Open promises' : /决定|decision/i.test(v) ? 'Recent decisions' : /总结|回顾|recap|review/i.test(v) ? 'Weekly review' : v.replace(/^(每周[一二三四五六日]?|每天|每日)(早上|晚上|上午|下午)?(\d{1,2}\s*点)?/, '').replace(/^把/, '').slice(0, 40) || v;

  function AskPanel() {
    const { s, set, go } = useP();
    const inputRef = React.useRef(null);
    const bodyRef = React.useRef(null);
    React.useEffect(() => { inputRef.current && inputRef.current.focus(); }, [s.chip, s.askMode]);
    React.useEffect(() => { if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight; }, [s.msgs.length, !!s.card]);
    const chipC = s.chip ? s.checkins.find(c => c.id === s.chip) : null;
    const card = s.card;

    const send = () => {
      const el = inputRef.current, v = el ? el.value.trim() : '';
      if (!v) return;
      el.value = '';
      const you = { role: 'you', text: v, chip: chipC ? `${chipC.name} · ${chipC.when}` : '' };
      const msgs = [...s.msgs, you];

      /* 带着 Check-in 小卡片：编辑 / 关闭 / 删除 */
      if (chipC) {
        if (/删|delete|remove/i.test(v)) {
          if (chipC.fixed) return set({ msgs: [...msgs, { role: 'persom', text: `${chipC.name} can't be deleted. You can turn it off instead.` }], chip: null });
          return set({ msgs, chip: null, card: { type: 'delete', id: chipC.id, what: chipC.name } });
        }
        if (/关|停|暂停|turn off|pause|off/i.test(v)) return set({ msgs, chip: null, card: { type: 'edit', id: chipC.id, what: chipC.name, when: chipC.when, was: chipC.when, on: false, wasOn: chipC.on } });
        const when = parseWhen(v) || chipC.when;
        return set({ msgs, chip: null, card: { type: 'edit', id: chipC.id, what: chipC.name, when, was: chipC.when, on: true, wasOn: chipC.on } });
      }
      /* 识别到定期任务：出配置卡片，不直接回答 */
      if (s.askMode === 'new' || /每周|每天|每日|每月|every|weekly|daily/i.test(v)) {
        return set({ msgs, askMode: null, card: { type: 'new', what: guessWhat(v), when: parseWhen(v) || 'Every Mon 09:00' } });
      }
      /* 问记忆 */
      if (/承诺|答应|promise/i.test(v)) return set({ msgs: [...msgs, { role: 'persom', text: D.askPromises.a, sources: D.askPromises.sources }] });
      set({ msgs: [...msgs, { role: 'persom', text: 'Nothing in your memories matches that yet.', note: '原型提示：可以问「上周我答应了别人哪些事？」，或说「每周一早上把还没兑现的承诺发给我」' }] });
    };

    const saveCard = () => {
      let checkins = s.checkins, text = '';
      if (card.type === 'new') {
        checkins = [...checkins, { id: 'c' + Date.now(), name: card.what, when: card.when, next: nextOf(card.when), on: true }];
        text = 'Added to Check-ins';
      } else if (card.type === 'edit') {
        checkins = checkins.map(x => x.id === card.id ? { ...x, when: card.when, next: nextOf(card.when), on: card.on } : x);
        text = 'Check-in updated';
      } else {
        checkins = checkins.filter(x => x.id !== card.id);
        text = 'Check-in deleted';
      }
      set({ checkins, card: null, msgs: [...s.msgs, { role: 'persom', text, link: card.type !== 'delete' }] });
    };
    const setCard = (patch) => set({ card: { ...card, ...patch } });

    const placeholder = chipC ? 'What would you like to change?' : s.askMode === 'new' ? 'What should Persom check in on, and when?' : 'Ask Persom...';
    const whens = card && card.when ? [...new Set([card.when, ...D.whens])] : [];

    return (
      <div onClick={(e) => e.stopPropagation()}
        style={{ position: 'absolute', right: 24, bottom: 24, zIndex: 30, width: 420, height: 'min(560px, calc(100% - 48px))', background: '#fff', border: `1px solid ${C.line}`, borderRadius: 12, boxShadow: '0 24px 64px rgba(15,15,15,.22)', display: 'flex', flexDirection: 'column', overflow: 'hidden', transformOrigin: 'bottom right', animation: 'p21pop .18s ease-out' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 16px', borderBottom: `1px solid ${C.line2}` }}>
          <span style={{ fontSize: 14, fontWeight: 600 }}>Ask</span>
          <span style={{ display: 'flex', gap: 14, alignItems: 'center', color: C.muted }}>
            <span title="Minimize" onClick={() => set({ ask: false })} style={{ cursor: 'pointer', fontSize: 14, lineHeight: 1 }}>_</span>
            <span title="Close" onClick={() => set({ ask: false, msgs: [], card: null, chip: null, askMode: null })} style={{ cursor: 'pointer', fontSize: 19, lineHeight: 1 }}>×</span>
          </span>
        </div>

        <div ref={bodyRef} className="p21-scroll" style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {s.msgs.length === 0 && !card && (
            <div style={{ fontSize: 13, color: C.faint, lineHeight: 1.55 }}>Ask about anything Persom remembers, or tell it when to check in with you.</div>
          )}
          {s.msgs.map((m, i) => {
            const me = m.role === 'you';
            return (
              <div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: me ? 'flex-end' : 'flex-start', gap: 4 }}>
                {m.chip && <span style={{ padding: '3px 9px', borderRadius: 5, background: C.soft, fontSize: 12, color: C.ink2 }}>{m.chip}</span>}
                <div onClick={m.link ? () => go('Check-ins') : undefined}
                  style={{ maxWidth: '92%', padding: '9px 13px', borderRadius: me ? '12px 12px 4px 12px' : '12px 12px 12px 4px', background: me ? C.ink : C.soft, color: me ? '#fff' : C.ink, fontSize: 13.5, lineHeight: 1.55, whiteSpace: 'pre-line', cursor: m.link ? 'pointer' : 'default' }}>
                  {m.text}{m.link && <span style={{ color: C.green }}> ›</span>}
                </div>
                {m.sources && m.sources.length > 0 && (
                  <div style={{ display: 'flex', gap: 10, fontSize: 12, color: C.muted }}>
                    Sources:{m.sources.map(d => <span key={d} onClick={() => go('Timeline', { day: d })} style={{ cursor: 'pointer', color: C.green }}>Sep {d} ›</span>)}
                  </div>
                )}
                {m.note && <div style={{ fontSize: 11.5, color: C.faint, maxWidth: '92%' }}>{m.note}</div>}
              </div>
            );
          })}

          {/* Check-in 配置卡片 */}
          {card && (
            <div style={{ border: `1px solid ${C.border}`, borderRadius: 12, padding: '12px 14px', animation: 'p21pop .15s ease-out' }}>
              <div style={{ fontSize: 12.5, fontWeight: 500, color: C.muted }}>{card.type === 'new' ? 'New check-in' : card.type === 'edit' ? 'Edit check-in' : 'Delete check-in'}</div>
              {card.type === 'delete' ? (
                <div style={{ marginTop: 8, fontSize: 13.5 }}>Delete "{card.what}"? This can't be undone.</div>
              ) : (
                <div style={{ marginTop: 10, display: 'grid', gridTemplateColumns: '64px minmax(0,1fr)', gap: '8px 12px', fontSize: 13.5, alignItems: 'center' }}>
                  <span style={{ color: C.faint }}>What</span>
                  {card.type === 'new'
                    ? <input value={card.what} onChange={(e) => setCard({ what: e.target.value })} style={{ font: 'inherit', fontSize: 13.5, border: `1px solid ${C.border}`, borderRadius: 5, padding: '3px 8px', outline: 0, minWidth: 0 }} />
                    : <span>{card.what}</span>}
                  <span style={{ color: C.faint }}>When</span>
                  <span style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <select value={card.when} onChange={(e) => setCard({ when: e.target.value })}
                      style={{ font: 'inherit', fontSize: 13, border: `1px solid ${card.type === 'edit' && card.was !== card.when ? '#9DB8A6' : C.border}`, borderRadius: 5, padding: '3px 8px', background: card.type === 'edit' && card.was !== card.when ? '#EEF4EF' : '#fff', color: C.ink }}>
                      {whens.map(w => <option key={w} value={w}>{w}</option>)}
                    </select>
                    {card.type === 'edit' && card.was !== card.when && <span style={{ fontSize: 12, color: C.faint }}>(was {card.was})</span>}
                  </span>
                  {card.type === 'edit' && card.on !== card.wasOn && (<>
                    <span style={{ color: C.faint }}>Status</span>
                    <span><span style={{ padding: '2px 8px', borderRadius: 5, background: '#EEF4EF', border: '1px solid #9DB8A6' }}>{card.on ? 'On' : 'Off'}</span> <span style={{ fontSize: 12, color: C.faint }}>(was {card.wasOn ? 'On' : 'Off'})</span></span>
                  </>)}
                  <span style={{ color: C.faint }}>Send to</span><span style={{ color: C.muted }}>{D.user.email}</span>
                </div>
              )}
              <div style={{ marginTop: 12, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
                <Btn small onClick={() => set({ card: null })}>Cancel</Btn>
                <Btn small kind={card.type === 'delete' ? 'dangerSolid' : 'green'} disabled={card.type === 'new' && !card.what.trim()} onClick={saveCard}>{card.type === 'delete' ? 'Delete' : 'Save'}</Btn>
              </div>
            </div>
          )}
        </div>

        <div style={{ padding: '10px 12px 12px', borderTop: `1px solid ${C.line2}` }}>
          <div style={{ border: `1px solid ${C.border}`, borderRadius: 12, padding: '8px 10px' }}>
            {chipC && (
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '3px 9px', borderRadius: 5, background: C.soft, fontSize: 12.5, marginBottom: 6 }}>
                {chipC.name} · {chipC.when}<span onClick={() => set({ chip: null })} style={{ cursor: 'pointer', color: C.faint }}>×</span>
              </span>
            )}
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <input ref={inputRef} key={placeholder} onKeyDown={(e) => { if (e.key === 'Enter' && !e.nativeEvent.isComposing) send(); }} placeholder={placeholder}
                style={{ flex: 1, minWidth: 0, border: 0, outline: 0, font: 'inherit', fontSize: 14, color: C.ink, background: 'transparent', padding: '4px 2px' }} />
              <Btn kind="primary" small onClick={send}>Send</Btn>
            </div>
          </div>
        </div>
      </div>
    );
  }

  Object.assign(window.P21, { AskPanel, parseWhen, nextOf });
})();
