// ── HomebrewRepoView ────────────────────────────────────────────────────────
// Cross-campaign repository pooling HomebrewItem + CampaignMaterial. Filters
// (search text, type, realm, setting, tag) are sent to the server. Privacy is
// enforced server-side too — this view just renders what it gets back.
//
// Edit access: anyone whose role is owner/DM/admin for the row's campaign can
// edit. The flag `canEdit` is determined client-side from the current user's
// role + their campaign membership; mutating endpoints re-check on the server.
const HomebrewRepoView = ({ user, setNav }) => {
  const [rows, setRows]         = React.useState([]);
  const [facets, setFacets]     = React.useState({ settings:[], realms:[], tags:[] });
  const [campaigns, setCampaigns] = React.useState([]); // for figuring out canEdit
  const [loading, setLoading]   = React.useState(true);
  const [filters, setFilters]   = React.useState({ q:'', type:'all', realmId:'', setting:'', tag:'' });
  const [selected, setSelected] = React.useState(null); // detail-modal row

  const reload = React.useCallback(async () => {
    setLoading(true);
    try {
      const list = await api.homebrewRepo.list({
        q: filters.q || undefined,
        type: filters.type === 'all' ? undefined : filters.type,
        realmId: filters.realmId || undefined,
        setting: filters.setting || undefined,
        tag: filters.tag || undefined,
      });
      setRows(list || []);
    } catch (err) {
      console.error('[HomebrewRepo] load failed:', err);
    } finally {
      setLoading(false);
    }
  }, [filters.q, filters.type, filters.realmId, filters.setting, filters.tag]);

  // Initial: load facets + campaigns once; rows reload whenever filters change.
  React.useEffect(() => {
    Promise.all([api.homebrewRepo.facets(), api.campaigns.list()])
      .then(([f, cs]) => { setFacets(f || {settings:[], realms:[], tags:[]}); setCampaigns(cs || []); })
      .catch(err => console.error('[HomebrewRepo] facet/campaign load failed:', err));
  }, []);
  React.useEffect(() => { reload(); }, [reload]);

  const isAdmin = !!user.isAdmin;
  // canEdit = admin || (user is a DM/Co-DM of the row's campaign) || (user is the item's author)
  const canEdit = (row) => {
    if (isAdmin) return true;
    const c = campaigns.find(x => x.id === row.campaignId);
    if (c && isDmOf(c)) return true;
    if (row.kind === 'item' && row.authorId === user.id) return true;
    return false;
  };

  const togglePrivacy = async (row) => {
    if (!canEdit(row)) return;
    try {
      if (row.kind === 'item') {
        await api.campaigns.homebrew.update(row.campaignId, row.id, { isPublic: !row.isPublic });
      } else {
        await api.campaigns.materials.update(row.campaignId, row.id, { isPublic: !row.isPublic });
      }
      await reload();
      if (selected && selected.id === row.id && selected.kind === row.kind) {
        setSelected({ ...selected, isPublic: !row.isPublic });
      }
    } catch (err) {
      console.error('[HomebrewRepo] togglePrivacy failed:', err);
      window.dialog.alert('Failed to toggle privacy: ' + (err.message || 'unknown error'), { title:'Error' });
    }
  };

  const openInCampaign = (row) => {
    setNav({ view:'campaign', campaignId: row.campaignId, tab: row.kind === 'material' ? 'materials' : 'homebrew' });
  };

  return (
    <div style={hrStyles.page}>
      <div style={hrStyles.header}>
        <h1 style={hrStyles.title}>Homebrew Repository</h1>
        <div style={{fontSize:13, color:'#6b6966'}}>Cross-campaign library of homebrew items and materials</div>
      </div>

      <div style={hrStyles.filterBar}>
        <input
          placeholder="Search name or description…"
          value={filters.q}
          onChange={e => setFilters(f => ({...f, q: e.target.value}))}
          style={{...hrStyles.input, flex:'1 1 240px'}}
        />
        <select value={filters.type} onChange={e => setFilters(f => ({...f, type: e.target.value}))} style={hrStyles.select}>
          <option value="all">All types</option>
          <option value="item">Items only</option>
          <option value="material">Materials only</option>
        </select>
        <select value={filters.realmId} onChange={e => setFilters(f => ({...f, realmId: e.target.value}))} style={hrStyles.select}>
          <option value="">All realms</option>
          {facets.realms.map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
        </select>
        <select value={filters.setting} onChange={e => setFilters(f => ({...f, setting: e.target.value}))} style={hrStyles.select}>
          <option value="">All settings</option>
          {facets.settings.map(s => <option key={s} value={s}>{s}</option>)}
        </select>
        <select value={filters.tag} onChange={e => setFilters(f => ({...f, tag: e.target.value}))} style={hrStyles.select}>
          <option value="">All tags</option>
          {facets.tags.map(t => <option key={t} value={t}>{t}</option>)}
        </select>
        {(filters.q || filters.type !== 'all' || filters.realmId || filters.setting || filters.tag) && (
          <button style={hrStyles.clearBtn} onClick={() => setFilters({q:'', type:'all', realmId:'', setting:'', tag:''})}>Clear</button>
        )}
      </div>

      <div style={{fontSize:12, color:'#6b6966', margin:'4px 0 12px'}}>
        {loading ? 'Loading…' : `${rows.length} ${rows.length === 1 ? 'entry' : 'entries'}`}
      </div>

      {!loading && rows.length === 0 && (
        <div style={{color:'#6b6966', padding:'40px 0', textAlign:'center', fontSize:13}}>
          No homebrew matches the current filters.
        </div>
      )}

      <div style={hrStyles.grid}>
        {rows.map(row => {
          const editable = canEdit(row);
          const kindColor = row.kind === 'material' ? '#22c55e' : '#c9a227';
          return (
            <div key={`${row.kind}-${row.id}`} style={hrStyles.card} onClick={() => setSelected(row)}>
              <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:6, gap:8}}>
                <div style={{flex:1, minWidth:0}}>
                  <div style={{fontFamily:"'Cinzel',serif", fontSize:15, fontWeight:800, color:'#e8e6e3', overflow:'hidden', textOverflow:'ellipsis'}}>
                    {row.name}
                  </div>
                  <div style={{fontSize:11, color:'#6b6966', marginTop:2}}>
                    <span style={{color: kindColor, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.08em'}}>{row.kind}</span>
                    {row.subtype && <> · {row.subtype}</>}
                    {row.rarity && <> · <span style={{color: rarityColor(row.rarity)}}>{row.rarity}</span></>}
                  </div>
                </div>
                {!row.isPublic && (
                  <span title="Private — not visible in the public repository" style={hrStyles.privateBadge}>🔒 private</span>
                )}
              </div>

              {row.description && (
                <div style={{fontSize:12, color:'#9a9793', lineHeight:1.5, marginBottom:8, maxHeight:60, overflow:'hidden'}}>
                  {row.description.substring(0, 180)}{row.description.length > 180 ? '…' : ''}
                </div>
              )}

              <div style={{display:'flex', flexWrap:'wrap', gap:4, marginBottom:8}}>
                {row.tags.map(t => <span key={t} style={hrStyles.tag}>{t}</span>)}
              </div>

              <div style={{fontSize:11, color:'#6b6966', borderTop:'1px solid #1a1a20', paddingTop:8, display:'flex', justifyContent:'space-between', alignItems:'baseline', flexWrap:'wrap', gap:4}}>
                <span>
                  {row.realmName && <><span style={{color:'#c9a227'}}>{row.realmName}</span> · </>}
                  <span style={{color:'#9a9793'}}>{row.campaignName}</span>
                  {row.setting && <span style={{color:'#6b6966'}}> · {row.setting}</span>}
                </span>
                <span style={{color:'#4a4a52'}}>{row.createdAt}</span>
              </div>

              {editable && (
                <div style={{marginTop:8, display:'flex', gap:6}}>
                  <button style={hrStyles.smallBtn} onClick={e => { e.stopPropagation(); togglePrivacy(row); }}>
                    Make {row.isPublic ? 'private' : 'public'}
                  </button>
                  <button style={hrStyles.smallBtn} onClick={e => { e.stopPropagation(); openInCampaign(row); }}>Open in campaign →</button>
                </div>
              )}
            </div>
          );
        })}
      </div>

      {selected && (
        <div style={dialogStyles.scrim} {...scrimDismiss(() => setSelected(null))}>
          <div style={{...dialogStyles.box, maxWidth:680, maxHeight:'80vh', overflowY:'auto'}} onClick={e => e.stopPropagation()}>
            <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:8, gap:8}}>
              <div>
                <div style={{fontFamily:"'Cinzel',serif", fontSize:20, fontWeight:900, color:'#e8e6e3'}}>{selected.name}</div>
                <div style={{fontSize:12, color:'#6b6966', marginTop:4}}>
                  {selected.kind === 'item' ? 'Homebrew Item' : 'Material'}{selected.subtype && ` · ${selected.subtype}`}
                  {selected.rarity && <> · <span style={{color: rarityColor(selected.rarity)}}>{selected.rarity}</span></>}
                </div>
              </div>
              {!selected.isPublic && <span style={hrStyles.privateBadge}>🔒 private</span>}
            </div>

            <div style={{display:'flex', flexWrap:'wrap', gap:4, marginBottom:14}}>
              {selected.tags.map(t => <span key={t} style={hrStyles.tag}>{t}</span>)}
            </div>

            <div style={{whiteSpace:'pre-wrap', color:'#c5c3c0', fontSize:13, lineHeight:1.7, marginBottom:14}}>
              {selected.description || <span style={{color:'#6b6966'}}>No description.</span>}
            </div>

            <div style={{borderTop:'1px solid #2a2a32', paddingTop:12, fontSize:12, color:'#9a9793'}}>
              <div><strong style={{color:'#6b6966'}}>From:</strong> {selected.campaignName}</div>
              {selected.realmName && <div><strong style={{color:'#6b6966'}}>Realm:</strong> {selected.realmName}</div>}
              {selected.setting && <div><strong style={{color:'#6b6966'}}>Setting:</strong> {selected.setting}</div>}
              {selected.authorName && <div><strong style={{color:'#6b6966'}}>Author:</strong> {selected.authorName}</div>}
              <div><strong style={{color:'#6b6966'}}>Created:</strong> {selected.createdAt}</div>
            </div>

            <div style={dialogStyles.row}>
              {canEdit(selected) && (
                <button style={dialogStyles.btnGhost} onClick={() => togglePrivacy(selected)}>
                  Make {selected.isPublic ? 'private' : 'public'}
                </button>
              )}
              {canEdit(selected) && (
                <button style={dialogStyles.btnGhost} onClick={() => { openInCampaign(selected); setSelected(null); }}>
                  Open in campaign
                </button>
              )}
              <button style={dialogStyles.btn} onClick={() => setSelected(null)}>Close</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

const rarityColor = (r) => ({
  common:'#9a9793', uncommon:'#22c55e', rare:'#3b82f6',
  'very-rare':'#8b5cf6', legendary:'#f59e0b', artifact:'#c53030',
}[r] || '#9a9793');

const hrStyles = {
  page: { padding:'32px 36px', fontFamily:"'Nunito',sans-serif", overflowY:'auto', height:'100%' },
  header: { marginBottom:20 },
  title: { fontFamily:"'Cinzel',serif", fontSize:24, fontWeight:700, color:'#e8e6e3', margin:'0 0 4px' },
  filterBar: { display:'flex', flexWrap:'wrap', gap:8, marginBottom:8, alignItems:'center' },
  input: { background:'#16161b', border:'1px solid #2a2a32', borderRadius:6, color:'#e8e6e3', padding:'7px 10px', fontSize:13, fontFamily:"'Nunito',sans-serif" },
  select: { background:'#16161b', border:'1px solid #2a2a32', borderRadius:6, color:'#e8e6e3', padding:'7px 10px', fontSize:13, fontFamily:"'Nunito',sans-serif", cursor:'pointer' },
  clearBtn: { background:'transparent', border:'1px solid #3a3a42', color:'#9a9793', borderRadius:6, padding:'7px 12px', cursor:'pointer', fontSize:12, fontFamily:"'Nunito',sans-serif" },
  grid: { display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(280px, 1fr))', gap:14 },
  card: { background:'#1c1c22', border:'1px solid #2a2a32', borderRadius:10, padding:'14px 16px', cursor:'pointer', transition:'border-color 0.12s, transform 0.12s', display:'flex', flexDirection:'column' },
  tag: { fontSize:10, background:'#2a2a32', color:'#9a9793', borderRadius:20, padding:'2px 8px' },
  privateBadge: { fontSize:10, color:'#f87171', background:'rgba(248,113,113,0.10)', border:'1px solid rgba(248,113,113,0.30)', borderRadius:20, padding:'2px 8px', whiteSpace:'nowrap', flexShrink:0 },
  smallBtn: { background:'transparent', border:'1px solid #2a2a32', color:'#9a9793', borderRadius:5, padding:'4px 10px', cursor:'pointer', fontSize:11, fontFamily:"'Nunito',sans-serif" },
};

window.HomebrewRepoView = HomebrewRepoView;
