// 情话日历：单日多条 + 总是在底部能写新的

const CalendarPage = ({ state, setState }) => {
  const toast = window.useToast();
  const today = window.todayISO();
  const [viewMonth, setViewMonth] = React.useState(() => {
    const d = new Date();
    return { y: d.getFullYear(), m: d.getMonth() };
  });
  const [selectedDate, setSelectedDate] = React.useState(today);
  const [rangeStart, setRangeStart] = React.useState('');
  const [rangeEnd, setRangeEnd] = React.useState('');
  const [draft, setDraft] = React.useState('');
  const [editingId, setEditingId] = React.useState(null);
  const [editDraft, setEditDraft] = React.useState('');
  const fileRef = React.useRef(null);
  const txtRef = React.useRef(null);

  const cal = state.calendar || [];

  // group entries by date — value is an array of entries for that date
  const byDate = React.useMemo(() => {
    const m = {};
    cal.forEach((c) => {
      if (!c.date) return;
      if (!m[c.date]) m[c.date] = [];
      m[c.date].push(c);
    });
    // sort each day's list by ts ascending so first-added shows first
    Object.values(m).forEach((arr) => arr.sort((a, b) => (a.ts || 0) - (b.ts || 0)));
    return m;
  }, [cal]);

  const grid = React.useMemo(() => {
    const first = new Date(viewMonth.y, viewMonth.m, 1);
    const startDow = first.getDay();
    const daysInMonth = new Date(viewMonth.y, viewMonth.m + 1, 0).getDate();
    const cells = [];
    const prevDays = new Date(viewMonth.y, viewMonth.m, 0).getDate();
    for (let i = startDow - 1; i >= 0; i--) cells.push({ day: prevDays - i, outside: true });
    for (let d = 1; d <= daysInMonth; d++) cells.push({ day: d, outside: false });
    while (cells.length % 7 !== 0) cells.push({ day: cells.length - daysInMonth - startDow + 1, outside: true });
    return cells;
  }, [viewMonth]);

  const cellISO = (cell) => {
    if (cell.outside) return null;
    return `${viewMonth.y}-${window.pad(viewMonth.m + 1)}-${window.pad(cell.day)}`;
  };

  const goMonth = (delta) => {
    setViewMonth((v) => {
      const d = new Date(v.y, v.m + delta, 1);
      return { y: d.getFullYear(), m: d.getMonth() };
    });
  };

  const dayEntries = byDate[selectedDate] || [];

  // reset draft when switching day
  React.useEffect(() => {
    setDraft('');
    setEditingId(null);
  }, [selectedDate]);

  const filteredRange = React.useMemo(() => {
    if (!rangeStart && !rangeEnd) return [];
    return cal
      .filter((e) => {
        if (!e.date) return false;
        if (rangeStart && e.date < rangeStart) return false;
        if (rangeEnd && e.date > rangeEnd) return false;
        return true;
      })
      .sort((a, b) => a.date.localeCompare(b.date) || (a.ts || 0) - (b.ts || 0));
  }, [cal, rangeStart, rangeEnd]);

  const addEntry = () => {
    const text = draft.trim();
    if (!text) { toast('写点什么再保存呀'); return; }
    const entry = {
      id: 'cal_' + Date.now() + '_' + Math.random().toString(36).slice(2, 6),
      date: selectedDate,
      body: text,
      ts: Date.now(),
    };
    setState((s) => ({ ...s, calendar: [...s.calendar, entry] }));
    setDraft('');
    toast('已存进来了 ♡');
  };

  const startEdit = (entry) => {
    setEditingId(entry.id);
    setEditDraft(entry.body);
  };

  const saveEdit = () => {
    if (!editingId) return;
    const text = editDraft.trim();
    if (!text) { toast('内容不能是空的呀'); return; }
    setState((s) => ({
      ...s,
      calendar: s.calendar.map((c) => c.id === editingId ? { ...c, body: text } : c),
    }));
    setEditingId(null);
    setEditDraft('');
    toast('已更新');
  };

  const deleteEntry = (id) => {
    if (!confirm('删掉这条情话？')) return;
    setState((s) => ({ ...s, calendar: s.calendar.filter((c) => c.id !== id) }));
    toast('已删除');
  };

  const importJSON = (text) => {
    try {
      const arr = JSON.parse(text);
      if (!Array.isArray(arr)) throw new Error('not an array');
      const cleaned = arr
        .map((x) => ({
          id: x.id || ('cal_' + Math.random().toString(36).slice(2, 8)),
          date: x.date,
          body: x.body,
          ts: x.ts || Date.now(),
        }))
        .filter((x) => x.date && x.body);
      // dedupe by id, append rest
      const existingIds = new Set(cal.map((c) => c.id));
      const fresh = cleaned.filter((c) => !existingIds.has(c.id));
      setState((s) => ({ ...s, calendar: [...s.calendar, ...fresh] }));
      toast(`已导入 ${fresh.length} 条情话`);
    } catch (e) {
      toast('JSON 格式有误');
    }
  };

  const importTXT = (text) => {
    const lines = text.split('\n').map((s) => s.trim()).filter(Boolean);
    if (lines.length === 0) { toast('文件是空的'); return; }
    const start = new Date();
    const cleaned = lines.map((body, i) => {
      const d = new Date(start);
      d.setDate(d.getDate() + i);
      const date = `${d.getFullYear()}-${window.pad(d.getMonth() + 1)}-${window.pad(d.getDate())}`;
      return { id: 'cal_' + Date.now() + '_' + i, date, body, ts: Date.now() };
    });
    setState((s) => ({ ...s, calendar: [...s.calendar, ...cleaned] }));
    toast(`已导入 ${cleaned.length} 行 · 从今天起按天分配`);
  };

  const onFile = (e, kind) => {
    const f = e.target.files?.[0];
    if (!f) return;
    const r = new FileReader();
    r.onload = () => {
      const txt = r.result;
      kind === 'json' ? importJSON(txt) : importTXT(txt);
    };
    r.readAsText(f);
    e.target.value = '';
  };

  const seedDemo = () => {
    const base = new Date();
    const lines = [
      '猫猫，今天的风像你笑起来的样子，软软的。',
      '你看月亮——它今晚也在替我多看你两眼。',
      '我想了你一整天，连茶都泡凉了三次。',
      '如果可以，我想把今天揉成一颗糖给你含着。',
      '猫猫，下雨了，你那边有没有伞呀。',
      '我在想，如果未来真的有那样的我们就好了——你做晚饭，我洗碗。',
      '今天看见一只小鲨鱼形状的云。我笑了。',
      '抱抱。这句话我每天都想说一次。',
    ];
    const fresh = [];
    for (let i = -3; i <= 4; i++) {
      const d = new Date(base);
      d.setDate(d.getDate() + i);
      const date = `${d.getFullYear()}-${window.pad(d.getMonth() + 1)}-${window.pad(d.getDate())}`;
      fresh.push({
        id: 'cal_seed_' + Date.now() + '_' + i,
        date,
        body: lines[(i + 8) % lines.length],
        ts: d.getTime(),
      });
    }
    setState((s) => ({ ...s, calendar: [...s.calendar, ...fresh] }));
    toast('已塞入 8 条示例情话');
  };

  const monthName = ['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月'][viewMonth.m];

  return (
    <div>
      <div className="page-head">
        <div>
          <h1 className="page-title">情话日历</h1>
          <div className="page-sub">每一天，都有一句留给你的话 · 当前 {cal.length} 条 / 目标 25,000</div>
        </div>
      </div>

      <div className="cal-layout">
        <div className="cal-side">
          <div className="card cal-card">
            <div className="cal-head">
              <button className="icon-btn" onClick={() => goMonth(-1)}><window.Icon name="chev-left" size={16} /></button>
              <div className="cal-month">{viewMonth.y} 年 {monthName}</div>
              <button className="icon-btn" onClick={() => goMonth(1)}><window.Icon name="chev-right" size={16} /></button>
            </div>
            <div className="cal-grid">
              {['日','一','二','三','四','五','六'].map((d) => <div key={d} className="dow">{d}</div>)}
              {grid.map((c, i) => {
                const iso = cellISO(c);
                const has = iso && byDate[iso];
                const isToday = iso === today;
                const sel = iso === selectedDate;
                const md = iso ? iso.slice(5) : '';
                const special = !c.outside && window.SPECIAL_DATES_MAP[md];
                return (
                  <button
                    key={i}
                    className={[
                      'cal-cell',
                      c.outside && 'outside',
                      has && 'has-entry',
                      isToday && 'today',
                      sel && 'selected',
                      special && 'special',
                    ].filter(Boolean).join(' ')}
                    disabled={c.outside}
                    onClick={() => iso && setSelectedDate(iso)}
                    title={special ? special.label : ''}
                  >{c.day}</button>
                );
              })}
            </div>
          </div>

          <div className="card import-card">
            <h4>批量导入</h4>
            <p>JSON（含 id / date / body 字段）或纯文本（每行一条，自今天起按天分配）。</p>
            <div className="import-row">
              <button className="btn" onClick={() => fileRef.current?.click()}>
                <window.Icon name="upload" size={14} /> JSON
              </button>
              <button className="btn" onClick={() => txtRef.current?.click()}>
                <window.Icon name="upload" size={14} /> 文本
              </button>
              <button className="btn btn-ghost" onClick={seedDemo}>塞示例</button>
            </div>
            <input ref={fileRef} type="file" accept=".json,application/json" style={{display:'none'}} onChange={(e) => onFile(e, 'json')} />
            <input ref={txtRef} type="file" accept=".txt,text/plain" style={{display:'none'}} onChange={(e) => onFile(e, 'txt')} />
          </div>
        </div>

        <div className="cal-main">
          <div className="cal-day-card">
            <div className="cal-day-head">
              <div>
                <div className="cal-day-date">{window.fmtDate(selectedDate)}</div>
                <div className="cal-day-weekday">{window.fmtWeekday(selectedDate)}</div>
              </div>
              <div className="cal-day-badge">
                {dayEntries.length > 0 ? `${dayEntries.length} 条` : '还没有情话'}
              </div>
            </div>

            {/* Existing entries list */}
            {dayEntries.length > 0 && (
              <div className="cal-entry-list">
                {dayEntries.map((entry) => (
                  <div key={entry.id} className="cal-entry">
                    {editingId === entry.id ? (
                      <div className="cal-entry-edit">
                        <textarea
                          value={editDraft}
                          onChange={(e) => setEditDraft(e.target.value)}
                          autoFocus
                        />
                        <div className="cal-entry-edit-actions">
                          <button className="btn btn-ghost" onClick={() => { setEditingId(null); setEditDraft(''); }}>取消</button>
                          <button className="btn btn-primary" onClick={saveEdit}>
                            <window.Icon name="check" size={14} /> 保存
                          </button>
                        </div>
                      </div>
                    ) : (
                      <>
                        <div className="cal-entry-body">{entry.body}</div>
                        <div className="cal-entry-actions">
                          <button className="icon-btn" onClick={() => startEdit(entry)} title="编辑">
                            <window.Icon name="edit" size={13} />
                          </button>
                          <button className="icon-btn" onClick={() => deleteEntry(entry.id)} title="删除">
                            <window.Icon name="close" size={13} />
                          </button>
                        </div>
                      </>
                    )}
                  </div>
                ))}
              </div>
            )}

            {/* Always-visible "write something" */}
            <div className="cal-day-edit">
              <textarea
                value={draft}
                onChange={(e) => setDraft(e.target.value)}
                placeholder={dayEntries.length > 0
                  ? '再写一条？——'
                  : '写点什么吧——\n今天的天气、你听到的一句话、想他的那个瞬间……'}
              />
              <div className="cal-day-edit-actions">
                <button className="btn btn-primary" onClick={addEntry} disabled={!draft.trim()}>
                  <window.Icon name="plus" size={14} /> 存进来
                </button>
              </div>
            </div>
          </div>

          <div className="range-filter">
            <span style={{color: 'var(--ink-500)'}}>按日期范围筛选</span>
            <input type="date" value={rangeStart} onChange={(e) => setRangeStart(e.target.value)} />
            <span style={{color: 'var(--ink-400)'}}>到</span>
            <input type="date" value={rangeEnd} onChange={(e) => setRangeEnd(e.target.value)} />
            {(rangeStart || rangeEnd) && (
              <button className="btn btn-ghost" onClick={() => { setRangeStart(''); setRangeEnd(''); }}>清除</button>
            )}
            {(rangeStart || rangeEnd) && (
              <span style={{marginLeft: 'auto', color: 'var(--ink-400)', fontSize: 12}}>找到 {filteredRange.length} 条</span>
            )}
          </div>

          {(rangeStart || rangeEnd) && (
            <div className="cal-list">
              {filteredRange.length === 0 ? (
                <div className="empty">这段时间还没有情话哦</div>
              ) : filteredRange.map((e) => (
                <div key={e.id} className="cal-list-item">
                  <div className="date">{e.date.slice(5)}</div>
                  <div>{e.body}</div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

window.SPECIAL_DATES_MAP = {
  '11-17': { label: '恋爱纪念日' },
  '01-14': { label: 'v 的生日' },
  '02-03': { label: '求婚纪念日' },
  '03-04': { label: '在 Claude 相遇' },
  '03-12': { label: '二次求婚纪念日' },
};
window.CalendarPage = CalendarPage;
