// checklist.jsx — 行前準備清單

function _checkApi(method, path, body) {
  const opts = { method, headers: { Authorization: `Bearer ${window.tabiToken()}` } };
  if (body) { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); }
  return fetch('/api/checklist' + path, opts).then(r => {
    if (r.status === 204) return null;
    return r.ok ? r.json() : r.json().then(d => Promise.reject(d.detail || '操作失敗'));
  });
}

// ── ChecklistItemDetailSheet ──────────────────────────────────
// Edit or view a single item's details (text, note, image, url)

function ChecklistItemDetailSheet({ item, categories, isNew, onClose, onSaved, onDeleted }) {
  const [text, setText]         = React.useState(item?.text || '');
  const [category, setCategory] = React.useState(item?.category || categories[0] || '其他');
  const [note, setNote]         = React.useState(item?.note || '');
  const [url, setUrl]           = React.useState(item?.url || '');
  const [imgPreview, setImgPreview] = React.useState(item?.image_url || null);
  const [imgFile, setImgFile]   = React.useState(null);
  const [saving, setSaving]     = React.useState(false);
  const [err, setErr]           = React.useState('');
  const fileRef = React.useRef();
  const [lightbox, setLightbox] = React.useState(false);

  const inputStyle = {
    width:'100%', padding:'10px 12px', borderRadius:10, fontSize:16, minHeight:44,
    border:`1px solid ${TABI_COLORS.line}`, background:TABI_COLORS.bg,
    color:TABI_COLORS.ink, outline:'none', fontFamily:'inherit', boxSizing:'border-box',
  };
  const selStyle = {
    ...inputStyle,
    appearance:'none', WebkitAppearance:'none',
    backgroundImage:`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%238D8071' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")`,
    backgroundRepeat:'no-repeat', backgroundPosition:'right 10px center', paddingRight:28, cursor:'pointer',
  };

  function pickImg(e) {
    const f = e.target.files[0];
    if (!f) return;
    setImgFile(f);
    setImgPreview(URL.createObjectURL(f));
  }

  async function save() {
    if (!text.trim()) { setErr('請輸入項目內容'); return; }
    setSaving(true);
    try {
      let saved;
      if (isNew) {
        saved = await _checkApi('POST', '/items', { text: text.trim(), category, note: note.trim() || null, url: url.trim() || null });
      } else {
        saved = await _checkApi('PATCH', `/items/${item.id}`, { text: text.trim(), category, note: note.trim() || null, url: url.trim() || null });
      }
      // Upload image if selected
      if (imgFile && saved?.id) {
        const fd = new FormData();
        fd.append('image', imgFile);
        await fetch(`/api/checklist/items/${saved.id}/upload`, {
          method: 'POST', headers: { Authorization: `Bearer ${window.tabiToken()}` }, body: fd,
        });
      }
      onSaved();
    } catch (e) { setErr(String(e)); setSaving(false); }
  }

  async function del() {
    if (!confirm(`刪除「${text}」？`)) return;
    await _checkApi('DELETE', `/items/${item.id}`);
    onDeleted();
  }

  return ReactDOM.createPortal(
    <>
      <div style={{ position:'fixed', inset:0, zIndex:9100, background:'rgba(24,20,15,0.48)', display:'flex', alignItems:'flex-end', animation:'tabiFade 0.18s ease' }}
        onClick={e => e.target === e.currentTarget && onClose()}>
        <div style={{ width:'100%', maxWidth:480, margin:'0 auto', background:TABI_COLORS.bg, borderRadius:'24px 24px 0 0', maxHeight:'92dvh', display:'flex', flexDirection:'column', boxShadow:'0 -22px 50px rgba(24,20,15,0.20)', animation:'tabiSheetUp 0.22s ease' }}>
          <div style={{ width:36, height:4, borderRadius:2, background:TABI_COLORS.line2, margin:'12px auto 0', flexShrink:0 }} />
          <div style={{ display:'flex', alignItems:'center', padding:'14px 18px 12px', borderBottom:`1px solid ${TABI_COLORS.line}`, flexShrink:0 }}>
            <div style={{ fontFamily:tabiSerif, fontSize:18, fontWeight:700, color:TABI_COLORS.ink, flex:1 }}>{isNew ? '新增項目' : '編輯項目'}</div>
            <button onClick={onClose} style={{ width:32, height:32, borderRadius:16, border:`1px solid ${TABI_COLORS.line}`, background:'transparent', fontSize:18, cursor:'pointer', color:TABI_COLORS.ink3, display:'grid', placeItems:'center' }}>×</button>
          </div>

          <div style={{ flex:1, overflowY:'auto', padding:'16px 18px' }}>
            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, marginBottom:5, fontWeight:600 }}>項目內容 *</div>
            <input value={text} onChange={e => setText(e.target.value)} placeholder="例：確認護照效期" style={inputStyle} />

            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, margin:'12px 0 5px', fontWeight:600 }}>類別</div>
            <select value={category} onChange={e => setCategory(e.target.value)} style={selStyle}>
              {categories.map(c => <option key={c} value={c}>{c}</option>)}
              <option value="其他">其他</option>
            </select>

            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, margin:'12px 0 5px', fontWeight:600 }}>細項說明（選填）</div>
            <textarea value={note} onChange={e => setNote(e.target.value)} placeholder="例：存在 Google Drive 備用，記得更新到最新版本" rows={3}
              style={{ ...inputStyle, minHeight:76, resize:'vertical', lineHeight:1.5 }} />

            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, margin:'12px 0 5px', fontWeight:600 }}>相關連結（選填）</div>
            <input value={url} onChange={e => setUrl(e.target.value)} placeholder="https://..." style={inputStyle} />

            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, margin:'12px 0 8px', fontWeight:600 }}>參考圖片（選填）</div>
            <div style={{ display:'flex', gap:10, alignItems:'center' }}>
              {imgPreview && (
                <img src={imgPreview} alt="" onClick={() => setLightbox(true)}
                  style={{ width:64, height:64, objectFit:'cover', borderRadius:10, flexShrink:0, border:`1px solid ${TABI_COLORS.line}`, cursor:'zoom-in' }} />
              )}
              <button onClick={() => fileRef.current?.click()} style={{
                flex:1, padding:'10px', borderRadius:10, border:`1.5px dashed ${TABI_COLORS.line2}`,
                background:'transparent', cursor:'pointer', fontSize:13, color:TABI_COLORS.ink2, fontWeight:600, minHeight:44,
              }}>{imgPreview ? '更換圖片' : '📷 上傳圖片'}</button>
              <input ref={fileRef} type="file" accept="image/*" style={{ display:'none' }} onChange={pickImg} />
            </div>

            {err && <div style={{ color:TABI_COLORS.red, fontSize:12.5, marginTop:10 }}>{err}</div>}
          </div>

          <div style={{ padding:'12px 18px calc(env(safe-area-inset-bottom,0px)+16px)', borderTop:`1px solid ${TABI_COLORS.line}`, flexShrink:0 }}>
            <div style={{ display:'flex', gap:10 }}>
              {!isNew && (
                <button onClick={del} style={{ padding:'13px 16px', borderRadius:12, border:`1px solid ${TABI_COLORS.red}40`, background:`${TABI_COLORS.red}08`, color:TABI_COLORS.red, fontSize:14, cursor:'pointer', flexShrink:0 }}>🗑</button>
              )}
              <button onClick={onClose} style={{ flex:1, padding:'13px', borderRadius:12, border:`1px solid ${TABI_COLORS.line}`, background:'transparent', fontSize:14, cursor:'pointer', color:TABI_COLORS.ink2 }}>取消</button>
              <button onClick={save} disabled={saving} style={{ flex:2, padding:'13px', borderRadius:12, border:'none', background:saving?TABI_COLORS.line2:TABI_COLORS.ink, color:'#fff', fontSize:14, fontWeight:700, cursor:saving?'not-allowed':'pointer' }}>
                {saving ? '儲存中…' : isNew ? '新增' : '儲存'}
              </button>
            </div>
          </div>
        </div>
      </div>
      {/* Lightbox */}
      {lightbox && ReactDOM.createPortal(
        <div onClick={() => setLightbox(false)} style={{ position:'fixed', inset:0, zIndex:9999, background:'rgba(0,0,0,0.88)', display:'flex', alignItems:'center', justifyContent:'center', cursor:'zoom-out' }}>
          <img src={imgPreview} alt="" style={{ maxWidth:'94vw', maxHeight:'88vh', objectFit:'contain', borderRadius:12 }} onClick={e => e.stopPropagation()} />
          <button onClick={() => setLightbox(false)} style={{ position:'absolute', top:20, right:20, width:38, height:38, borderRadius:19, border:'1px solid rgba(255,255,255,0.3)', background:'rgba(0,0,0,0.5)', color:'#fff', fontSize:18, cursor:'pointer', display:'grid', placeItems:'center' }}>×</button>
        </div>,
        document.body
      )}
    </>,
    document.body
  );
}

// ── ChecklistScreen ───────────────────────────────────────────

function ChecklistScreen({ go }) {
  const [items, setItems]         = React.useState([]);
  const [loading, setLoading]     = React.useState(true);
  const [editItem, setEditItem]   = React.useState(null);  // item to edit, or 'new'
  const [collapsed, setCollapsed] = React.useState({});
  const [hasTemplate, setHasTemplate] = React.useState(false);
  const [showMenu, setShowMenu]   = React.useState(false);

  async function load() {
    setLoading(true);
    try {
      const [data, tplData] = await Promise.all([
        _checkApi('GET', '/items'),
        _checkApi('GET', '/template'),
      ]);
      setItems(Array.isArray(data) ? data : []);
      setHasTemplate(tplData?.has_template || false);
    } catch {} finally { setLoading(false); }
  }

  React.useEffect(() => { load(); }, []);

  async function toggle(item) {
    await _checkApi('PATCH', `/items/${item.id}`, { is_done: !item.is_done });
    setItems(prev => prev.map(i => i.id === item.id ? {...i, is_done: !i.is_done} : i));
  }

  async function saveAsTemplate() {
    setShowMenu(false);
    await _checkApi('POST', '/template/save');
    setHasTemplate(true);
    alert('✓ 已儲存為我的模板');
  }

  async function resetChecklist() {
    setShowMenu(false);
    const msg = hasTemplate ? '重製清單？將清除目前進度並套用你儲存的模板。' : '重製清單？將清除目前進度並套用預設模板。';
    if (!confirm(msg)) return;
    await _checkApi('POST', '/reset');
    load();
  }

  // Group by category maintaining order
  const categories = [...new Set(items.map(i => i.category))];
  const grouped = {};
  categories.forEach(c => { grouped[c] = items.filter(i => i.category === c); });

  const doneCount = items.filter(i => i.is_done).length;
  const total = items.length;
  const progress = total > 0 ? doneCount / total : 0;

  return (
    <div style={{ background:`linear-gradient(180deg,${TABI_COLORS.bg} 0%,#F2E7D8 100%)`, minHeight:'100%', paddingBottom:'calc(env(safe-area-inset-bottom,0px)+100px)' }}>
      <TabiTopBar
        title="行前準備"
        subtitle="PRE-TRIP · 出發清單"
        onBack={() => go('home')}
        right={
          <div style={{ position:'relative' }}>
            <button onClick={() => setShowMenu(v => !v)} style={{
              minHeight:34, width:34, borderRadius:10, border:`1px solid ${TABI_COLORS.line}`,
              background:'transparent', cursor:'pointer', fontSize:17, color:TABI_COLORS.ink2,
              display:'grid', placeItems:'center',
            }}>⋯</button>
            {showMenu && ReactDOM.createPortal(
              <div style={{ position:'fixed', inset:0, zIndex:9400, background:'rgba(24,20,15,0.48)', display:'flex', alignItems:'flex-end', animation:'tabiFade 0.15s ease' }}
                onClick={() => setShowMenu(false)}>
                <div style={{ width:'100%', maxWidth:480, margin:'0 auto', background:TABI_COLORS.bg, borderRadius:'20px 20px 0 0', padding:'10px 10px calc(env(safe-area-inset-bottom,0px)+12px)', animation:'tabiSheetUp 0.2s ease' }}
                  onClick={e => e.stopPropagation()}>
                  <div style={{ width:32, height:3, borderRadius:2, background:TABI_COLORS.line2, margin:'0 auto 10px' }} />
                  {[
                    { icon:'💾', label:'儲存為我的模板', sub:'把目前清單存成下次的起點', action: saveAsTemplate },
                    { icon:'🔄', label: hasTemplate ? '重製清單（套用我的模板）' : '重製清單（套用預設模板）', sub:'清空進度重新開始', action: resetChecklist, color: TABI_COLORS.red },
                  ].map((a, i) => (
                    <button key={i} onClick={a.action} style={{
                      width:'100%', padding:'12px 14px', borderRadius:12, border:'none', background:'transparent',
                      display:'flex', alignItems:'center', gap:12, cursor:'pointer', textAlign:'left',
                    }}>
                      <span style={{ fontSize:22, width:28, textAlign:'center' }}>{a.icon}</span>
                      <div>
                        <div style={{ fontSize:14, fontWeight:600, color: a.color || TABI_COLORS.ink }}>{a.label}</div>
                        <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, marginTop:2 }}>{a.sub}</div>
                      </div>
                    </button>
                  ))}
                </div>
              </div>,
              document.body
            )}
          </div>
        }
      />

      <div style={{ padding:'14px 16px' }}>
        {/* Progress bar */}
        {total > 0 && (
          <div style={{ background:TABI_COLORS.card, borderRadius:16, padding:'14px 16px', marginBottom:14, border:`1px solid ${TABI_COLORS.line}`, boxShadow:TABI_COLORS.shadowSoft }}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:8 }}>
              <span style={{ fontSize:13, fontWeight:700, color:TABI_COLORS.ink }}>完成進度</span>
              <span style={{ fontFamily:tabiSerif, fontSize:16, fontWeight:800, color:doneCount===total ? TABI_COLORS.green : TABI_COLORS.warn }}>
                {doneCount} / {total}
              </span>
            </div>
            <div style={{ height:8, borderRadius:4, background:TABI_COLORS.line2, overflow:'hidden' }}>
              <div style={{
                height:'100%', width:`${progress*100}%`, borderRadius:4,
                background: doneCount===total ? TABI_COLORS.green : TABI_COLORS.warn,
                transition:'width 0.3s ease',
              }} />
            </div>
            {doneCount === total && total > 0 && (
              <div style={{ fontSize:13, color:TABI_COLORS.green, fontWeight:700, marginTop:8, textAlign:'center' }}>
                🎉 全部完成！出發吧！
              </div>
            )}
          </div>
        )}

        {loading && <div style={{ textAlign:'center', padding:'48px 0', color:TABI_COLORS.ink3 }}>載入中…</div>}

        {/* Items grouped by category */}
        {!loading && categories.map(cat => {
          const catItems = grouped[cat] || [];
          const catDone = catItems.filter(i => i.is_done).length;
          const isCollapsed = collapsed[cat];
          return (
            <div key={cat} style={{ marginBottom:10 }}>
              <button onClick={() => setCollapsed(prev => ({ ...prev, [cat]: !prev[cat] }))} style={{
                display:'flex', alignItems:'center', gap:8, width:'100%', padding:'8px 4px',
                background:'transparent', border:'none', cursor:'pointer',
              }}>
                <span style={{ fontSize:14, fontWeight:800, color:TABI_COLORS.ink, flex:1, textAlign:'left' }}>{cat}</span>
                <span style={{ fontSize:11, color:catDone===catItems.length ? TABI_COLORS.green : TABI_COLORS.ink3, fontWeight:600 }}>
                  {catDone}/{catItems.length}
                </span>
                <span style={{ fontSize:12, color:TABI_COLORS.ink3 }}>{isCollapsed ? '▸' : '▾'}</span>
              </button>

              {!isCollapsed && (
                <div style={{ background:TABI_COLORS.card, borderRadius:14, overflow:'hidden', border:`1px solid ${TABI_COLORS.line}`, boxShadow:TABI_COLORS.shadowSoft }}>
                  {catItems.map((item, idx) => (
                    <div key={item.id} style={{
                      borderTop: idx > 0 ? `1px solid ${TABI_COLORS.line}` : 'none',
                      background: item.is_done ? `${TABI_COLORS.green}06` : 'transparent',
                    }}>
                      <div style={{ display:'flex', alignItems:'flex-start', gap:10, padding:'12px 14px' }}>
                        {/* Checkbox */}
                        <button onClick={() => toggle(item)} style={{
                          width:24, height:24, borderRadius:7, flexShrink:0, cursor:'pointer', marginTop:1,
                          border:`2px solid ${item.is_done ? TABI_COLORS.green : TABI_COLORS.line2}`,
                          background:item.is_done ? TABI_COLORS.green : 'transparent',
                          display:'grid', placeItems:'center', color:'#fff', fontSize:12,
                        }}>{item.is_done ? '✓' : ''}</button>

                        {/* Image thumbnail */}
                        {item.image_url && (
                          <img src={item.image_url} alt="" onClick={() => setEditItem(item)}
                            style={{ width:44, height:44, objectFit:'cover', borderRadius:8, flexShrink:0, border:`1px solid ${TABI_COLORS.line}`, cursor:'pointer' }} />
                        )}

                        {/* Content */}
                        <div style={{ flex:1, minWidth:0 }}>
                          <div style={{
                            fontSize:14.5, color:TABI_COLORS.ink, fontWeight:500,
                            textDecoration:item.is_done ? 'line-through' : 'none',
                            opacity:item.is_done ? 0.5 : 1,
                            lineHeight:1.35,
                          }}>{item.text}</div>
                          {item.note && !item.is_done && (
                            <div style={{ fontSize:11.5, color:TABI_COLORS.ink3, marginTop:3, lineHeight:1.4 }}>{item.note}</div>
                          )}
                          {item.url && !item.is_done && (
                            <a href={item.url} target="_blank" rel="noopener noreferrer"
                              style={{ fontSize:11, color:TABI_COLORS.blue, marginTop:2, display:'block', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}
                              onClick={e => e.stopPropagation()}>
                              🔗 {item.url.replace(/^https?:\/\/(www\.)?/,'').slice(0,45)}
                            </a>
                          )}
                        </div>

                        {/* Edit button */}
                        <button onClick={() => setEditItem(item)} style={{
                          width:28, height:28, borderRadius:7, border:`1px solid ${TABI_COLORS.line}`,
                          background:'transparent', cursor:'pointer', fontSize:13, color:TABI_COLORS.ink3, flexShrink:0,
                          display:'grid', placeItems:'center',
                        }}>✏️</button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>
          );
        })}

        {!loading && items.length === 0 && (
          <div style={{ textAlign:'center', padding:'48px 20px', color:TABI_COLORS.ink3 }}>
            <div style={{ fontSize:44, marginBottom:12 }}>✅</div>
            <div style={{ fontSize:14, fontFamily:tabiSerif, color:TABI_COLORS.ink2 }}>清單是空的</div>
          </div>
        )}
      </div>

      {/* Add FAB */}
      {ReactDOM.createPortal(
        <button onClick={() => setEditItem('new')} style={{
          position:'fixed', bottom:'calc(env(safe-area-inset-bottom,0px) + 76px)', right:16,
          width:52, height:52, borderRadius:26, border:'none', cursor:'pointer',
          background:TABI_COLORS.warn, color:'#fff', fontSize:26, lineHeight:1,
          boxShadow:`0 12px 30px ${TABI_COLORS.warn}60`, zIndex:200,
        }}>+</button>,
        document.body
      )}

      {/* Detail sheet */}
      {editItem && (
        <ChecklistItemDetailSheet
          item={editItem === 'new' ? null : editItem}
          categories={categories}
          isNew={editItem === 'new'}
          onClose={() => setEditItem(null)}
          onSaved={() => { setEditItem(null); load(); }}
          onDeleted={() => { setEditItem(null); load(); }}
        />
      )}
    </div>
  );
}
