// ============================================================
// SocialPulse — Posts Page (full filters + view toggle)
// ============================================================

const POSTS_PAGE_SIZE = 50;

function PostsPage({ onNavigate }) {
  const initParams = (typeof _hashParams === 'function') ? _hashParams() : {};
  const [platform, setPlatform] = useState(initParams.platform || '');
  const [sortBy, setSortBy] = useState('date_desc');
  const [searchQ, setSearchQ] = useState('');
  const [from, setFrom] = useState(initParams.from || '');
  const [to, setTo] = useState(initParams.to || '');
  const [view, setView] = useState(localStorage.getItem('sp_posts_view') || 'card');
  const [selectedBrands, setSelectedBrands] = useState(() => {
    const raw = initParams.brand_ids;
    if (!raw) return new Set();
    return new Set(raw.split(',').map(Number).filter(Boolean));
  });
  const [selectedCats, setSelectedCats] = useState(() => {
    const raw = initParams.category_ids;
    if (!raw) return new Set();
    return new Set(raw.split(',').map(Number).filter(Boolean));
  });
  const [visibleCount, setVisibleCount] = useState(POSTS_PAGE_SIZE);

  useEffect(() => { localStorage.setItem('sp_posts_view', view); }, [view]);

  useEffect(() => {
    const onHash = () => {
      const p = (typeof _hashParams === 'function') ? _hashParams() : {};
      if (p.from != null) setFrom(p.from);
      if (p.to != null) setTo(p.to);
      if (p.platform != null) setPlatform(p.platform);
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  const brands = useApi(() => spBrands.list(), []);
  const cats = useApi(() => spStats.categories(), []);

  // Reset visible window when any filter changes
  useEffect(() => { setVisibleCount(POSTS_PAGE_SIZE); }, [platform, sortBy, from, to, selectedBrands, selectedCats]);

  const fetchKey = useMemo(() => JSON.stringify({
    platform, sortBy, from, to,
    b: Array.from(selectedBrands).sort(),
    c: Array.from(selectedCats).sort(),
  }), [platform, sortBy, from, to, selectedBrands, selectedCats]);

  const posts = useApi(() => {
    const params = { sort: sortBy, limit: 200 };
    if (platform) params.platform = platform;
    if (from) params.from = from;
    if (to) params.to = to;
    if (selectedBrands.size) params.brand_ids = Array.from(selectedBrands).join(',');
    else if (selectedCats.size) params.category_ids = Array.from(selectedCats).join(',');
    return spPosts.list(params);
  }, [fetchKey]);

  const allBrands = brands.data || [];
  const allCats = cats.data || [];
  const hasNoBrands = !brands.loading && allBrands.length === 0;

  // Brand list narrowed by selected categories (so chips stay coherent)
  const visibleBrandList = useMemo(() => {
    if (!selectedCats.size) return allBrands;
    return allBrands.filter(b => selectedCats.has(b.category_id));
  }, [allBrands, selectedCats]);

  const filtered = useMemo(() => {
    let list = posts.data || [];
    if (searchQ) {
      const q = searchQ.toLowerCase();
      list = list.filter(p => (p.message || '').toLowerCase().includes(q) || (p.brand_name || '').toLowerCase().includes(q));
    }
    return list;
  }, [posts.data, searchQ]);

  const visible = filtered.slice(0, visibleCount);

  const toggleBrand = (id) => {
    setSelectedBrands(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };
  const toggleCat = (id) => {
    setSelectedCats(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      // Drop brand selections that are no longer in any selected category
      if (next.size) {
        setSelectedBrands(prevB => {
          const allowed = new Set(allBrands.filter(b => next.has(b.category_id)).map(b => b.id));
          const filtered = new Set();
          prevB.forEach(bid => { if (allowed.has(bid)) filtered.add(bid); });
          return filtered;
        });
      }
      return next;
    });
  };
  const clearAll = () => { setSelectedBrands(new Set()); setSelectedCats(new Set()); };

  const exportCsv = async () => {
    const params = { sort: sortBy };
    if (platform) params.platform = platform;
    if (from) params.from = from;
    if (to) params.to = to;
    if (selectedBrands.size) params.brand_ids = Array.from(selectedBrands).join(',');
    else if (selectedCats.size) params.category_ids = Array.from(selectedCats).join(',');
    const url = spPosts.exportCsvUrl(params);
    try {
      const r = await fetch(url, { headers: { Authorization: `Bearer ${spGetToken()}` } });
      if (!r.ok) throw new Error('匯出失敗');
      const blob = await r.blob();
      const a = document.createElement('a');
      a.href = URL.createObjectURL(blob);
      a.download = `socialpulse-${new Date().toISOString().slice(0,10)}.csv`;
      a.click();
      URL.revokeObjectURL(a.href);
      spToast('已下載 CSV');
    } catch (e) { spToast(e.message || '匯出失敗', 'err'); }
  };

  return (
    <div>
      <div style={{display:'flex',alignItems:'center',gap:12,padding:'16px 0'}}>
        <h2 style={{fontSize:22,fontWeight:800,letterSpacing:'-.02em'}}>所有貼文</h2>
        <span style={{fontFamily:'var(--font-mono)',fontSize:11,color:'var(--text3)',padding:'3px 8px',border:'1px solid var(--line)',borderRadius:'var(--r-xs)'}}>{filtered.length} 筆</span>
        <div style={{marginLeft:'auto',display:'flex',gap:8,alignItems:'center'}}>
          <input style={{
            background:'var(--panel)',border:'1px solid var(--line)',borderRadius:'var(--r-md)',
            padding:'7px 12px',fontSize:13,color:'var(--text)',width:220,fontFamily:'var(--font-ui)',outline:'none',
          }} placeholder="搜尋品牌或關鍵字…" value={searchQ} onChange={e=>setSearchQ(e.target.value)}
            onFocus={e=>e.target.style.borderColor='var(--indigo)'}
            onBlur={e=>e.target.style.borderColor='var(--line)'}/>
          <button className="btn btn-ghost btn-sm" onClick={exportCsv}>📥 匯出 CSV</button>
        </div>
      </div>

      {hasNoBrands ? (
        <div style={{padding:'60px 20px',textAlign:'center'}}>
          <div style={{fontSize:42,marginBottom:16}}>📭</div>
          <div style={{fontSize:16,fontWeight:600,marginBottom:6}}>還沒有追蹤任何品牌</div>
          <div style={{fontSize:13,color:'var(--text2)',marginBottom:20}}>先加入想追蹤的 FB 粉專或 IG 帳號，才能抓到貼文數據</div>
          <button className="btn btn-primary" onClick={() => onNavigate && onNavigate('brands')}>
            去新增品牌 →
          </button>
        </div>
      ) : (
        <>
          {/* Category chips */}
          {allCats.length > 0 && (
            <div style={{display:'flex',gap:6,padding:'10px 0',flexWrap:'wrap',alignItems:'center'}}>
              <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em',marginRight:4}}>分類</span>
              <Chip active={!selectedCats.size} onClick={() => setSelectedCats(new Set())}>全部</Chip>
              {allCats.map(c => (
                <Chip key={c.id} active={selectedCats.has(c.id)} onClick={() => toggleCat(c.id)}>
                  {c.icon} {c.name}
                </Chip>
              ))}
            </div>
          )}

          {/* Brand chips (narrowed by selected categories) */}
          {visibleBrandList.length > 0 && (
            <div style={{display:'flex',gap:6,padding:'6px 0',flexWrap:'wrap',alignItems:'center'}}>
              <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em',marginRight:4}}>品牌</span>
              <Chip active={!selectedBrands.size} onClick={() => setSelectedBrands(new Set())}>全部 ({visibleBrandList.length})</Chip>
              {visibleBrandList.map(b => (
                <Chip key={b.id} active={selectedBrands.has(b.id)} onClick={() => toggleBrand(b.id)}>
                  {b.name}
                </Chip>
              ))}
              {(selectedBrands.size > 0 || selectedCats.size > 0) && (
                <button onClick={clearAll} className="btn btn-ghost btn-sm" style={{marginLeft:6,fontSize:11}}>清除全部</button>
              )}
            </div>
          )}

          {/* Toolbar: platform / date range / sort / view toggle */}
          <div style={{display:'flex',gap:8,alignItems:'center',padding:'12px 0',borderBottom:'1px solid var(--line)',borderTop:'1px solid var(--line)',marginTop:8,flexWrap:'wrap'}}>
            <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em'}}>平台</span>
            {[['','全部'],['fb','FB'],['ig','IG']].map(([v,l]) => (
              <Chip key={v} active={platform===v} onClick={()=>setPlatform(v)}>{l}</Chip>
            ))}
            <span style={{width:1,height:18,background:'var(--line)',margin:'0 4px'}}/>

            <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em'}}>日期</span>
            <DateInput value={from} onChange={setFrom} placeholder="從"/>
            <span style={{color:'var(--text3)'}}>→</span>
            <DateInput value={to} onChange={setTo} placeholder="到"/>
            {(from || to) && <button className="btn btn-ghost btn-sm" style={{fontSize:11}} onClick={() => { setFrom(''); setTo(''); }}>清除日期</button>}

            <span style={{width:1,height:18,background:'var(--line)',margin:'0 4px'}}/>
            <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em'}}>排序</span>
            {[
              ['date_desc','最新優先'],
              ['engagement_desc','互動排序'],
              ['likes_desc','讚數排序'],
            ].map(([v,l]) => <Chip key={v} active={sortBy===v} onClick={()=>setSortBy(v)}>{l}</Chip>)}

            <div style={{marginLeft:'auto',display:'inline-flex',background:'var(--panel)',border:'1px solid var(--line)',borderRadius:'var(--r-md)',padding:2}}>
              <button onClick={() => setView('card')} style={{
                padding:'5px 12px',border:'none',cursor:'pointer',fontSize:12,fontWeight:600,
                background: view==='card' ? 'var(--indigo)' : 'transparent',
                color: view==='card' ? '#fff' : 'var(--text2)',
                borderRadius:'var(--r-sm)',
              }}>🖼 卡片</button>
              <button onClick={() => setView('table')} style={{
                padding:'5px 12px',border:'none',cursor:'pointer',fontSize:12,fontWeight:600,
                background: view==='table' ? 'var(--indigo)' : 'transparent',
                color: view==='table' ? '#fff' : 'var(--text2)',
                borderRadius:'var(--r-sm)',
              }}>☰ 表格</button>
            </div>
          </div>

          {posts.loading ? <LoadingState label="載入貼文中…"/> :
           posts.error ? <ErrorState error={posts.error} onRetry={posts.reload}/> :
           filtered.length === 0 ? (
             <div style={{padding:'60px 20px',textAlign:'center'}}>
               <div style={{fontSize:16,fontWeight:600,marginBottom:6}}>沒有符合條件的貼文</div>
               <div style={{fontSize:13,color:'var(--text2)',marginBottom:20}}>試著調整篩選條件，或到品牌頁更新數據</div>
               <button className="btn btn-ghost btn-sm" onClick={() => onNavigate && onNavigate('brands')}>前往品牌 →</button>
             </div>
           ) : view === 'table' ? (
             <PostTable posts={visible}/>
           ) : (
             <PostCardGrid posts={visible}/>
           )}

          {filtered.length > visibleCount && (
            <div style={{padding:20,textAlign:'center'}}>
              <button className="btn btn-ghost" onClick={() => setVisibleCount(v => v + POSTS_PAGE_SIZE)}>
                載入更多（剩 {filtered.length - visibleCount} 筆）
              </button>
            </div>
          )}
        </>
      )}
    </div>
  );
}

function DateInput({ value, onChange, placeholder }) {
  return (
    <input type="date" value={value} onChange={e => onChange(e.target.value)}
      style={{
        background:'var(--panel)',border:'1px solid var(--line)',borderRadius:'var(--r-md)',
        padding:'5px 10px',fontSize:12,color:'var(--text)',outline:'none',
        fontFamily:'var(--font-mono)',width:135,
      }}
      placeholder={placeholder}
    />
  );
}

function PostTable({ posts }) {
  return (
    <div style={{background:'var(--panel)',border:'1px solid var(--line)',borderRadius:'var(--r-xl)',overflow:'hidden',marginTop:16}}>
      <table style={{width:'100%',borderCollapse:'collapse'}}>
        <thead>
          <tr>
            {[['#',40],['貼文',''],['讚',80],['留言',80],['分享',80],['觀看',90],['總互動',100]].map(([l,w],i) => (
              <th key={l} style={{textAlign:i>=2?'right':'left',padding:'12px 16px',fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)',textTransform:'uppercase',letterSpacing:'.1em',fontWeight:600,borderBottom:'1px solid var(--line)',background:'var(--bg2)',width:w||'auto'}}>{l}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {posts.map((p,i) => {
            const eng = (p.likes_count||0)+(p.comments_count||0)+(p.shares_count||0);
            const isVideo = !!(p.video_url || (p.video_view_count||0) > 0);
            return (
              <tr key={p.id||i} style={{transition:'background .1s',cursor:p.permalink_url?'pointer':'default'}}
                onClick={()=>{ if(p.permalink_url && /^https?:\/\//i.test(p.permalink_url)) window.open(p.permalink_url,'_blank','noopener,noreferrer'); }}
                onMouseOver={e=>e.currentTarget.style.background='var(--panel2)'}
                onMouseOut={e=>e.currentTarget.style.background='transparent'}>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',fontFamily:'var(--font-mono)',fontSize:11,color:'var(--text3)'}}>{i+1}</td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)'}}>
                  <div style={{display:'flex',alignItems:'center',gap:10}}>
                    {p.image_url
                      ? <img src={p.image_url} loading="lazy" style={{width:40,height:40,borderRadius:'var(--r-sm)',objectFit:'cover',flexShrink:0}} onError={e=>{e.target.style.display='none'}}/>
                      : <BrandAvatar name={p.brand_name} color="var(--indigo)" size={40}/>}
                    <div style={{minWidth:0,flex:1}}>
                      <div style={{display:'flex',gap:6,alignItems:'center',marginBottom:2}}>
                        <span style={{fontWeight:600,fontSize:13}}>{p.brand_name}</span>
                        <PlatformBadge platform={p.platform||'fb'}/>
                        <span style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)'}}>{p.created_time?.slice(0,16).replace('T',' ')}</span>
                        {p.video_view_count>0 && <span style={{fontFamily:'var(--font-mono)',fontSize:9,padding:'1px 5px',borderRadius:3,background:'var(--purple)',color:'#fff',fontWeight:600}}>VID</span>}
                      </div>
                      <div style={{fontSize:12,color:'var(--text2)',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',maxWidth:600}}>{p.message||'（無文字）'}</div>
                    </div>
                  </div>
                </td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',textAlign:'right',fontFamily:'var(--font-mono)',color:'var(--red)',fontWeight:600}}>{fmtK(p.likes_count||0)}</td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',textAlign:'right',fontFamily:'var(--font-mono)',color:'var(--blue)'}}>{fmtK(p.comments_count||0)}</td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',textAlign:'right',fontFamily:'var(--font-mono)',color:'var(--green)'}}>{fmtK(p.shares_count||0)}</td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',textAlign:'right',fontFamily:'var(--font-mono)',color:'var(--purple)'}}>{isVideo ? fmtK(p.video_view_count||0) : '—'}</td>
                <td style={{padding:'12px 16px',borderBottom:'1px solid var(--line)',textAlign:'right',fontFamily:'var(--font-mono)',fontWeight:700,fontSize:15,color:'var(--orange)'}}>{fmtK(eng)}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function PostCardGrid({ posts }) {
  return (
    <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(320px,1fr))',gap:14,marginTop:16}}>
      {posts.map(p => <PostCard key={p.id} post={p}/>)}
    </div>
  );
}

function PostCard({ post: p }) {
  const eng = (p.likes_count||0)+(p.comments_count||0)+(p.shares_count||0);
  const link = p.permalink_url && /^https?:\/\//.test(p.permalink_url) ? p.permalink_url : null;
  return (
    <div style={{
      background:'var(--panel)',border:'1px solid var(--line)',borderRadius:'var(--r-xl)',
      overflow:'hidden',display:'flex',flexDirection:'column',
    }}>
      <div style={{padding:'12px 14px',borderBottom:'1px solid var(--line)',display:'flex',gap:10,alignItems:'center'}}>
        {p.brand_logo
          ? <img src={p.brand_logo} loading="lazy" style={{width:32,height:32,borderRadius:'var(--r-sm)',objectFit:'cover'}} onError={e=>{e.target.style.display='none'}}/>
          : <BrandAvatar name={p.brand_name} color="var(--indigo)" size={32}/>}
        <div style={{minWidth:0,flex:1}}>
          <div style={{fontWeight:600,fontSize:13,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{p.brand_name}</div>
          <div style={{fontFamily:'var(--font-mono)',fontSize:10,color:'var(--text3)'}}>{p.created_time?.slice(0,16).replace('T',' ')}</div>
        </div>
        <PlatformBadge platform={p.platform||'fb'}/>
      </div>
      {p.image_url && (
        <img src={p.image_url} loading="lazy" alt=""
          style={{width:'100%',aspectRatio:'1.6',objectFit:'cover',background:'var(--panel2)'}}
          onError={e=>{e.target.style.display='none'}}/>
      )}
      <div style={{padding:'12px 14px',flex:1}}>
        {p.video_url && (
          <span style={{display:'inline-block',background:'var(--purple)',color:'#fff',fontSize:10,padding:'2px 6px',borderRadius:4,marginBottom:6,fontWeight:600}}>🎥 影片</span>
        )}
        <div style={{
          fontSize:13,color:'var(--text)',lineHeight:1.55,
          display:'-webkit-box',WebkitLineClamp:4,WebkitBoxOrient:'vertical',
          overflow:'hidden',
        }}>{p.message || '（無文字內容）'}</div>
      </div>
      <div style={{padding:'10px 14px',borderTop:'1px solid var(--line)',display:'flex',gap:14,fontFamily:'var(--font-mono)',fontSize:12,flexWrap:'wrap'}}>
        <span style={{color:'var(--red)'}}>❤ {fmtK(p.likes_count||0)}</span>
        <span style={{color:'var(--blue)'}}>💬 {fmtK(p.comments_count||0)}</span>
        <span style={{color:'var(--green)'}}>🔄 {fmtK(p.shares_count||0)}</span>
        {(p.video_url || (p.video_view_count||0) > 0) && (
          <span style={{color:'var(--purple)'}}>👀 {fmtK(p.video_view_count||0)}</span>
        )}
        <span style={{color:'var(--orange)',fontWeight:700,marginLeft:'auto'}}>🔥 {fmtK(eng)}</span>
      </div>
      {link && (
        <a href={link} target="_blank" rel="noopener noreferrer"
          style={{padding:'10px 14px',borderTop:'1px solid var(--line)',fontSize:12,color:'var(--indigo)',textDecoration:'none',textAlign:'center',fontWeight:600}}>
          查看原文 →
        </a>
      )}
    </div>
  );
}

Object.assign(window, { PostsPage });
