const { useState: useStateMC, useEffect: useEffectMC, useRef: useRefMC } = React;

const C_STATUS_OPTIONS = ['Draft', 'Activă', 'Completă', 'Anulată'];
const C_STATUS_COLORS = {
  'Draft': { bg: 'rgba(255,255,255,.05)', color: 'var(--txt-2)' },
  'Activă': { bg: 'rgba(82,242,15,.1)', color: 'var(--accent-1)' },
  'Completă': { bg: 'rgba(63,169,245,.1)', color: '#3FA9F5' },
  'Anulată': { bg: 'rgba(255,90,90,.1)', color: '#FF5A5A' },
};
const CAMPAIGN_TYPES_OPTIONS = ['TikTok Live', 'Video TikTok', 'Story Instagram', 'Reel Instagram', 'Post Instagram', 'YouTube', 'Mix'];

const CC_STATUS_OPTIONS = ['Invitat', 'Acceptat', 'Refuzat', 'Material trimis', 'Material aprobat', 'Publicat', 'Plătit'];
const CC_STATUS_COLORS = {
  'Invitat': { bg: 'rgba(255,255,255,.05)', color: 'var(--txt-2)' },
  'Acceptat': { bg: 'rgba(82,242,15,.08)', color: 'var(--accent-1)' },
  'Refuzat': { bg: 'rgba(255,90,90,.1)', color: '#FF5A5A' },
  'Material trimis': { bg: 'rgba(255,215,0,.1)', color: '#FFD700' },
  'Material aprobat': { bg: 'rgba(63,169,245,.1)', color: '#3FA9F5' },
  'Publicat': { bg: 'rgba(82,242,15,.15)', color: 'var(--accent-1)' },
  'Plătit': { bg: 'rgba(82,242,15,.2)', color: 'var(--accent-1)' },
};
const CC_PAYMENT_STATUS_OPTIONS = ['Neplătit', 'În proces', 'Plătit'];

function MediaAdminCampaigns({ onNav }) {
  const [profile, setProfile] = useStateMC(null);
  const [loading, setLoading] = useStateMC(true);
  const [campaigns, setCampaigns] = useStateMC([]);
  const [brands, setBrands] = useStateMC([]);
  const [staffList, setStaffList] = useStateMC([]);
  const [search, setSearch] = useStateMC('');
  const [statusFilter, setStatusFilter] = useStateMC('Toate');
  const [selectedCampaign, setSelectedCampaign] = useStateMC(null);
  const [showCreateDrawer, setShowCreateDrawer] = useStateMC(false);
  const [refreshKey, setRefreshKey] = useStateMC(0);
  const [creatorsByCampaign, setCreatorsByCampaign] = useStateMC({});
  const [sortBy, setSortBy] = useStateMC('created_at');
  const [sortDir, setSortDir] = useStateMC('desc');
  const [currentPage, setCurrentPage] = useStateMC(1);
  const [perPage, setPerPage] = useStateMC(20);
  const [viewMode, setViewMode] = useStateMC('list');

  useEffectMC(() => { setCurrentPage(1); }, [search, statusFilter, perPage]);

  useEffectMC(() => {
    let mounted = true;
    let channel = null;

    const fetchAll = async () => {
      try {
        const [
          { data: camps },
          { data: brs },
          { data: staff }
        ] = await Promise.all([
          window.sb.from('campaigns').select('*').order('created_at', { ascending: false }),
          window.sb.from('brand_applications').select('id, company, brand').order('company'),
          window.sb.from('staff_profiles').select('id, full_name').eq('is_active', true).order('full_name'),
        ]);
        if (!mounted) return;
        setCampaigns(camps || []);
        setBrands(brs || []);
        setStaffList(staff || []);

        const { data: allCc } = await window.sb
          .from('campaign_creators')
          .select('campaign_id, status');
        const stats = {};
        (allCc || []).forEach(cc => {
          if (!stats[cc.campaign_id]) stats[cc.campaign_id] = { total: 0, published: 0 };
          stats[cc.campaign_id].total++;
          if (cc.status === 'Publicat' || cc.status === 'Plătit') stats[cc.campaign_id].published++;
        });
        if (!mounted) return;
        setCreatorsByCampaign(stats);
      } catch (err) {
        console.error('[4U Media Admin] Campaigns fetch error:', err);
      }
    };

    (async () => {
      try {
        let tries = 0;
        while (!window.sb && tries < 100) { await new Promise(r => setTimeout(r, 50)); tries++; }
        if (!window.sb) { onNav('media-login'); return; }

        const { data: { session } } = await window.sb.auth.getSession();
        if (!session) { onNav('media-login'); return; }

        const { data: prof, error } = await window.sb
          .from('staff_profiles').select('id, full_name, email, role, is_active')
          .eq('id', session.user.id).maybeSingle();
        if (error || !prof || !prof.is_active) {
          await window.sb.auth.signOut(); onNav('media-login'); return;
        }
        if (!mounted) return;
        setProfile(prof);

        await fetchAll();
        if (!mounted) return;
        setLoading(false);

        channel = window.sb.channel('media-admin-campaigns-realtime')
          .on('postgres_changes', { event: '*', schema: 'public', table: 'campaigns' }, fetchAll)
          .on('postgres_changes', { event: '*', schema: 'public', table: 'campaign_creators' }, fetchAll)
          .subscribe();
      } catch (err) {
        console.error('[4U Media Admin] Campaigns page error:', err);
        onNav('media-login');
      }
    })();

    return () => {
      mounted = false;
      if (channel) window.sb.removeChannel(channel);
    };
  }, [refreshKey]);

  const filteredCampaigns = campaigns.filter(c => {
    if (statusFilter !== 'Toate' && c.status !== statusFilter) return false;
    if (search) {
      const s = search.toLowerCase();
      const brand = brands.find(b => b.id === c.brand_id);
      if (!(c.name || '').toLowerCase().includes(s) &&
          !(brand?.company || '').toLowerCase().includes(s) &&
          !(brand?.brand || '').toLowerCase().includes(s)) return false;
    }
    return true;
  }).sort((a, b) => {
    let valA, valB;
    if (sortBy === 'progress') {
      valA = (creatorsByCampaign[a.id] || {}).total || 0;
      valB = (creatorsByCampaign[b.id] || {}).total || 0;
    } else {
      valA = a[sortBy]; valB = b[sortBy];
    }
    if (valA === null || valA === undefined) valA = '';
    if (valB === null || valB === undefined) valB = '';
    if (typeof valA === 'string') valA = valA.toLowerCase();
    if (typeof valB === 'string') valB = valB.toLowerCase();
    if (valA < valB) return sortDir === 'asc' ? -1 : 1;
    if (valA > valB) return sortDir === 'asc' ? 1 : -1;
    return 0;
  });

  const totalPages = Math.max(1, Math.ceil(filteredCampaigns.length / perPage));
  const safePage = Math.min(Math.max(1, currentPage), totalPages);
  const paginatedCampaigns = filteredCampaigns.slice((safePage - 1) * perPage, safePage * perPage);

  const handleSort = (key) => {
    if (sortBy === key) {
      setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
    } else {
      setSortBy(key);
      setSortDir('asc');
    }
  };

  if (loading) {
    return (
      <div style={{ minHeight: '100vh', display: 'grid', placeItems: 'center' }}>
        <span style={{ width: 32, height: 32, borderRadius: 999, border: '3px solid rgba(82,242,15,.2)', borderTopColor: 'var(--accent-1)', animation: 'mc-spin 0.8s linear infinite' }} />
        <style>{`@keyframes mc-spin { to { transform: rotate(360deg); } }`}</style>
      </div>
    );
  }

  return (
    <MediaAdminLayout onNav={onNav} currentPage="media-admin-campaigns" profile={profile}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 32, flexWrap: 'wrap', gap: 16 }}>
        <div>
          <h1 className="display" style={{ fontSize: 'clamp(28px, 4vw, 40px)', margin: '0 0 8px' }}>Campanii</h1>
          <p style={{ color: 'var(--txt-2)', fontSize: 15, margin: 0 }}>
            Total: <strong style={{ color: 'var(--txt-0)' }}>{campaigns.length}</strong>
            {filteredCampaigns.length !== campaigns.length && (<> · Afișate: <strong style={{ color: 'var(--accent-1)' }}>{filteredCampaigns.length}</strong></>)}
          </p>
        </div>
        <button onClick={() => setShowCreateDrawer(true)} className="btn btn-primary">+ Campanie nouă</button>
      </div>

      <div className="filter-panel" style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
        <input type="text" placeholder="🔍 Caută după nume campanie sau brand..."
          value={search} onChange={e => setSearch(e.target.value)}
          className="input" style={{ flex: 1, minWidth: 300 }} />
        <select value={statusFilter} onChange={e => setStatusFilter(e.target.value)}
          className="input" style={{ width: 200, color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
          <option value="Toate" style={{ backgroundColor: '#1a1a1a' }}>Toate statusurile</option>
          {C_STATUS_OPTIONS.map(s => <option key={s} value={s} style={{ backgroundColor: '#1a1a1a' }}>{s}</option>)}
        </select>
        <div style={{ display: 'flex', borderRadius: 8, border: '.5px solid var(--line)', overflow: 'hidden', flexShrink: 0 }}>
          {[{ k: 'list', label: '📋 Listă' }, { k: 'calendar', label: '📅 Calendar' }].map(opt => {
            const active = viewMode === opt.k;
            return (
              <button
                key={opt.k}
                type="button"
                onClick={() => setViewMode(opt.k)}
                style={{
                  padding: '9px 16px',
                  fontSize: 13,
                  fontWeight: active ? 600 : 500,
                  background: active ? 'var(--accent-1)' : 'transparent',
                  color: active ? '#000' : 'var(--txt-2)',
                  border: 'none',
                  cursor: 'pointer',
                  transition: 'background .15s, color .15s',
                  whiteSpace: 'nowrap',
                }}
              >{opt.label}</button>
            );
          })}
        </div>
      </div>

      {viewMode === 'list' && (
      <>
      <div className="card-glass" style={{ padding: 0, overflow: 'hidden' }}>
        {filteredCampaigns.length === 0 ? (
          <div style={{ padding: 60, textAlign: 'center', color: 'var(--txt-3)' }}>
            {campaigns.length === 0 ? 'Nicio campanie încă. Apasă "+ Campanie nouă" ca să începi.' : 'Niciun rezultat care să corespundă filtrelor.'}
          </div>
        ) : (
          <div className="ma-table-scroll" style={{ overflowX: 'auto', overflowY: 'hidden' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
              <thead>
                <tr style={{ background: 'rgba(255,255,255,.03)' }}>
                  <ThSortable sortKey="name" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Nume campanie</ThSortable>
                  <ThSortable sortKey="brand_id" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Brand</ThSortable>
                  <ThSortable>Tip</ThSortable>
                  <ThSortable sortKey="status" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Status</ThSortable>
                  <ThSortable sortKey="material_deadline" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Deadline material</ThSortable>
                  <ThSortable sortKey="progress" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Progress</ThSortable>
                  <ThSortable sortKey="assigned_to" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Manager</ThSortable>
                  <ThSortable sortKey="created_at" currentSort={sortBy} currentDir={sortDir} onSort={handleSort}>Data creare</ThSortable>
                </tr>
              </thead>
              <tbody>
                {paginatedCampaigns.map(c => {
                  const brand = brands.find(b => b.id === c.brand_id);
                  const manager = staffList.find(s => s.id === c.assigned_to);
                  return (
                    <tr key={c.id} onClick={() => setSelectedCampaign(c)}
                      style={{ cursor: 'pointer', borderTop: '.5px solid var(--line)', transition: 'background .15s' }}
                      onMouseEnter={e => e.currentTarget.style.background = 'rgba(82,242,15,.04)'}
                      onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                      <Td><strong>{c.name}</strong></Td>
                      <Td>{brand ? (brand.brand || brand.company) : <span style={{ color: 'var(--txt-3)' }}>—</span>}</Td>
                      <Td>{c.campaign_types && c.campaign_types.length > 0 ? c.campaign_types.slice(0, 2).join(', ') + (c.campaign_types.length > 2 ? '...' : '') : <span style={{ color: 'var(--txt-3)' }}>—</span>}</Td>
                      <Td><StatusBadgeC status={c.status} colors={C_STATUS_COLORS} /></Td>
                      <Td>{c.material_deadline ? <span className="mono" style={{ fontSize: 11 }}>{new Date(c.material_deadline).toLocaleDateString('ro-RO')}</span> : <span style={{ color: 'var(--txt-3)' }}>—</span>}</Td>
                      <Td>{(() => {
                        const s = creatorsByCampaign[c.id] || { total: 0, published: 0 };
                        if (s.total === 0) return <span style={{ color: 'var(--txt-3)' }}>—</span>;
                        return <span style={{ fontSize: 12 }}><strong style={{ color: 'var(--accent-1)' }}>{s.published}</strong> / {s.total} publicați</span>;
                      })()}</Td>
                      <Td>{manager ? manager.full_name : <span style={{ color: 'var(--txt-3)' }}>—</span>}</Td>
                      <Td><span className="mono" style={{ fontSize: 11, color: 'var(--txt-3)' }}>{new Date(c.created_at).toLocaleDateString('ro-RO')}</span></Td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <window.PaginationControl
        totalItems={filteredCampaigns.length}
        currentPage={safePage}
        perPage={perPage}
        onPageChange={setCurrentPage}
        onPerPageChange={(v) => { setPerPage(v); setCurrentPage(1); }}
      />
      </>
      )}

      {viewMode === 'calendar' && (
        <CampaignCalendar campaigns={filteredCampaigns} onSelectCampaign={setSelectedCampaign} />
      )}

      {selectedCampaign && (
        <CampaignDrawer
          campaign={selectedCampaign}
          brands={brands}
          staffList={staffList}
          onClose={() => setSelectedCampaign(null)}
          onUpdate={() => { setRefreshKey(k => k + 1); setSelectedCampaign(null); }}
        />
      )}

      {showCreateDrawer && (
        <CampaignCreateDrawer
          brands={brands}
          staffList={staffList}
          onClose={() => setShowCreateDrawer(false)}
          onCreate={() => { setRefreshKey(k => k + 1); setShowCreateDrawer(false); }}
        />
      )}
    </MediaAdminLayout>
  );
}

function Th({ children }) {
  return <th style={{ textAlign: 'left', padding: '14px 16px', fontWeight: 600, fontSize: 11, color: 'var(--txt-3)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{children}</th>;
}
function Td({ children }) {
  return <td style={{ padding: '14px 16px', color: 'var(--txt-1)' }}>{children}</td>;
}
function ThSortable({ children, sortKey, currentSort, currentDir, onSort }) {
  const isActive = sortKey && currentSort === sortKey;
  const clickable = !!sortKey;
  return (
    <th
      onClick={clickable ? () => onSort(sortKey) : undefined}
      style={{
        textAlign: 'left', padding: '14px 16px', fontWeight: 600, fontSize: 11,
        color: isActive ? 'var(--accent-1)' : 'var(--txt-3)',
        textTransform: 'uppercase', letterSpacing: '0.05em',
        cursor: clickable ? 'pointer' : 'default',
        userSelect: 'none'
      }}
    >
      {children}
      {isActive && <span style={{ marginLeft: 6 }}>{currentDir === 'asc' ? '↑' : '↓'}</span>}
    </th>
  );
}
function StatusBadgeC({ status, colors }) {
  const c = colors[status] || { bg: 'rgba(255,255,255,.05)', color: 'var(--txt-2)' };
  return <span style={{ fontSize: 11, padding: '4px 10px', borderRadius: 6, background: c.bg, color: c.color, fontWeight: 500 }}>{status}</span>;
}

function waNormalizePhone(phone, country) {
  if (!phone) return '';
  let digits = String(phone).replace(/\D/g, '');
  if (digits.startsWith('00')) {
    digits = digits.slice(2);
  } else if (digits.startsWith('0')) {
    const prefix = country === 'Republica Moldova' ? '373' : '40';
    digits = prefix + digits.slice(1);
  }
  return digits;
}

function CampaignDrawer({ campaign, brands, staffList, onClose, onUpdate }) {
  const [name, setName] = useStateMC(campaign.name);
  const [brandId, setBrandId] = useStateMC(campaign.brand_id || '');
  const [campaignTypes, setCampaignTypes] = useStateMC(campaign.campaign_types || []);
  const [status, setStatus] = useStateMC(campaign.status);
  const [startDate, setStartDate] = useStateMC(campaign.start_date || '');
  const [endDate, setEndDate] = useStateMC(campaign.end_date || '');
  const [materialDeadline, setMaterialDeadline] = useStateMC(campaign.material_deadline || '');
  const [budgetTotal, setBudgetTotal] = useStateMC(campaign.budget_total || '');
  const [brief, setBrief] = useStateMC(campaign.brief || '');
  const [internalNotes, setInternalNotes] = useStateMC(campaign.internal_notes || '');
  const [assignedTo, setAssignedTo] = useStateMC(campaign.assigned_to || '');
  const [saving, setSaving] = useStateMC(false);
  const [errorMsg, setErrorMsg] = useStateMC('');

  const [creators, setCreators] = useStateMC([]);
  const [influencers, setInfluencers] = useStateMC([]);
  const [showAddCreator, setShowAddCreator] = useStateMC(false);
  const [selectedCreator, setSelectedCreator] = useStateMC(null);
  const [creatorsRefreshKey, setCreatorsRefreshKey] = useStateMC(0);

  useEffectMC(() => {
    (async () => {
      const [{ data: cc }, { data: infs }] = await Promise.all([
        window.sb.from('campaign_creators').select('*').eq('campaign_id', campaign.id),
        window.sb.from('influencer_applications').select('id, full_name, email, tiktok_handle, tiktok_followers, backstage_id, phone, country, county, city, niches').order('full_name'),
      ]);
      setCreators(cc || []);
      setInfluencers(infs || []);
    })();
  }, [creatorsRefreshKey, campaign.id]);

  const toggleType = (t) => {
    setCampaignTypes(prev => prev.includes(t) ? prev.filter(x => x !== t) : [...prev, t]);
  };

  const handleSave = async () => {
    setSaving(true); setErrorMsg('');
    try {
      const { error } = await window.sb.from('campaigns').update({
        name: name.trim(),
        brand_id: brandId || null,
        campaign_types: campaignTypes,
        status,
        start_date: startDate || null,
        end_date: endDate || null,
        material_deadline: materialDeadline || null,
        budget_total: budgetTotal ? parseFloat(budgetTotal) : null,
        brief: brief.trim() || null,
        internal_notes: internalNotes.trim() || null,
        assigned_to: assignedTo || null,
      }).eq('id', campaign.id);
      if (error) { setErrorMsg('Eroare: ' + error.message); setSaving(false); return; }
      setSaving(false);
      onUpdate();
    } catch (err) { setErrorMsg('Conexiune eșuată.'); setSaving(false); }
  };

  return (
    <div className="ma-modal-wrap" onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 100, display: 'grid', placeItems: 'center', background: 'rgba(0,0,0,.6)', backdropFilter: 'blur(4px)' }}>
      <div className="ma-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 900, width: '90vw', maxHeight: '90vh', overflow: 'auto', background: '#0a0a0a', border: '.5px solid var(--line)', borderRadius: 16, padding: 32 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
          <h2 className="display" style={{ fontSize: 22, margin: 0 }}>Detalii campanie</h2>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: 'var(--txt-2)', fontSize: 22, cursor: 'pointer', padding: 4 }}>✕</button>
        </div>

        <EditField label="Nume campanie">
          <input type="text" value={name} onChange={e => setName(e.target.value)} className="input" style={{ width: '100%' }} />
        </EditField>

        <EditField label="Brand asociat">
          <select value={brandId} onChange={e => setBrandId(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
            <option value="" style={{ backgroundColor: '#1a1a1a' }}>— Niciun brand —</option>
            {brands.map(b => <option key={b.id} value={b.id} style={{ backgroundColor: '#1a1a1a' }}>{b.brand ? (b.brand + ' (' + b.company + ')') : b.company}</option>)}
          </select>
        </EditField>

        <EditField label="Tipuri campanie (selectează multiple)">
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {CAMPAIGN_TYPES_OPTIONS.map(t => (
              <button key={t} onClick={() => toggleType(t)} type="button" style={{
                padding: '8px 14px', borderRadius: 8, fontSize: 12, cursor: 'pointer',
                border: campaignTypes.includes(t) ? '1px solid var(--accent-1)' : '.5px solid var(--line)',
                background: campaignTypes.includes(t) ? 'rgba(82,242,15,.1)' : 'transparent',
                color: campaignTypes.includes(t) ? 'var(--accent-1)' : 'var(--txt-2)'
              }}>{t}</button>
            ))}
          </div>
        </EditField>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12 }}>
          <EditField label="Status">
            <select value={status} onChange={e => setStatus(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
              {C_STATUS_OPTIONS.map(s => <option key={s} value={s} style={{ backgroundColor: '#1a1a1a' }}>{s}</option>)}
            </select>
          </EditField>
          <EditField label="Manager campanie">
            <select value={assignedTo} onChange={e => setAssignedTo(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
              <option value="" style={{ backgroundColor: '#1a1a1a' }}>— Nealocat —</option>
              {staffList.map(s => <option key={s.id} value={s.id} style={{ backgroundColor: '#1a1a1a' }}>{s.full_name}</option>)}
            </select>
          </EditField>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12 }}>
          <EditField label="Data start">
            <input type="date" value={startDate} onChange={e => setStartDate(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }} />
          </EditField>
          <EditField label="Data end">
            <input type="date" value={endDate} onChange={e => setEndDate(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }} />
          </EditField>
          <EditField label="Deadline material">
            <input type="date" value={materialDeadline} onChange={e => setMaterialDeadline(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }} />
          </EditField>
        </div>

        <EditField label="Buget total (RON)">
          <input type="number" min="0" step="0.01" value={budgetTotal} onChange={e => setBudgetTotal(e.target.value)} className="input" style={{ width: '100%' }} />
        </EditField>

        <EditField label="Brief campanie">
          <textarea value={brief} onChange={e => setBrief(e.target.value)} rows={8} className="input" style={{ width: '100%', resize: 'vertical', minHeight: 180, height: 'auto', padding: '12px 14px', fontFamily: 'inherit', lineHeight: 1.6 }} placeholder="Descriere campanie, ce trebuie să facă creatorii..." />
        </EditField>

        <EditField label="Note interne">
          <textarea value={internalNotes} onChange={e => setInternalNotes(e.target.value)} rows={6} className="input" style={{ width: '100%', resize: 'vertical', minHeight: 140, height: 'auto', padding: '12px 14px', fontFamily: 'inherit', lineHeight: 1.7 }} placeholder="Observații, follow-up, etc." />
        </EditField>

        {/* SECTION DOCUMENTE */}
        <CampaignDocumentsSection campaignId={campaign.id} />

        {errorMsg && <div style={{ marginTop: 16, padding: '10px 12px', borderRadius: 8, background: 'rgba(255,90,90,.08)', border: '.5px solid rgba(255,100,100,.3)', fontSize: 12, color: 'var(--txt-2)' }}>⚠️ {errorMsg}</div>}

        <button onClick={handleSave} disabled={saving} className="btn btn-primary" style={{ width: '100%', marginTop: 20, opacity: saving ? 0.6 : 1 }}>
          {saving ? 'Se salvează...' : 'Salvează modificările'}
        </button>

        {/* SECTION CREATORI ALOCAȚI */}
        <div style={{ marginTop: 40, padding: 20, borderRadius: 12, background: 'rgba(82,242,15,.03)', border: '1px solid rgba(82,242,15,.15)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
            <h3 style={{ fontSize: 14, margin: 0, color: 'var(--accent-1)' }}>👥 Creatori alocați ({creators.length})</h3>
            <button onClick={() => setShowAddCreator(true)} className="btn btn-glass btn-sm">+ Alocă creator</button>
          </div>

          {creators.length === 0 ? (
            <div style={{ padding: 24, textAlign: 'center', color: 'var(--txt-3)', fontSize: 13 }}>Niciun creator alocat încă.</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {creators.map(cc => {
                const inf = influencers.find(i => i.id === cc.influencer_id);
                if (!inf) return null;
                return (
                  <div key={cc.id} onClick={() => setSelectedCreator(cc)} style={{ padding: 12, borderRadius: 8, background: 'rgba(255,255,255,.02)', border: '.5px solid var(--line)', cursor: 'pointer', transition: 'background .15s' }}
                    onMouseEnter={e => e.currentTarget.style.background = 'rgba(82,242,15,.05)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'rgba(255,255,255,.02)'}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4, gap: 8 }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
                        <strong style={{ fontSize: 13 }}>{inf.full_name}</strong>
                        <button
                          type="button"
                          disabled={!inf.phone}
                          onClick={(e) => {
                            e.stopPropagation();
                            const phone = waNormalizePhone(inf.phone, inf.country);
                            if (!phone) return;
                            const brand = brands.find(b => b.id === campaign.brand_id);
                            const brandName = brand ? (brand.brand || brand.company) : '';
                            const msg = `Salut ${inf.full_name}, ai fost selectat pentru campania ${campaign.name} de la ${brandName} prin 4U Agency. \u{1F389} Revenim în curând cu toate detaliile!`;
                            window.open(`https://wa.me/${phone}?text=${encodeURIComponent(msg)}`, '_blank');
                          }}
                          title={inf.phone ? 'Trimite mesaj WhatsApp' : 'Telefon lipsă'}
                          style={{
                            padding: '3px 10px',
                            fontSize: 11,
                            borderRadius: 6,
                            border: '.5px solid rgba(37,211,102,.3)',
                            background: inf.phone ? 'rgba(37,211,102,.08)' : 'rgba(255,255,255,.03)',
                            color: inf.phone ? '#25D366' : 'var(--txt-3)',
                            cursor: inf.phone ? 'pointer' : 'not-allowed',
                            fontWeight: 500,
                            whiteSpace: 'nowrap',
                          }}
                        >
                          📱 WhatsApp
                        </button>
                      </div>
                      <StatusBadgeC status={cc.status} colors={CC_STATUS_COLORS} />
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--txt-3)' }}>
                      {inf.tiktok_handle && <span>@{inf.tiktok_handle}</span>}
                      {cc.payment_status && <span style={{ marginLeft: 12 }}>💰 {cc.payment_status}</span>}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {showAddCreator && (
          <AddCreatorModal
            campaignId={campaign.id}
            existingCreators={creators}
            influencers={influencers}
            onClose={() => setShowAddCreator(false)}
            onAdd={() => setCreatorsRefreshKey(k => k + 1)}
          />
        )}

        {selectedCreator && (
          <CreatorAllocationDrawer
            allocation={selectedCreator}
            influencer={influencers.find(i => i.id === selectedCreator.influencer_id)}
            onClose={() => setSelectedCreator(null)}
            onUpdate={() => { setCreatorsRefreshKey(k => k + 1); setSelectedCreator(null); }}
          />
        )}
      </div>
    </div>
  );
}

function CampaignCreateDrawer({ brands, staffList, onClose, onCreate }) {
  const [name, setName] = useStateMC('');
  const [brandId, setBrandId] = useStateMC('');
  const [assignedTo, setAssignedTo] = useStateMC('');
  const [saving, setSaving] = useStateMC(false);
  const [errorMsg, setErrorMsg] = useStateMC('');

  const handleCreate = async () => {
    if (!name.trim()) { setErrorMsg('Numele campaniei e obligatoriu.'); return; }
    setSaving(true); setErrorMsg('');
    try {
      const { error } = await window.sb.from('campaigns').insert({
        name: name.trim(),
        brand_id: brandId || null,
        assigned_to: assignedTo || null,
        status: 'Draft',
      });
      if (error) { setErrorMsg('Eroare: ' + error.message); setSaving(false); return; }
      setSaving(false);
      onCreate();
    } catch (err) { setErrorMsg('Conexiune eșuată.'); setSaving(false); }
  };

  return (
    <div className="ma-modal-wrap" onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 100, display: 'grid', placeItems: 'center', background: 'rgba(0,0,0,.6)', backdropFilter: 'blur(4px)' }}>
      <div className="ma-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 900, width: '90vw', maxHeight: '90vh', overflow: 'auto', background: '#0a0a0a', border: '.5px solid var(--line)', borderRadius: 16, padding: 32 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
          <h2 className="display" style={{ fontSize: 22, margin: 0 }}>Campanie nouă</h2>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: 'var(--txt-2)', fontSize: 22, cursor: 'pointer', padding: 4 }}>✕</button>
        </div>

        <p style={{ fontSize: 13, color: 'var(--txt-2)', marginBottom: 24 }}>Completează minimul necesar. Restul detaliilor (date, buget, brief) le adaugi după creare în detaliile campaniei.</p>

        <EditField label="Nume campanie *">
          <input type="text" value={name} onChange={e => setName(e.target.value)} className="input" style={{ width: '100%' }} placeholder="ex: Vară 2026 - Pepsi" />
        </EditField>

        <EditField label="Brand asociat">
          <select value={brandId} onChange={e => setBrandId(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
            <option value="" style={{ backgroundColor: '#1a1a1a' }}>— Niciun brand (alegi mai târziu) —</option>
            {brands.map(b => <option key={b.id} value={b.id} style={{ backgroundColor: '#1a1a1a' }}>{b.brand ? (b.brand + ' (' + b.company + ')') : b.company}</option>)}
          </select>
        </EditField>

        <EditField label="Manager">
          <select value={assignedTo} onChange={e => setAssignedTo(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
            <option value="" style={{ backgroundColor: '#1a1a1a' }}>— Nealocat —</option>
            {staffList.map(s => <option key={s.id} value={s.id} style={{ backgroundColor: '#1a1a1a' }}>{s.full_name}</option>)}
          </select>
        </EditField>

        {errorMsg && <div style={{ marginTop: 16, padding: '10px 12px', borderRadius: 8, background: 'rgba(255,90,90,.08)', border: '.5px solid rgba(255,100,100,.3)', fontSize: 12, color: 'var(--txt-2)' }}>⚠️ {errorMsg}</div>}

        <button onClick={handleCreate} disabled={saving} className="btn btn-primary" style={{ width: '100%', marginTop: 20, opacity: saving ? 0.6 : 1 }}>
          {saving ? 'Se creează...' : 'Creează campania'}
        </button>
      </div>
    </div>
  );
}

function AddCreatorModal({ campaignId, existingCreators, influencers, onClose, onAdd }) {
  const [search, setSearch] = useStateMC('');
  const [adding, setAdding] = useStateMC(null);
  const [hoveredInfId, setHoveredInfId] = useStateMC(null);
  const [confirmRemoveInfId, setConfirmRemoveInfId] = useStateMC(null);
  const [countryFilter, setCountryFilter] = useStateMC('');
  const [countyFilter, setCountyFilter] = useStateMC('');
  const [cityFilter, setCityFilter] = useStateMC('');
  const [nicheFilter, setNicheFilter] = useStateMC([]);
  const [minFollowers, setMinFollowers] = useStateMC('');
  const [maxFollowers, setMaxFollowers] = useStateMC('');

  const existingCreatorIds = existingCreators.map(c => c.influencer_id);

  const toggleNiche = (n) => {
    setNicheFilter(prev => prev.includes(n) ? prev.filter(x => x !== n) : [...prev, n]);
  };

  const filtered = influencers.filter(i => {
    if (search) {
      const s = search.toLowerCase();
      if (!i.full_name.toLowerCase().includes(s) && !(i.tiktok_handle || '').toLowerCase().includes(s)) return false;
    }
    if (countryFilter && i.country !== countryFilter) return false;
    if (countyFilter && i.county !== countyFilter) return false;
    if (cityFilter && i.city !== cityFilter) return false;
    if (nicheFilter.length > 0) {
      if (!Array.isArray(i.niches) || !i.niches.some(n => nicheFilter.includes(n))) return false;
    }
    if (minFollowers !== '') {
      const min = parseInt(minFollowers, 10);
      if (!Number.isNaN(min) && (i.tiktok_followers == null || i.tiktok_followers < min)) return false;
    }
    if (maxFollowers !== '') {
      const max = parseInt(maxFollowers, 10);
      if (!Number.isNaN(max) && (i.tiktok_followers == null || i.tiktok_followers > max)) return false;
    }
    return true;
  });

  const handleAdd = async (infId) => {
    if (existingCreatorIds.includes(infId)) return;
    setAdding(infId);
    const { error } = await window.sb.from('campaign_creators').insert({
      campaign_id: campaignId,
      influencer_id: infId,
      status: 'Invitat',
      payment_status: 'Neplătit',
    });
    if (error) { alert('Eroare: ' + error.message); setAdding(null); return; }
    setAdding(null);
    onAdd();
  };

  const handleRemoveConfirmed = async () => {
    const infId = confirmRemoveInfId;
    const allocation = existingCreators.find(c => c.influencer_id === infId);
    setConfirmRemoveInfId(null);
    setHoveredInfId(null);
    if (!allocation) return;
    const { error } = await window.sb.from('campaign_creators').delete().eq('id', allocation.id);
    if (error) { alert('Eroare: ' + error.message); return; }
    onAdd();
  };

  const niches = window.NICHES_OPTIONS || [];
  const confirmInfluencer = confirmRemoveInfId ? influencers.find(i => i.id === confirmRemoveInfId) : null;

  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 200, background: 'rgba(0,0,0,.8)', backdropFilter: 'blur(6px)', display: 'grid', placeItems: 'center', padding: 24 }}>
      <div onClick={e => e.stopPropagation()} className="card-glass" style={{ width: '100%', maxWidth: 720, maxHeight: '80vh', display: 'flex', flexDirection: 'column' }}>
        {/* Header (fix) */}
        <div style={{ padding: 24, borderBottom: '.5px solid var(--line)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h3 className="display" style={{ fontSize: 18, margin: 0 }}>Alocă creator pe campanie</h3>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: 'var(--txt-2)', fontSize: 22, cursor: 'pointer' }}>✕</button>
        </div>

        {/* Search + filtre (fix) */}
        <div style={{ padding: 24, paddingBottom: 16, display: 'flex', flexDirection: 'column', gap: 12 }}>
          <input type="text" placeholder="🔍 Caută după nume sau handle TikTok..." value={search} onChange={e => setSearch(e.target.value)} className="input" style={{ width: '100%' }} />

          <div>
            <div style={{ fontSize: 12, color: 'var(--txt-0)', fontWeight: 600, marginBottom: 6 }}>Locație (țară / județ / oraș)</div>
            <window.CountryCascade
              country={countryFilter} county={countyFilter} city={cityFilter}
              setCountry={setCountryFilter} setCounty={setCountyFilter} setCity={setCityFilter}
              required={false} showLabels={false} allowClear={true}
            />
          </div>

          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <div style={{ flex: 1, minWidth: 140 }}>
              <div style={{ fontSize: 12, color: 'var(--txt-0)', fontWeight: 600, marginBottom: 6 }}>Followers de la</div>
              <input type="number" min="0" value={minFollowers} onChange={e => setMinFollowers(e.target.value)} className="input" style={{ width: '100%' }} placeholder="ex: 1000" />
            </div>
            <div style={{ flex: 1, minWidth: 140 }}>
              <div style={{ fontSize: 12, color: 'var(--txt-0)', fontWeight: 600, marginBottom: 6 }}>Followers până la</div>
              <input type="number" min="0" value={maxFollowers} onChange={e => setMaxFollowers(e.target.value)} className="input" style={{ width: '100%' }} placeholder="ex: 100000" />
            </div>
          </div>

          <div>
            <div style={{ fontSize: 12, color: 'var(--txt-0)', fontWeight: 600, marginBottom: 6 }}>Nișe (multi-select)</div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
              {niches.map(n => {
                const active = nicheFilter.includes(n);
                return (
                  <button key={n} type="button" onClick={() => toggleNiche(n)} style={{
                    padding: '6px 12px', borderRadius: 6, fontSize: 12, cursor: 'pointer',
                    border: active ? '1px solid var(--accent-1)' : '.5px solid var(--line)',
                    background: active ? 'rgba(82,242,15,.1)' : 'transparent',
                    color: active ? 'var(--accent-1)' : 'var(--txt-2)'
                  }}>{n}</button>
                );
              })}
            </div>
          </div>
        </div>

        {/* Lista (singura zonă cu scroll) */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 24px 24px', minHeight: 0 }}>
          {filtered.length === 0 ? (
            <div style={{ padding: 40, textAlign: 'center', color: 'var(--txt-3)' }}>Niciun creator nu corespunde filtrelor.</div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {filtered.map(i => {
                const isAllocated = existingCreatorIds.includes(i.id);
                const isAdding = adding === i.id;
                return (
                  <div key={i.id} style={{ padding: 12, borderRadius: 8, background: 'rgba(255,255,255,.02)', border: '.5px solid var(--line)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 12 }}>
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <div style={{ fontSize: 13, fontWeight: 600 }}>{i.full_name}</div>
                      <div style={{ fontSize: 11, color: 'var(--txt-3)' }}>
                        {i.tiktok_handle && <span>@{i.tiktok_handle}</span>}
                        {i.tiktok_followers && <span style={{ marginLeft: 8 }}>{i.tiktok_followers.toLocaleString('ro-RO')} followers</span>}
                      </div>
                    </div>
                    {isAllocated ? (() => {
                      const hovered = hoveredInfId === i.id;
                      return (
                        <button
                          type="button"
                          onMouseEnter={() => setHoveredInfId(i.id)}
                          onMouseLeave={() => setHoveredInfId(null)}
                          onClick={() => setConfirmRemoveInfId(i.id)}
                          title="Scoate de pe campanie"
                          style={{
                            padding: '6px 14px', fontSize: 12, borderRadius: 6,
                            background: hovered ? 'rgba(255,90,90,.12)' : 'rgba(82,242,15,.1)',
                            color: hovered ? '#FF5A5A' : 'var(--accent-1)',
                            border: hovered ? '.5px solid rgba(255,90,90,.4)' : '.5px solid rgba(82,242,15,.3)',
                            cursor: 'pointer', fontWeight: 500, whiteSpace: 'nowrap',
                            transition: 'background .15s, color .15s, border-color .15s',
                          }}
                        >{hovered ? '✗ Scoate' : '✓ Alocat'}</button>
                      );
                    })() : (
                      <button onClick={() => handleAdd(i.id)} disabled={isAdding} className="btn btn-glass btn-sm">
                        {isAdding ? '...' : '+ Alocă'}
                      </button>
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {confirmRemoveInfId && (
          <window.ConfirmDialog
            title="Confirmare scoatere"
            message={`Ești sigur că vrei să elimini ${confirmInfluencer ? confirmInfluencer.full_name : 'acest creator'} din campanie?`}
            confirmText="Da, elimină"
            cancelText="Anulează"
            danger={true}
            onConfirm={handleRemoveConfirmed}
            onCancel={() => setConfirmRemoveInfId(null)}
          />
        )}
      </div>
    </div>
  );
}

function CreatorAllocationDrawer({ allocation, influencer, onClose, onUpdate }) {
  const [status, setStatus] = useStateMC(allocation.status);
  const [materialUrl, setMaterialUrl] = useStateMC(allocation.material_url || '');
  const [publishedUrl, setPublishedUrl] = useStateMC(allocation.published_url || '');
  const [paymentAmount, setPaymentAmount] = useStateMC(allocation.payment_amount || '');
  const [paymentStatus, setPaymentStatus] = useStateMC(allocation.payment_status);
  const [internalNotes, setInternalNotes] = useStateMC(allocation.internal_notes || '');
  const [saving, setSaving] = useStateMC(false);
  const [errorMsg, setErrorMsg] = useStateMC('');
  const [confirmRemove, setConfirmRemove] = useStateMC(false);

  const handleSave = async () => {
    setSaving(true); setErrorMsg('');
    try {
      const updates = {
        status, payment_status: paymentStatus,
        material_url: materialUrl.trim() || null,
        published_url: publishedUrl.trim() || null,
        payment_amount: paymentAmount ? parseFloat(paymentAmount) : null,
        internal_notes: internalNotes.trim() || null,
      };
      // Set timestamps automat când statusul se schimbă
      if (status === 'Material trimis' && materialUrl && !allocation.material_sent_at) updates.material_sent_at = new Date().toISOString();
      if (status === 'Publicat' && publishedUrl && !allocation.published_at) updates.published_at = new Date().toISOString();
      if (paymentStatus === 'Plătit' && !allocation.paid_at) updates.paid_at = new Date().toISOString();

      const { error } = await window.sb.from('campaign_creators').update(updates).eq('id', allocation.id);
      if (error) { setErrorMsg('Eroare: ' + error.message); setSaving(false); return; }
      setSaving(false); onUpdate();
    } catch (err) { setErrorMsg('Conexiune eșuată.'); setSaving(false); }
  };

  const handleRemove = () => setConfirmRemove(true);

  const performRemove = async () => {
    setConfirmRemove(false);
    const { error } = await window.sb.from('campaign_creators').delete().eq('id', allocation.id);
    if (error) { alert('Eroare: ' + error.message); return; }
    onUpdate();
  };

  if (!influencer) return null;

  return (
    <div className="ma-modal-wrap" onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 200, display: 'grid', placeItems: 'center', background: 'rgba(0,0,0,.7)', backdropFilter: 'blur(6px)' }}>
      <div className="ma-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 900, width: '90vw', maxHeight: '90vh', overflow: 'auto', background: '#0a0a0a', border: '.5px solid var(--line)', borderRadius: 16, padding: 32 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
          <h2 className="display" style={{ fontSize: 20, margin: 0 }}>{influencer.full_name}</h2>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: 'var(--txt-2)', fontSize: 22, cursor: 'pointer' }}>✕</button>
        </div>
        <div style={{ fontSize: 12, color: 'var(--txt-3)', marginBottom: 24 }}>
          {influencer.tiktok_handle && <span>@{influencer.tiktok_handle}</span>}
          {influencer.tiktok_followers && <span style={{ marginLeft: 8 }}>· {influencer.tiktok_followers.toLocaleString('ro-RO')} followers</span>}
          {influencer.backstage_id && <span style={{ marginLeft: 8 }}>· ID: {influencer.backstage_id}</span>}
        </div>

        <EditField label="Status">
          <select value={status} onChange={e => setStatus(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
            {CC_STATUS_OPTIONS.map(s => <option key={s} value={s} style={{ backgroundColor: '#1a1a1a' }}>{s}</option>)}
          </select>
        </EditField>

        <EditField label="Link material trimis">
          <input type="url" value={materialUrl} onChange={e => setMaterialUrl(e.target.value)} className="input" style={{ width: '100%' }} placeholder="https://..." />
          {allocation.material_sent_at && <div style={{ fontSize: 11, color: 'var(--txt-3)', marginTop: 4 }}>Primit la: {new Date(allocation.material_sent_at).toLocaleString('ro-RO')}</div>}
        </EditField>

        <EditField label="Link post publicat">
          <input type="url" value={publishedUrl} onChange={e => setPublishedUrl(e.target.value)} className="input" style={{ width: '100%' }} placeholder="https://tiktok.com/..." />
          {allocation.published_at && <div style={{ fontSize: 11, color: 'var(--txt-3)', marginTop: 4 }}>Publicat la: {new Date(allocation.published_at).toLocaleString('ro-RO')}</div>}
        </EditField>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <EditField label="Plată (RON)">
            <input type="number" min="0" step="0.01" value={paymentAmount} onChange={e => setPaymentAmount(e.target.value)} className="input" style={{ width: '100%' }} />
          </EditField>
          <EditField label="Status plată">
            <select value={paymentStatus} onChange={e => setPaymentStatus(e.target.value)} className="input" style={{ width: '100%', color: '#FFFFFF', backgroundColor: '#1a1a1a' }}>
              {CC_PAYMENT_STATUS_OPTIONS.map(s => <option key={s} value={s} style={{ backgroundColor: '#1a1a1a' }}>{s}</option>)}
            </select>
          </EditField>
        </div>
        {allocation.paid_at && <div style={{ fontSize: 11, color: 'var(--txt-3)', marginTop: -8, marginBottom: 16 }}>Plătit la: {new Date(allocation.paid_at).toLocaleString('ro-RO')}</div>}

        <EditField label="Note interne">
          <textarea value={internalNotes} onChange={e => setInternalNotes(e.target.value)} rows={3} className="input" style={{ width: '100%', resize: 'vertical', minHeight: 60, fontFamily: 'inherit' }} />
        </EditField>

        {errorMsg && <div style={{ marginTop: 16, padding: '10px 12px', borderRadius: 8, background: 'rgba(255,90,90,.08)', border: '.5px solid rgba(255,100,100,.3)', fontSize: 12, color: 'var(--txt-2)' }}>⚠️ {errorMsg}</div>}

        <button onClick={handleSave} disabled={saving} className="btn btn-primary" style={{ width: '100%', marginTop: 12, opacity: saving ? 0.6 : 1 }}>
          {saving ? 'Se salvează...' : 'Salvează'}
        </button>
        <button onClick={handleRemove} className="btn btn-glass" style={{ width: '100%', marginTop: 8, color: '#FF5A5A' }}>
          Scoate de pe campanie
        </button>

        {confirmRemove && (
          <window.ConfirmDialog
            title="Confirmare scoatere"
            message={`Ești sigur că vrei să elimini ${influencer ? influencer.full_name : 'acest creator'} din campanie?`}
            confirmText="Da, elimină"
            cancelText="Anulează"
            danger={true}
            onConfirm={performRemove}
            onCancel={() => setConfirmRemove(false)}
          />
        )}
      </div>
    </div>
  );
}

function EditField({ label, children }) {
  return (
    <div style={{ marginBottom: 16 }}>
      <label className="mono" style={{ fontSize: 10, color: 'var(--txt-3)', letterSpacing: '0.1em', marginBottom: 6, display: 'block' }}>{label.toUpperCase()}</label>
      {children}
    </div>
  );
}

function CampaignCalendar({ campaigns, onSelectCampaign }) {
  const today = new Date();
  const [monthDate, setMonthDate] = useStateMC(new Date(today.getFullYear(), today.getMonth(), 1));

  const year = monthDate.getFullYear();
  const month = monthDate.getMonth();

  const parseISO = (s) => {
    if (!s) return null;
    const [y, m, d] = String(s).split('-').map(Number);
    if (!y || !m || !d) return null;
    return new Date(y, m - 1, d);
  };

  const sameYMD = (a, b) => a && b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();

  // First-day offset: vrem Mon=0 ... Sun=6
  const firstDay = new Date(year, month, 1);
  const firstDayOffset = (firstDay.getDay() + 6) % 7;
  const lastOfMonth = new Date(year, month + 1, 0);
  const totalCells = Math.ceil((firstDayOffset + lastOfMonth.getDate()) / 7) * 7;

  const cells = [];
  for (let i = 0; i < totalCells; i++) {
    const dayNum = i - firstDayOffset + 1;
    const date = new Date(year, month, dayNum);
    cells.push({ date, inMonth: date.getMonth() === month });
  }

  const campaignsOnDay = (date) => {
    const dT = date.getTime();
    return campaigns.filter(c => {
      const s = parseISO(c.start_date);
      const e = parseISO(c.end_date);
      if (!s && !e) return false;
      if (s && e) return dT >= s.getTime() && dT <= e.getTime();
      if (s) return sameYMD(date, s);
      return sameYMD(date, e);
    });
  };

  const deadlinesOnDay = (date) => campaigns.filter(c => {
    const d = parseISO(c.material_deadline);
    return d && sameYMD(date, d);
  });

  const goPrev = () => setMonthDate(new Date(year, month - 1, 1));
  const goNext = () => setMonthDate(new Date(year, month + 1, 1));
  const goToday = () => { const t = new Date(); setMonthDate(new Date(t.getFullYear(), t.getMonth(), 1)); };

  const monthLabel = monthDate.toLocaleDateString('ro-RO', { month: 'long', year: 'numeric' });
  const weekDays = ['Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm', 'Dum'];
  const todayRef = new Date();

  const navBtn = {
    padding: '6px 12px', fontSize: 13, borderRadius: 8,
    background: 'rgba(255,255,255,.04)', border: '.5px solid var(--line)',
    color: 'var(--txt-1)', cursor: 'pointer', fontWeight: 500,
  };

  return (
    <div className="card-glass" style={{ padding: 20 }}>
      {/* Navigare */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16, gap: 12, flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button type="button" onClick={goPrev} style={navBtn} title="Luna anterioară">‹</button>
          <h2 className="display" style={{ margin: 0, fontSize: 18, textTransform: 'capitalize', minWidth: 180, textAlign: 'center' }}>{monthLabel}</h2>
          <button type="button" onClick={goNext} style={navBtn} title="Luna următoare">›</button>
        </div>
        <button type="button" onClick={goToday} style={{ ...navBtn, padding: '6px 14px' }}>Azi</button>
      </div>

      {/* Capete coloane (zile) */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4, marginBottom: 4 }}>
        {weekDays.map(d => (
          <div key={d} style={{ fontSize: 11, color: 'var(--txt-3)', textTransform: 'uppercase', letterSpacing: '0.05em', textAlign: 'center', padding: '6px 0', fontWeight: 600 }}>{d}</div>
        ))}
      </div>

      {/* Grid lunar */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 4 }}>
        {cells.map((cell, idx) => {
          const onDay = campaignsOnDay(cell.date);
          const deadlines = deadlinesOnDay(cell.date);
          const isToday = sameYMD(cell.date, todayRef);
          const MAX_VISIBLE = 3;
          const visibleCamps = onDay.slice(0, MAX_VISIBLE);
          const hidden = onDay.length - visibleCamps.length;
          return (
            <div key={idx} style={{
              minHeight: 110,
              padding: 6,
              borderRadius: 8,
              border: '.5px solid var(--line)',
              background: cell.inMonth ? 'rgba(255,255,255,.02)' : 'rgba(255,255,255,.005)',
              opacity: cell.inMonth ? 1 : 0.45,
              display: 'flex', flexDirection: 'column', gap: 3,
              overflow: 'hidden',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', minHeight: 22 }}>
                <span style={{
                  fontSize: 12,
                  fontWeight: isToday ? 700 : 500,
                  color: isToday ? '#000' : 'var(--txt-2)',
                  background: isToday ? 'var(--accent-1)' : 'transparent',
                  borderRadius: 6,
                  padding: isToday ? '2px 8px' : '2px 0',
                  lineHeight: 1,
                }}>{cell.date.getDate()}</span>
                {deadlines.length > 0 && (
                  <span title={deadlines.map(d => 'Deadline material: ' + d.name).join('\n')}
                    style={{ fontSize: 13, color: 'var(--accent-2)', lineHeight: 1 }}>⚑</span>
                )}
              </div>

              {visibleCamps.map(c => {
                const col = C_STATUS_COLORS[c.status] || { bg: 'rgba(255,255,255,.05)', color: 'var(--txt-2)' };
                return (
                  <div key={c.id} onClick={() => onSelectCampaign(c)} title={c.name + ' · ' + c.status}
                    style={{
                      fontSize: 10, padding: '3px 6px', borderRadius: 4,
                      background: col.bg, color: col.color,
                      cursor: 'pointer',
                      whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                      fontWeight: 500,
                    }}
                  >{c.name}</div>
                );
              })}
              {hidden > 0 && (
                <div style={{ fontSize: 10, color: 'var(--txt-3)', textAlign: 'center', padding: '1px 0' }}>+ {hidden} {hidden === 1 ? 'altă' : 'alte'}</div>
              )}

              {deadlines.map(d => (
                <div key={'dl-' + d.id} onClick={() => onSelectCampaign(d)} title={'Deadline material: ' + d.name}
                  style={{
                    fontSize: 10, padding: '3px 6px', borderRadius: 4,
                    background: 'rgba(255,215,0,.12)',
                    color: 'var(--accent-2)',
                    border: '.5px dashed rgba(255,215,0,.5)',
                    cursor: 'pointer',
                    whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                    fontWeight: 500,
                  }}
                >⚑ {d.name}</div>
              ))}
            </div>
          );
        })}
      </div>

      {/* Legendă */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, marginTop: 16, paddingTop: 12, borderTop: '.5px solid var(--line)', fontSize: 11, color: 'var(--txt-3)' }}>
        {C_STATUS_OPTIONS.map(s => {
          const col = C_STATUS_COLORS[s];
          return (
            <div key={s} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <span style={{ width: 12, height: 12, borderRadius: 3, background: col.bg, border: '.5px solid ' + col.color, display: 'inline-block' }} />
              <span>{s}</span>
            </div>
          );
        })}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ color: 'var(--accent-2)', fontSize: 13 }}>⚑</span>
          <span>Deadline material</span>
        </div>
      </div>
    </div>
  );
}

function CampaignDocumentsSection({ campaignId }) {
  const [docs, setDocs] = useStateMC([]);
  const [loading, setLoading] = useStateMC(true);
  const [uploading, setUploading] = useStateMC(false);
  const [drag, setDrag] = useStateMC(false);
  const [staffId, setStaffId] = useStateMC(null);
  const [errorMsg, setErrorMsg] = useStateMC('');
  const [confirmDeleteDoc, setConfirmDeleteDoc] = useStateMC(null);
  const fileInputRef = useRefMC(null);

  const fetchDocs = async () => {
    const { data, error } = await window.sb
      .from('campaign_attachments')
      .select('*')
      .eq('campaign_id', campaignId)
      .order('created_at', { ascending: false });
    if (!error) setDocs(data || []);
    setLoading(false);
  };

  useEffectMC(() => {
    (async () => {
      try {
        const { data: { session } } = await window.sb.auth.getSession();
        setStaffId(session?.user?.id || null);
      } catch (e) { /* ignore */ }
    })();
    fetchDocs();
  }, [campaignId]);

  const sanitize = (name) => name.replace(/[^\w.\-]+/g, '_');

  const genUuid = () => {
    if (typeof crypto !== 'undefined' && crypto.randomUUID) return crypto.randomUUID();
    return Date.now() + '-' + Math.random().toString(36).slice(2, 10);
  };

  const handleFiles = async (fileList) => {
    if (!fileList || fileList.length === 0) return;
    setUploading(true); setErrorMsg('');
    const files = Array.from(fileList);
    for (const file of files) {
      try {
        const path = `${campaignId}/${genUuid()}-${sanitize(file.name)}`;
        const { error: upErr } = await window.sb.storage
          .from('campaign-attachments')
          .upload(path, file, {
            contentType: file.type || 'application/octet-stream',
            upsert: false,
          });
        if (upErr) { setErrorMsg('Eroare upload "' + file.name + '": ' + upErr.message); continue; }
        const { error: insErr } = await window.sb
          .from('campaign_attachments')
          .insert({
            campaign_id: campaignId,
            file_path: path,
            file_name: file.name,
            file_size: file.size,
            mime_type: file.type || null,
            uploaded_by: staffId || null,
          });
        if (insErr) {
          await window.sb.storage.from('campaign-attachments').remove([path]);
          setErrorMsg('Eroare salvare "' + file.name + '": ' + insErr.message);
          continue;
        }
      } catch (e) {
        setErrorMsg('Eroare "' + file.name + '": ' + (e.message || 'necunoscută'));
      }
    }
    setUploading(false);
    if (fileInputRef.current) fileInputRef.current.value = '';
    await fetchDocs();
  };

  const handleDownload = async (doc) => {
    const { data, error } = await window.sb.storage
      .from('campaign-attachments')
      .createSignedUrl(doc.file_path, 60 * 60);
    if (error || !data?.signedUrl) {
      setErrorMsg('Nu pot deschide fișierul: ' + (error?.message || 'eroare necunoscută'));
      return;
    }
    window.open(data.signedUrl, '_blank');
  };

  const performDelete = async () => {
    const doc = confirmDeleteDoc;
    setConfirmDeleteDoc(null);
    if (!doc) return;
    await window.sb.storage.from('campaign-attachments').remove([doc.file_path]);
    const { error } = await window.sb.from('campaign_attachments').delete().eq('id', doc.id);
    if (error) { setErrorMsg('Eroare ștergere: ' + error.message); return; }
    fetchDocs();
  };

  const formatSize = (bytes) => {
    if (bytes == null) return '';
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
    if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
    return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB';
  };

  return (
    <div style={{ marginTop: 24, padding: 20, borderRadius: 12, background: 'rgba(82,242,15,.03)', border: '1px solid rgba(82,242,15,.15)' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
        <h3 style={{ fontSize: 14, margin: 0, color: 'var(--accent-1)' }}>📎 Documente ({docs.length})</h3>
      </div>

      <div
        onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={(e) => { e.preventDefault(); setDrag(false); if (!uploading) handleFiles(e.dataTransfer.files); }}
        onClick={() => { if (!uploading) fileInputRef.current?.click(); }}
        style={{
          border: drag ? '2px solid var(--accent-1)' : '2px dashed rgba(82,242,15,.3)',
          borderRadius: 10,
          padding: '24px 16px',
          textAlign: 'center',
          cursor: uploading ? 'not-allowed' : 'pointer',
          background: drag ? 'rgba(82,242,15,.06)' : 'rgba(82,242,15,.02)',
          transition: 'all .15s',
          marginBottom: 12,
        }}
      >
        <input
          ref={fileInputRef}
          type="file"
          multiple
          style={{ display: 'none' }}
          onChange={(e) => handleFiles(e.target.files)}
        />
        <div style={{ fontSize: 28, marginBottom: 6 }}>{uploading ? '⏳' : '📤'}</div>
        <div style={{ fontSize: 13, fontWeight: 500, color: uploading ? 'var(--txt-3)' : 'var(--txt-1)' }}>
          {uploading ? 'Se încarcă...' : 'Trage fișierele aici sau click pentru a selecta'}
        </div>
        <div style={{ fontSize: 11, color: 'var(--txt-3)', marginTop: 4 }}>
          Mai multe fișiere, orice tip · Doar staff intern
        </div>
      </div>

      {errorMsg && (
        <div style={{ marginBottom: 12, padding: '10px 12px', borderRadius: 8, background: 'rgba(255,90,90,.08)', border: '.5px solid rgba(255,100,100,.3)', fontSize: 12, color: 'var(--txt-2)' }}>
          ⚠️ {errorMsg}
        </div>
      )}

      {loading ? (
        <div style={{ padding: 16, textAlign: 'center', color: 'var(--txt-3)', fontSize: 12 }}>Se încarcă lista...</div>
      ) : docs.length === 0 ? (
        <div style={{ padding: 16, textAlign: 'center', color: 'var(--txt-3)', fontSize: 12 }}>Niciun document încărcat încă.</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {docs.map(doc => (
            <div key={doc.id}
              style={{
                display: 'flex', alignItems: 'center', gap: 10,
                padding: '10px 12px', borderRadius: 8,
                background: 'rgba(255,255,255,.02)', border: '.5px solid var(--line)',
                transition: 'background .15s',
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'rgba(82,242,15,.04)'}
              onMouseLeave={e => e.currentTarget.style.background = 'rgba(255,255,255,.02)'}
            >
              <div style={{ fontSize: 18, flexShrink: 0 }}>📄</div>
              <div
                onClick={() => handleDownload(doc)}
                style={{ flex: 1, minWidth: 0, cursor: 'pointer' }}
                title="Click pentru a descărca"
              >
                <div style={{ fontSize: 13, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {doc.file_name}
                </div>
                <div style={{ fontSize: 11, color: 'var(--txt-3)', marginTop: 2 }}>
                  {formatSize(doc.file_size)}{doc.file_size != null ? ' · ' : ''}{new Date(doc.created_at).toLocaleString('ro-RO')}
                </div>
              </div>
              <button
                type="button"
                onClick={() => handleDownload(doc)}
                title="Descarcă"
                style={{
                  padding: '6px 10px', fontSize: 12, borderRadius: 6,
                  border: '.5px solid rgba(82,242,15,.3)',
                  background: 'rgba(82,242,15,.08)',
                  color: 'var(--accent-1)',
                  cursor: 'pointer',
                  flexShrink: 0,
                  fontWeight: 500,
                }}
              >
                ↓
              </button>
              <button
                type="button"
                onClick={() => setConfirmDeleteDoc(doc)}
                title="Șterge"
                style={{
                  padding: '6px 10px', fontSize: 12, borderRadius: 6,
                  border: '.5px solid rgba(255,90,90,.3)',
                  background: 'rgba(255,90,90,.06)',
                  color: '#FF5A5A',
                  cursor: 'pointer',
                  flexShrink: 0,
                }}
              >
                ✕
              </button>
            </div>
          ))}
        </div>
      )}

      {confirmDeleteDoc && (
        <window.ConfirmDialog
          title="Ștergere document"
          message={`Ești sigur că vrei să ștergi acest document? „${confirmDeleteDoc.file_name}"`}
          confirmText="Da, șterge"
          cancelText="Anulează"
          danger={true}
          onConfirm={performDelete}
          onCancel={() => setConfirmDeleteDoc(null)}
        />
      )}
    </div>
  );
}

window.MediaAdminCampaigns = MediaAdminCampaigns;
