const { useState: useStateL, useEffect: useEffectL } = React;

// Backend status <-> kanban column mapping
const STATUS_TO_STAGE = {
  'new': 'new',
  'qualified': 'contacted',
  'shown_properties': 'qualified',
  'interested': 'showing',
  'won': 'offer',
  // 'cold' and 'lost' have no kanban column — they'll fall through to 'new'
  'cold': 'new',
  'lost': 'new'
};
const STAGE_TO_STATUS = {
  'new': 'new',
  'contacted': 'qualified',
  'qualified': 'shown_properties',
  'showing': 'interested',
  'offer': 'won'
};

// Transform a backend lead row into a kanban card
function leadToCard(l) {
  const bedrooms = l.preferred_bedrooms ? l.preferred_bedrooms + ' BR' : '';
  const type = l.preferred_type ? l.preferred_type.toUpperCase() : '';
  const areasArr = Array.isArray(l.preferred_areas) ? l.preferred_areas : [];
  const area = areasArr[0] || '';
  const isSessionPhone = typeof l.phone === 'string' && l.phone.startsWith('s-');
  const displayPhone = l.contact_phone || (isSessionPhone ? window.__t('leads.phonePending') : l.phone);
  const inWord = (window.__lang === 'ar') ? 'في' : 'in';
  const parts = [type || bedrooms, area ? inWord + ' ' + area : '', displayPhone && !isSessionPhone ? '· ' + displayPhone : ''].filter(Boolean);
  const addr = parts.join(' ') || (l.contact_phone ? window.__t('leads.contact') + ': ' + l.contact_phone : window.__t('leads.discovery'));

  const budgetQar = l.budget_max ? Number(l.budget_max) : (l.budget_min ? Number(l.budget_min) : null);
  let budget = 'TBD';
  if (budgetQar && budgetQar > 0) {
    if (budgetQar >= 1000000) budget = (budgetQar / 1000000).toFixed(1);
    else budget = (budgetQar / 1000).toFixed(0) + 'K';
  }

  const scoreMap = { 'new': 3, 'qualified': 3, 'shown_properties': 4, 'interested': 4, 'won': 5, 'cold': 2, 'lost': 1 };
  const score = scoreMap[l.status] || 3;

  const days = l.created_at ? Math.floor((Date.now() - new Date(l.created_at).getTime()) / (1000 * 60 * 60 * 24)) : 0;

  return {
    id: l.id,
    name: l.name || 'Unknown',
    addr,
    budget,
    score,
    agent: 'AI',
    days,
    src: window.__t('leads.src.web'),
    stage: STATUS_TO_STAGE[l.status] || 'new',
    _raw: l
  };
}

const LeadCard = ({ lead, onDragStart, onDragEnd, dragging, pulsing }) => {
  const maxScore = 5;
  const isHot = lead.score >= 4;
  const cardRef = React.useRef(null);
  React.useEffect(() => {
    if (pulsing && cardRef.current) cardRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' });
  }, [pulsing]);
  return (
    <div
      ref={cardRef}
      className={`lead-card ${dragging ? 'dragging' : ''} ${pulsing ? 'is-pulsing' : ''}`}
      draggable
      onDragStart={(e) => { e.dataTransfer.effectAllowed = 'move'; onDragStart(lead.id); }}
      onDragEnd={onDragEnd}
    >
      <div className="top">
        <div style={{ flex: 1 }}>
          <div className="name">{lead.name}</div>
          <div className="addr">{lead.addr}</div>
        </div>
        <button style={{ width: 22, height: 22, color: 'var(--fg-3)' }} title="More">
          <Icon name="more" size={14} />
        </button>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <div className="price"><span className="cur">QAR</span>{lead.budget}{typeof lead.budget === 'string' && lead.budget !== 'TBD' && !lead.budget.endsWith('K') ? 'M' : ''}</div>
        <span className={`score ${isHot ? 'hot' : ''}`}>
          {isHot ? 'HOT' : 'WARM'}
          <span className="bar">
            {Array.from({ length: maxScore }).map((_, i) => (
              <i key={i} className={i < lead.score ? 'on' : ''} />
            ))}
          </span>
        </span>
      </div>
      <div className="foot">
        <div className="avatars">
          <div className="a">{lead.agent}</div>
        </div>
        <span>{lead.src}</span>
        <span>{lead.days}d</span>
      </div>
    </div>
  );
};

// Mock leads from data.js are treated as demo data — shown to every user as visual context.
// They live only in local state; drag-drop on them updates UI but NOT the DB.
const MOCK_LEADS = (window.__data?.leads || []).map(l => ({
  ...l,
  _isMock: true
}));

function isMockId(id) { return typeof id === 'string' && /^l\d+$/.test(id); }

const Leads = () => {
  const [realLeads, setRealLeads] = useStateL([]);
  const [mockLeads, setMockLeads] = useStateL(MOCK_LEADS);
  const [loading, setLoading] = useStateL(true);
  const [error, setError] = useStateL('');
  const [draggedId, setDraggedId] = useStateL(null);
  const [hoverStage, setHoverStage] = useStateL(null);
  const [filter, setFilter] = useStateL('all');
  const [refreshTick, setRefreshTick] = useStateL(0);
  const [pulseId, setPulseId] = useStateL(null);

  // Tutorial popup stashes the freshly-created lead id in window.__pulseRowId
  // before navigating here. Pick it up and pulse the matching card.
  useEffectL(() => {
    if (!window.__pulseRowId) return;
    if (realLeads.some(l => l.id === window.__pulseRowId)) {
      setPulseId(window.__pulseRowId);
      window.__pulseRowId = null;
      const t = setTimeout(() => setPulseId(null), 8000);
      return () => clearTimeout(t);
    }
  }, [realLeads]);

  // Fetch real leads from re_leads (RLS scopes to current user)
  useEffectL(() => {
    let cancelled = false;
    setLoading(true);
    window.__api.sbGet('re_leads', {
      'select': 'id,phone,contact_phone,name,language,intent,budget_min,budget_max,preferred_type,preferred_bedrooms,preferred_areas,status,notes,created_at,updated_at',
      'order': 'created_at.desc',
      'limit': '100'
    }).then(rows => {
      if (cancelled) return;
      setRealLeads((rows || []).map(leadToCard));
      setLoading(false);
    }).catch(e => {
      if (cancelled) return;
      console.error('leads fetch failed:', e);
      setError(e.message);
      setLoading(false);
    });
    return () => { cancelled = true; };
  }, [refreshTick]);

  const leads = [...realLeads, ...mockLeads];
  const setLeads = (updater) => {
    // Separate updates to real vs mock based on id
    if (typeof updater === 'function') {
      const next = updater(leads);
      setRealLeads(next.filter(l => !isMockId(l.id)));
      setMockLeads(next.filter(l => isMockId(l.id)));
    } else {
      setRealLeads(updater.filter(l => !isMockId(l.id)));
      setMockLeads(updater.filter(l => isMockId(l.id)));
    }
  };

  // Auto-refresh every 10s so leads created via chat show up
  useEffectL(() => {
    const interval = setInterval(() => setRefreshTick(t => t + 1), 10000);
    return () => clearInterval(interval);
  }, []);

  const stageValue = (stageKey) => leads.filter(l => l.stage === stageKey).reduce((s, l) => {
    const num = parseFloat(l.budget);
    return s + (isNaN(num) ? 0 : num);
  }, 0);

  const onDrop = async (e, stageKey) => {
    e.preventDefault();
    const id = draggedId;
    setDraggedId(null);
    setHoverStage(null);
    if (!id) return;
    const prev = leads.find(l => l.id === id);
    if (!prev || prev.stage === stageKey) return;

    // Mock leads update local state only
    if (isMockId(id)) {
      setMockLeads(ls => ls.map(l => l.id === id ? { ...l, stage: stageKey } : l));
      return;
    }

    // Real leads — optimistic update + persist to Supabase
    setRealLeads(ls => ls.map(l => l.id === id ? { ...l, stage: stageKey } : l));
    const newStatus = STAGE_TO_STATUS[stageKey] || 'new';
    try {
      await window.__api.sbPatch('re_leads', { 'id': 'eq.' + id }, { status: newStatus, updated_at: new Date().toISOString() });
    } catch (err) {
      console.error('stage update failed:', err);
      // Rollback
      setRealLeads(ls => ls.map(l => l.id === id ? { ...l, stage: prev.stage } : l));
    }
  };

  const filtered = filter === 'all' ? leads : leads.filter(l => l.score >= 4);
  const totalVal = leads.reduce((s, l) => {
    const num = parseFloat(l.budget);
    return s + (isNaN(num) ? 0 : num);
  }, 0);

  const t = (k) => window.__t(k);
  return (
    <div className="content view">
      <div className="section-head">
        <div>
          <div className="sub" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {loading ? <span className="spinner sm" /> : `${leads.length} ${leads.length === 1 ? t('leads.header.active') : t('leads.header.active.plural')} · QAR ${totalVal.toFixed(1)}M ${t('leads.header.pipeline')}`}
            {error && <span style={{ color: 'var(--neg)', marginLeft: 10 }}>· {error}</span>}
          </div>
          <h2>{t('title.leads')}</h2>
        </div>
        <div style={{ display: 'flex', gap: 10 }}>
          <div className="pill-tabs">
            <button className={filter === 'all' ? 'active' : ''} onClick={() => setFilter('all')}>{t('leads.filter.all')}</button>
            <button className={filter === 'hot' ? 'active' : ''} onClick={() => setFilter('hot')}>{t('leads.filter.hot')}</button>
          </div>
          <button className="btn" onClick={() => setRefreshTick(x => x + 1)}><Icon name="sort" size={13} /> {t('leads.refresh')}</button>
          <button className="btn"><Icon name="filter" size={13} /> {t('leads.filter')}</button>
        </div>
      </div>

      {loading && leads.length === 0 ? (
        <div className="loading-block" style={{ padding: 60 }}><div className="spinner lg" /></div>
      ) : (
        <div className="kanban">
          {window.__data.stages.map((s, i) => {
            const stageLabel = window.__t('stage.' + s.key) || s.name;
            const stageLeads = filtered.filter(l => l.stage === s.key);
            const val = stageLeads.reduce((sum, l) => {
              const num = parseFloat(l.budget);
              return sum + (isNaN(num) ? 0 : num);
            }, 0);
            const totalStage = leads.filter(l => l.stage === s.key).length;
            const barMax = Math.max(...window.__data.stages.map(st => stageValue(st.key))) || 1;
            const fillPct = (stageValue(s.key) / barMax) * 100;
            return (
              <div
                key={s.key}
                className={`col ${hoverStage === s.key ? 'drop-target' : ''}`}
                onDragOver={(e) => { e.preventDefault(); setHoverStage(s.key); }}
                onDragLeave={() => setHoverStage(h => h === s.key ? null : h)}
                onDrop={(e) => onDrop(e, s.key)}
              >
                <div className="col-head">
                  <div className="row">
                    <div className="name">
                      <span className="dot" style={{ background: i === 4 ? 'var(--maroon)' : 'var(--fg)' }} />
                      {stageLabel}
                    </div>
                    <div className="count">{totalStage}</div>
                  </div>
                  <div className="value">QAR {val.toFixed(1)}M</div>
                  <div className="bar"><div className="fill" style={{ width: `${fillPct}%`, background: i === 4 ? 'var(--maroon)' : 'var(--fg)' }} /></div>
                </div>
                <div className="col-body">
                  {stageLeads.map(l => (
                    <LeadCard key={l.id} lead={l} dragging={draggedId === l.id} pulsing={pulseId === l.id} onDragStart={setDraggedId} onDragEnd={() => { setDraggedId(null); setHoverStage(null); }} />
                  ))}
                  {stageLeads.length === 0 && (
                    <div style={{ border: '1px dashed var(--line-2)', padding: 16, fontSize: 12, color: 'var(--fg-4)', textAlign: 'center', borderRadius: 2 }}>
                      {t('leads.empty.drop')}
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}

      <div style={{ marginTop: 18, fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--fg-4)', textTransform: 'uppercase', letterSpacing: '0.12em' }}>
        {t('leads.tip')}
      </div>
    </div>
  );
};

window.Leads = Leads;
