// Venues diagnostic tab — dynamic over-indexing classifications (Greens vs Reds)
// Accessible only to SLT, Region, and Area roles

function VenuesView({ allowedVenueIds, onSelectVenue }) {
  const [showMoreGreens, setShowMoreGreens] = React.useState(false);
  const [showMoreReds, setShowMoreReds] = React.useState(false);
  const [query, setQuery] = React.useState('');
  const [sortKey, setSortKey] = React.useState(''); // '' (natural), or clause.metricKey
  const [sortDir, setSortDir] = React.useState('desc'); // 'asc' | 'desc'

  // Reset sorting config when query text changes
  React.useEffect(() => {
    setSortKey('');
    setSortDir('desc');
  }, [query]);

  // Define segments for each classification
  const greenKeys = [
    "DS1 - Experience Players",
    "DS2 - Prize-Oriented Players",
    "Power Players",
    "Social Squad",
    "Holiday Heros"
  ];
  const redKeys = [
    "Casual",
    "Drifters",
    "Dormant",
    "Budget",
    "Heavy Hitters",
    "Prize Chasers"
  ];

  // Helper to compute combined segment shares
  const getCombinedShare = (data, keys) => {
    if (!data || !data.segments || data.segments.length === 0) return 0;
    const totalUsers = data.totalUsers || data.segments.reduce((sum, s) => sum + (s.userCount || 0), 0);
    if (totalUsers === 0) return 0;
    
    const targetUsers = data.segments
      .filter(s => keys.includes(s.key))
      .reduce((sum, s) => sum + (s.userCount || 0), 0);
    
    return targetUsers / totalUsers;
  };

  // 1. Compute Active Group Benchmark (represents overall group aggregate)
  const benchmarkData = React.useMemo(() => {
    return SEGMENT_DATA.getSegmentData('ALL', allowedVenueIds);
  }, [allowedVenueIds]);

  const benchmarkGreenShare = React.useMemo(() => getCombinedShare(benchmarkData, greenKeys), [benchmarkData]);
  const benchmarkRedShare = React.useMemo(() => getCombinedShare(benchmarkData, redKeys), [benchmarkData]);

  // 2. Parse and calculate shares for each allowed store on-the-fly
  const venueDiagnostics = React.useMemo(() => {
    const individualIds = allowedVenueIds.filter(id => id !== 'ALL');
    
    const list = individualIds.map(vId => {
      const storeData = SEGMENT_DATA.getSegmentData(vId);
      const name = storeData.name || window.VENUE_METADATA[vId]?.name || `Venue ${vId}`;
      
      const greenShare = getCombinedShare(storeData, greenKeys);
      const redShare = getCombinedShare(storeData, redKeys);

      return {
        id: vId,
        name: name,
        greenShare,
        redShare,
        greenDiff: greenShare - benchmarkGreenShare,
        redDiff: redShare - benchmarkRedShare
      };
    }).filter(v => v.greenShare > 0 || v.redShare > 0);

    // Classify into Greens and Reds
    // Greens: combined high-value/regular segment share is HIGHER than the benchmark
    const greens = list
      .filter(v => v.greenDiff > 0)
      .sort((a, b) => b.greenDiff - a.greenDiff);

    // Reds: combined casual/high-cost segment share is HIGHER than the benchmark
    const reds = list
      .filter(v => v.redDiff > 0)
      .sort((a, b) => b.redDiff - a.redDiff);

    return { greens, reds };
  }, [allowedVenueIds, benchmarkGreenShare, benchmarkRedShare]);

  // --- Upgraded Multi-Clause (AND/OR) Synonym NLP Query Engine ---
  const parseQueryClause = (clauseText) => {
    const str = clauseText.trim();
    if (!str) return null;

    // Determine sort direction (top/bottom)
    const bottomKeywords = ['lowest', 'bottom', 'fewer', 'worst', 'underperform', 'least', 'low', 'minimum', 'min', 'fewest', 'weakest', 'underperforming', 'decline', 'declining', 'drop', 'dropped', 'loss', 'losing', 'least-active', 'quietest'];
    const topKeywords = ['highest', 'top', 'most', 'best', 'high', 'greatest', 'max', 'maximum', 'biggest', 'leader', 'leaders', 'rank 1', 'highest-performing', 'performance', 'expanding', 'growth', 'grow', 'gain', 'gained', 'gains', 'busiest', 'busy', 'traffic', 'popular', 'most-played', 'most-played'];

    let isBottom = bottomKeywords.some(kw => str.includes(kw));
    let isTop = topKeywords.some(kw => str.includes(kw));
    if (!isBottom && !isTop) isTop = true; // default to top

    // Determine target metric using rich synonym sets
    let metricKey = 'revenue';
    let metricLabel = 'Revenue';
    let metricFormat = 'idr';

    // Segment Name Matching (Highest Priority)
    const segMetas = [
      { key: "DS1 - Experience Players", kws: ['ds1', 'experience players', 'experience segment'] },
      { key: "DS2 - Prize-Oriented Players", kws: ['ds2', 'prize-oriented players', 'prize oriented', 'prize players'] },
      { key: "Power Players", kws: ['power players', 'power segment', 'power player'] },
      { key: "Social Squad", kws: ['social squad', 'social segment', 'social players'] },
      { key: "Holiday Heros", kws: ['holiday heros', 'holiday heroes', 'holiday segment'] },
      { key: "Casual", kws: ['casual', 'casuals', 'casual segment'] },
      { key: "Drifters", kws: ['drifters', 'drifter', 'drifter segment'] },
      { key: "Budget", kws: ['budget', 'budget segment', 'budget players'] },
      { key: "Dormant", kws: ['dormant', 'dormant segment', 'dormants'] },
      { key: "Heavy Hitters", kws: ['heavy hitters', 'heavy hitter', 'heavy segment'] },
      { key: "Prize Chasers", kws: ['prize chasers', 'prize chaser', 'prize chasers segment'] },
      { key: "Outlier", kws: ['outlier', 'outliers', 'outliers segment'] }
    ];

    let matchedSeg = null;
    for (const seg of segMetas) {
      if (seg.kws.some(kw => str.includes(kw))) {
        matchedSeg = seg;
        break;
      }
    }

    if (matchedSeg) {
      metricKey = matchedSeg.key;
      metricLabel = matchedSeg.key.split(' - ')[0] + ' Share';
      metricFormat = 'pct';
    } else {
      const redemptionKeywords = ['redemption', 'redeem', 'prizes', 'prize', 'trophy', 'trophies', 'claim', 'claimed', 'gift', 'gifts', 'tixred', 'shop'];
      const guestKeywords = ['guest', 'guests', 'user', 'users', 'customer', 'customers', 'visitor', 'visitors', 'people', 'size', 'base', 'pop', 'population', 'crowd', 'footfall'];
      const playKeywords = ['plays', 'play', 'game', 'games', 'gameplay', 'activity', 'active', 'machine', 'machines'];
      const profitKeywords = ['profit', 'profitability', 'margin', 'margins', 'gp1', 'gp2', 'profitable', 'efficient', 'efficiency', 'earned', 'earning', 'earnings', 'gain', 'gains'];

      if (str.includes('gp2%') || str.includes('gp2 %') || str.includes('gp2 percentage') || str.includes('profit margin') || str.includes('profitability') || str.includes('margins') || str.includes('margin')) {
        metricKey = 'gp2Pct';
        metricLabel = 'GP2 % (Profit Margin)';
        metricFormat = 'pct';
      } else if (str.includes('gp2') || str.includes('gross profit 2') || str.includes('gp 2')) {
        metricKey = 'gp2';
        metricLabel = 'GP2 (IDR)';
        metricFormat = 'idr';
      } else if (str.includes('gp1%') || str.includes('gp1 %') || str.includes('gp1 percentage') || str.includes('gp 1%') || str.includes('gp 1 percentage')) {
        metricKey = 'gp1Pct';
        metricLabel = 'GP1 %';
        metricFormat = 'pct';
      } else if (str.includes('gp1') || str.includes('gross profit 1') || str.includes('gp 1')) {
        metricKey = 'gp1';
        metricLabel = 'GP1 (IDR)';
        metricFormat = 'idr';
      } else if (str.includes('vending') || str.includes('vending cost') || str.includes('machine cost') || str.includes('operating cost')) {
        metricKey = 'vendingCost';
        metricLabel = 'Vending Cost (IDR)';
        metricFormat = 'idr';
      } else if (str.includes('liability') || str.includes('unclaimed ticket') || str.includes('unclaimed ticket cost') || str.includes('liability cost')) {
        metricKey = 'liability';
        metricLabel = 'Liability (IDR)';
        metricFormat = 'idr';
      } else if (str.includes('plays per guest') || str.includes('avg plays') || str.includes('average plays') || str.includes('plays average') || str.includes('gameavg')) {
        metricKey = 'gameAvg';
        metricLabel = 'Avg Plays';
        metricFormat = 'dec1';
      } else if (str.includes('tickets won') || str.includes('won tickets') || str.includes('won tix') || str.includes('tix won') || str.includes('earned tickets')) {
        metricKey = 'tixWon';
        metricLabel = 'Tickets Won';
        metricFormat = 'num';
      } else if (str.includes('tickets redeemed') || str.includes('redeemed tickets') || str.includes('redeemed tix') || str.includes('tix redeemed') || str.includes('spent tickets')) {
        metricKey = 'tixRed';
        metricLabel = 'Tickets Redeemed';
        metricFormat = 'num';
      } else if (str.includes('redeem / won') || str.includes('redeem won ratio') || str.includes('redemption rate') || str.includes('tixpct')) {
        metricKey = 'tixPct';
        metricLabel = 'Redemption Rate';
        metricFormat = 'pct';
      } else if (str.includes('visit average') || str.includes('avg visit') || str.includes('average visit') || str.includes('visitavg')) {
        metricKey = 'visitAvg';
        metricLabel = 'Avg Visits';
        metricFormat = 'dec1';
      } else if (str.includes('dwell average') || str.includes('avg dwell') || str.includes('average dwell') || str.includes('dwellavg')) {
        metricKey = 'dwellAvg';
        metricLabel = 'Avg Dwell';
        metricFormat = 'mins';
      } else if (str.includes('visit interval') || str.includes('avg interval') || str.includes('average interval') || str.includes('intervalavg')) {
        metricKey = 'intervalAvg';
        metricLabel = 'Avg Interval';
        metricFormat = 'days';
      } else if (redemptionKeywords.some(kw => str.includes(kw))) {
        metricKey = 'redemptionAmt';
        metricLabel = 'Redemption (IDR)';
        metricFormat = 'idr';
      } else if (guestKeywords.some(kw => str.includes(kw))) {
        metricKey = 'userCount';
        metricLabel = 'Total Guests';
        metricFormat = 'num';
      } else if (playKeywords.some(kw => str.includes(kw))) {
        metricKey = 'gameTotal';
        metricLabel = 'Total Plays';
        metricFormat = 'num';
      } else if (profitKeywords.some(kw => str.includes(kw))) {
        metricKey = 'gp2Pct';
        metricLabel = 'Profit Margin';
        metricFormat = 'pct';
      }
    }

    return {
      isBottom,
      metricKey,
      metricLabel,
      metricFormat
    };
  };

  const parseQuery = (text) => {
    if (!text.trim()) return null;
    const str = text.toLowerCase().trim();

    // 1. Determine Region matching (Region 1 to 5, reg 1, r1, rg1, etc.)
    let targetRegion = '';
    const regMatch = str.match(/\b(?:region|reg|r|rg)\s*([1-5])\b/);
    if (regMatch) {
      targetRegion = `Region ${regMatch[1]}`;
    }

    // 2. Determine Area matching (checking major words of the areas)
    let targetArea = '';
    const areas = window.VENUE_AUTH.getAreas();
    const queryWords = str.split(/[\s,.\-+*\/]+/);
    for (const area of areas) {
      const areaWords = area.toLowerCase().split(/[\s,.\-+*\/]+/).filter(w => w.length > 2);
      const matchesArea = areaWords.some(aw => queryWords.includes(aw)) || str.includes(area.toLowerCase().replace(/[^a-z0-9]/g, ''));
      if (matchesArea) {
        targetArea = area;
        break;
      }
    }

    // 3. Extract row count limit
    const numMatch = str.match(/\b\d+\b/);
    let limit = 10;
    if (numMatch) {
      const parsedNum = parseInt(numMatch[0]);
      if (!(regMatch && parsedNum === parseInt(regMatch[1]))) {
        limit = parsedNum;
      }
    }

    // 4. Split clauses by logical operators (AND/OR) and commas
    const isOr = str.includes(' or ') || str.includes('||');
    const operator = isOr ? 'OR' : 'AND';
    const clausesText = str.split(/\s+(?:and|or|&&|\|\|)\s+|\s*,\s*/);

    const parsedClauses = clausesText
      .map(cText => parseQueryClause(cText))
      .filter(Boolean);

    if (parsedClauses.length === 0) return null;

    return {
      limit,
      targetRegion,
      targetArea,
      operator,
      clauses: parsedClauses
    };
  };

  const queryResult = React.useMemo(() => {
    const qParams = parseQuery(query);
    if (!qParams) return null;

    const individualIds = allowedVenueIds.filter(id => id !== 'ALL');
    let list = individualIds.map(vId => {
      const storeData = SEGMENT_DATA.getSegmentData(vId);
      const meta = window.VENUE_METADATA[vId];
      if (!storeData) return null;

      // Extract values for all parsed clauses
      const clauseValues = qParams.clauses.map(clause => {
        let val = 0;
        const getSum = (key) => storeData.segments.reduce((s, x) => s + (x[key] || 0), 0);

        const segKeysList = [
          "DS1 - Experience Players", "DS2 - Prize-Oriented Players", "Power Players", "Social Squad", "Holiday Heros",
          "Casual", "Drifters", "Dormant", "Budget", "Heavy Hitters", "Prize Chasers", "Outlier"
        ];

        if (segKeysList.includes(clause.metricKey)) {
          const targetSeg = storeData.segments.find(s => s.key === clause.metricKey);
          const totalU = storeData.totalUsers || getSum('userCount');
          val = (targetSeg && totalU > 0) ? (targetSeg.userCount / totalU) : 0;
        } else if (clause.metricKey === 'gp2Pct') {
          const rev = storeData.totalRevenue || 0;
          const gp1 = rev - (getSum('redemptionAmt') + getSum('vendingCost'));
          const gp2 = gp1 - getSum('liability');
          val = rev > 0 ? gp2 / rev : 0;
        } else if (clause.metricKey === 'gp2') {
          const rev = storeData.totalRevenue || 0;
          const gp1 = rev - (getSum('redemptionAmt') + getSum('vendingCost'));
          val = gp1 - getSum('liability');
        } else if (clause.metricKey === 'gp1Pct') {
          const rev = storeData.totalRevenue || 0;
          const gp1 = rev - (getSum('redemptionAmt') + getSum('vendingCost'));
          val = rev > 0 ? gp1 / rev : 0;
        } else if (clause.metricKey === 'gp1') {
          const rev = storeData.totalRevenue || 0;
          val = rev - (getSum('redemptionAmt') + getSum('vendingCost'));
        } else if (clause.metricKey === 'vendingCost') {
          val = getSum('vendingCost');
        } else if (clause.metricKey === 'liability') {
          val = getSum('liability');
        } else if (clause.metricKey === 'gameAvg') {
          const totalU = storeData.totalUsers || getSum('userCount');
          val = totalU > 0 ? getSum('gameTotal') / totalU : 0;
        } else if (clause.metricKey === 'tixWon') {
          val = getSum('tixWon');
        } else if (clause.metricKey === 'tixRed') {
          val = getSum('tixRed');
        } else if (clause.metricKey === 'tixPct') {
          const won = getSum('tixWon');
          val = won > 0 ? getSum('tixRed') / won : 0;
        } else if (clause.metricKey === 'visitAvg') {
          const totalU = storeData.totalUsers || getSum('userCount');
          val = totalU > 0 ? storeData.segments.reduce((s, x) => s + (x.visitAvg || 0) * (x.userCount || 0), 0) / totalU : 0;
        } else if (clause.metricKey === 'dwellAvg') {
          const totalVisits = storeData.segments.reduce((s, x) => s + (x.totalVisits || 0), 0);
          val = totalVisits > 0 ? storeData.segments.reduce((s, x) => s + (x.dwellAvg || 0) * (x.totalVisits || 0), 0) / totalVisits : 0;
        } else if (clause.metricKey === 'intervalAvg') {
          const totalU = storeData.totalUsers || getSum('userCount');
          val = totalU > 0 ? storeData.segments.reduce((s, x) => s + (x.intervalAvg || 0) * (x.userCount || 0), 0) / totalU : 0;
        } else if (clause.metricKey === 'userCount') {
          val = storeData.totalUsers || getSum('userCount');
        } else if (clause.metricKey === 'redemptionAmt') {
          val = getSum('redemptionAmt');
        } else if (clause.metricKey === 'gameTotal') {
          val = getSum('gameTotal');
        } else {
          val = storeData.totalRevenue || getSum('revenue');
        }

        return { key: clause.metricKey, val };
      });

      return {
        id: vId,
        name: storeData.name || meta?.name || `Venue ${vId}`,
        region: meta?.region || 'Unknown',
        area: meta?.area || 'Unknown',
        clauseValues
      };
    }).filter(Boolean);

    // Filter list by region and area constraints
    if (qParams.targetRegion) {
      list = list.filter(v => v.region === qParams.targetRegion);
    }
    if (qParams.targetArea) {
      list = list.filter(v => v.area === qParams.targetArea);
    }

    if (list.length === 0) {
      return { params: qParams, list: [], totalCount: 0, formatters: {} };
    }

    // --- High-Performance Multicriteria Decision Index (MCDA) Scoring ---
    // Compute max values for normalizations
    const maxValues = {};
    qParams.clauses.forEach(clause => {
      const key = clause.metricKey;
      maxValues[key] = Math.max(...list.map(v => {
        const item = v.clauseValues.find(cv => cv.key === key);
        return item ? Math.abs(item.val) : 0;
      }), 0.0001);
    });

    // Score each venue (0.0 to 1.0)
    list.forEach(v => {
      const scores = qParams.clauses.map(clause => {
        const key = clause.metricKey;
        const max = maxValues[key];
        const item = v.clauseValues.find(cv => cv.key === key);
        const val = item ? item.val : 0;
        const normVal = Math.min(Math.max(val / max, 0), 1);
        return clause.isBottom ? (1.0 - normVal) : normVal; // reverse score if low value is desired
      });

      // Compound scores based on operator
      if (qParams.operator === 'AND') {
        // Geometric/product mean ensures high ratings on BOTH are required
        v.combinedScore = scores.reduce((prod, s) => prod * s, 1);
      } else {
        // Union sum
        v.combinedScore = scores.reduce((sum, s) => sum + s, 0);
      }
    });

    // Sort descending by Combined Decision Score
    list.sort((a, b) => b.combinedScore - a.combinedScore);

    // Slice to the top displayed limit first (e.g. top 10)
    const sliced = list.slice(0, qParams.limit);

    // If a secondary header sort is active, sort ONLY this displayed subset!
    if (sortKey) {
      sliced.sort((a, b) => {
        const itemA = a.clauseValues.find(cv => cv.key === sortKey);
        const itemB = b.clauseValues.find(cv => cv.key === sortKey);
        const valA = itemA ? itemA.val : 0;
        const valB = itemB ? itemB.val : 0;
        return sortDir === 'asc' ? valA - valB : valB - valA;
      });
    }

    // Compute column formatters for each metric column
    const formatters = {};
    qParams.clauses.forEach(clause => {
      const key = clause.metricKey;
      const vals = sliced.map(v => {
        const item = v.clauseValues.find(cv => cv.key === key);
        return item ? item.val : 0;
      });
      formatters[key] = fmt.columnFormatter(vals, clause.metricFormat);
    });

    return {
      params: qParams,
      list: sliced,
      totalCount: list.length,
      formatters
    };
  }, [query, allowedVenueIds, sortKey, sortDir]);

  const visibleGreens = showMoreGreens ? venueDiagnostics.greens : venueDiagnostics.greens.slice(0, 10);
  const visibleReds = showMoreReds ? venueDiagnostics.reds : venueDiagnostics.reds.slice(0, 10);

  return (
    <div className="section-grid">
      <div className="page-head">
        <div>
          <h1>Venue Diagnostics & Benchmarking</h1>
          <p>Analyzing individual venue guest profiles relative to the active group aggregate benchmark.</p>
        </div>
      </div>

      {/* Smart Query Console Card */}
      <div className="card" style={{ marginBottom: 20, padding: '24px 28px' }}>
        <div style={{ font: "700 15px 'Space Grotesk', sans-serif", color: 'var(--navy)', marginBottom: 8 }}>
          Venues Quick Finder
        </div>
        <div style={{ font: "500 12.5px 'Inter', sans-serif", color: 'var(--ink-2)', marginBottom: 16, lineHeight: '1.5', background: '#f8fafc', padding: '12px 16px', borderRadius: '8px', borderLeft: '3px solid var(--navy)' }}>
          <strong>How to use:</strong> Type natural keywords like <strong>'top'</strong>, <strong>'lowest'</strong>, <strong>'revenue'</strong>, <strong>'guests'</strong>, or specific segment names like <strong>'DS1'</strong>, <strong>'Dormant'</strong> to instantly search, rank, and compare venues. You can even combine conditions with <strong>'and'</strong> or <strong>'or'</strong> (e.g. <em>'high revenue and low redemption'</em>).
        </div>
        
        {/* Query Input Box */}
        <div style={{ position: 'relative', width: '100%', marginBottom: 14 }}>
          <input
            type="text"
            className="login-input"
            style={{ width: '100%', padding: '14px 18px 14px 44px', font: "500 13.5px 'Inter', sans-serif", border: '2px solid var(--navy)', outline: 'none' }}
            placeholder='Type keywords or segment names to search and rank...'
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
          <svg style={{ position: 'absolute', left: 16, top: '50%', transform: 'translateY(-50%)', color: 'var(--navy)' }} width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="8" cy="8" r="5" />
            <line x1="15" y1="15" x2="11.5" y2="11.5" />
          </svg>
          {query && (
            <button 
              onClick={() => setQuery('')}
              style={{ position: 'absolute', right: 16, top: '50%', transform: 'translateY(-50%)', border: 'none', background: 'none', font: "600 13px 'Space Grotesk', sans-serif", color: 'var(--red)', cursor: 'pointer' }}
            >
              Clear
            </button>
          )}
        </div>

        {/* Quick Click Query Chips */}
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
          <span style={{ fontSize: 11, fontStyle: 'italic', color: 'var(--ink-4)', marginRight: 4 }}>Common searches:</span>
          {[
            { label: 'Highest Revenue Venues', text: 'show top 10 venues by highest revenue' },
            { label: 'Highest Redemption Venues', text: 'top 5 venues by highest redemption' },
            { label: 'Top Venues by Guests', text: 'top 10 venues by highest guests' },
            { label: 'Lowest Profit Margin', text: 'lowest profit margin venues' },
            { label: 'Region 3 Outlets', text: 'venues in Region 3' }
          ].map((chip, idx) => (
            <button
              key={idx}
              className="seg-tab-pill"
              style={{ padding: '4px 12px', fontSize: 11 }}
              onClick={() => setQuery(chip.text)}
            >
              ⚡ {chip.label}
            </button>
          ))}
        </div>

        {/* Query Results Display */}
        {queryResult && (
          <div style={{ marginTop: 24, borderTop: '1px dashed var(--line)', paddingTop: 20 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12, flexWrap: 'wrap', gap: 8 }}>
              <div style={{ font: "700 14px 'Space Grotesk', sans-serif", color: 'var(--navy)' }}>
                Search Results: {queryResult.params.clauses.map(c => (c.isBottom ? 'Lowest' : 'Highest') + ' ' + c.metricLabel).join(' ' + queryResult.params.operator + ' ')} ({queryResult.list.length} Venues)
                {queryResult.params.targetRegion && ` in ${queryResult.params.targetRegion}`}
                {queryResult.params.targetArea && ` in ${queryResult.params.targetArea}`}
              </div>
              <span style={{ fontSize: 11, fontWeight: 700, background: 'var(--navy-50)', color: 'var(--navy)', padding: '2px 8px', borderRadius: 10 }}>
                Found {queryResult.totalCount} matches
              </span>
            </div>

            <div style={{ overflowX: 'auto' }}>
              <table className="seg-chart-table" style={{ fontSize: 12 }}>
                <thead>
                  <tr>
                    <th 
                      style={{ width: '80px', cursor: 'pointer', userSelect: 'none' }}
                      onClick={() => { setSortKey(''); setSortDir('desc'); }}
                    >
                      Rank {!sortKey ? '▼' : <span style={{ color: 'var(--ink-4)', fontSize: 9 }}> ⇅</span>}
                    </th>
                    <th>Venue Name</th>
                    <th>Subdivision</th>
                    {queryResult.params.clauses.map((clause, cIdx) => {
                      const isSorted = sortKey === clause.metricKey;
                      return (
                        <th 
                          key={cIdx} 
                          style={{ textAlign: 'right', cursor: 'pointer', userSelect: 'none' }}
                          onClick={() => {
                            if (sortKey === clause.metricKey) {
                              setSortDir(sortDir === 'desc' ? 'asc' : 'desc');
                            } else {
                              setSortKey(clause.metricKey);
                              setSortDir('desc');
                            }
                          }}
                        >
                          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
                            {clause.metricLabel}
                            {isSorted ? (sortDir === 'desc' ? ' ▼' : ' ▲') : <span style={{ color: 'var(--ink-4)', fontSize: 9 }}> ⇅</span>}
                          </span>
                        </th>
                      );
                    })}
                  </tr>
                </thead>
                <tbody>
                  {queryResult.list.map((v, idx) => {
                    return (
                      <tr key={v.id} onClick={() => onSelectVenue(v.id)} style={{ cursor: 'pointer' }}>
                        <td style={{ fontWeight: 700, color: 'var(--ink-3)' }}>#{idx + 1}</td>
                        <td>
                          <div style={{ fontWeight: 600, color: 'var(--navy)' }}>{v.name}</div>
                          <div style={{ fontSize: 10.5, color: 'var(--ink-4)' }}>ID: {v.id}</div>
                        </td>
                        <td>
                          <div style={{ fontWeight: 500, color: 'var(--ink-2)' }}>{v.region}</div>
                          <div style={{ fontSize: 10.5, color: 'var(--ink-4)' }}>{v.area}</div>
                        </td>
                        {queryResult.params.clauses.map((clause, cIdx) => {
                          const item = v.clauseValues.find(cv => cv.key === clause.metricKey);
                          const val = item ? item.val : 0;
                          
                          const fmtr = queryResult.formatters[clause.metricKey];
                          const formattedVal = fmtr ? fmtr(val) : (
                            clause.metricFormat === 'idr' ? fmt.idr(val) : (
                              clause.metricFormat === 'pct' ? fmt.pct(val, 1) : fmt.num(val)
                            )
                          );

                          // Style the values cleanly: red for bottom metrics if they're negative/underperforming, green for positive.
                          const isNegativePerformance = clause.isBottom ? (val > 0) : (val < 0);
                          const color = isNegativePerformance ? 'var(--red)' : '#059669';

                          return (
                            <td key={cIdx} className="num" style={{ fontWeight: 700, color }}>
                              {formattedVal}
                            </td>
                          );
                        })}
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </div>

      {/* Group Benchmark Summary Card */}
      <div className="card" style={{ marginBottom: 8, padding: '20px 24px' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: '20px' }}>
          <div>
            <div style={{ font: "700 15px 'Space Grotesk', sans-serif", color: 'var(--navy)' }}>Active Group Benchmark</div>
            <div style={{ font: "500 12px 'Space Grotesk', sans-serif", color: 'var(--ink-3)', marginTop: 4 }}>
              The combined average share across all {allowedVenueIds.filter(id => id !== 'ALL').length} allowed venues.
            </div>
          </div>
          <div style={{ display: 'flex', gap: '24px' }}>
            <div style={{ padding: '4px 16px', background: '#ecfdf5', border: '1px solid #a7f3d0', borderRadius: '8px', minWidth: '160px' }}>
              <div style={{ font: "600 11px 'Space Grotesk', sans-serif", color: '#065f46', textTransform: 'uppercase', letterSpacing: '0.04em' }}>Green Benchmark</div>
              <div style={{ font: "700 24px 'Space Grotesk', sans-serif", color: '#047857', marginTop: 4 }}>{(benchmarkGreenShare * 100).toFixed(1)}%</div>
            </div>
            <div style={{ padding: '4px 16px', background: '#fef2f2', border: '1px solid #fca5a5', borderRadius: '8px', minWidth: '160px' }}>
              <div style={{ font: "600 11px 'Space Grotesk', sans-serif", color: '#991b1b', textTransform: 'uppercase', letterSpacing: '0.04em' }}>Yellow & Red Benchmark</div>
              <div style={{ font: "700 24px 'Space Grotesk', sans-serif", color: '#ef4444', marginTop: 4 }}>{(benchmarkRedShare * 100).toFixed(1)}%</div>
            </div>
          </div>
        </div>
      </div>

      {/* Two Column Grid */}
      <div className="grid grid-2" style={{ gap: '20px' }}>
        
        {/* Left Column: Greens */}
        <div className="card seg-col-card" style={{ padding: '0 0 20px 0' }}>
          <div className="card-head" style={{ borderBottom: '1px solid var(--line)', paddingBottom: 16, marginBottom: 0 }}>
            <div>
              <div className="card-title" style={{ color: '#065f46', display: 'flex', alignItems: 'center', gap: '8px' }}>
                <span style={{ width: 8, height: 16, background: '#10b981', borderRadius: '2px' }} />
                Greens: High-Value Venue Leaders
              </div>
              <div className="card-sub" style={{ marginTop: 4 }}>
                Venues with a **higher combined share** of high-value segments (DS1, DS2, Power, Social, Holiday) than the benchmark.
              </div>
            </div>
          </div>
          <div style={{ padding: '0 20px' }}>
            <table className="seg-chart-table" style={{ whiteSpace: 'nowrap' }}>
              <thead>
                <tr>
                  <th>Venue Name</th>
                  <th style={{ textAlign: 'right', width: '22%' }}>Combined %</th>
                  <th style={{ textAlign: 'right', width: '22%' }}>vs Benchmark</th>
                </tr>
              </thead>
              <tbody>
                {visibleGreens.map(v => (
                  <tr key={v.id} onClick={() => onSelectVenue(v.id)} style={{ cursor: 'pointer' }}>
                    <td style={{ maxWidth: '280px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      <div style={{ fontWeight: 600, color: 'var(--navy)' }}>{v.name}</div>
                      <div style={{ fontSize: '10.5px', color: 'var(--ink-3)', fontFamily: 'JetBrains Mono', marginTop: 2 }}>ID: {v.id}</div>
                    </td>
                    <td className="num" style={{ fontWeight: 600, color: '#047857' }}>
                      {(v.greenShare * 100).toFixed(1)}%
                    </td>
                    <td className="num">
                      <span style={{ color: '#059669', fontWeight: 700, background: '#ecfdf5', padding: '2px 8px', borderRadius: '4px', fontSize: '11.5px' }}>
                        ▲ +{(v.greenDiff * 100).toFixed(1)}pp
                      </span>
                    </td>
                  </tr>
                ))}
                {venueDiagnostics.greens.length === 0 && (
                  <tr>
                    <td colSpan="3" style={{ textAlign: 'center', padding: '30px 0', color: 'var(--ink-4)', fontStyle: 'italic' }}>
                      No venues are over-indexing on Green segments.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>

            {/* Show More Button */}
            {venueDiagnostics.greens.length > 10 && (
              <div style={{ display: 'flex', justifyContent: 'center', marginTop: 16 }}>
                <button 
                  className="logout-btn" 
                  style={{ background: 'var(--navy-50)', color: 'var(--navy)', border: '1px solid var(--line)', padding: '6px 16px', fontWeight: 600 }}
                  onClick={() => setShowMoreGreens(!showMoreGreens)}
                >
                  {showMoreGreens ? 'Show Less' : `Show More (+${venueDiagnostics.greens.length - 10} venues)`}
                </button>
              </div>
            )}
          </div>
        </div>

        {/* Right Column: Yellows & Reds */}
        <div className="card seg-col-card" style={{ padding: '0 0 20px 0' }}>
          <div className="card-head" style={{ borderBottom: '1px solid var(--line)', paddingBottom: 16, marginBottom: 0 }}>
            <div>
              <div className="card-title" style={{ color: '#991b1b', display: 'flex', alignItems: 'center', gap: '8px' }}>
                <span style={{ width: 8, height: 16, background: '#ef4444', borderRadius: '2px' }} />
                Yellows & Reds: Casual & High-Cost Over-indexes
              </div>
              <div className="card-sub" style={{ marginTop: 4 }}>
                Venues with a **higher combined share** of casual/high-cost segments (Casual, Drifters, Dormant, Budget, Heavy Hitters, Prize Chasers) than the benchmark.
              </div>
            </div>
          </div>
          <div style={{ padding: '0 20px' }}>
            <table className="seg-chart-table" style={{ whiteSpace: 'nowrap' }}>
              <thead>
                <tr>
                  <th>Venue Name</th>
                  <th style={{ textAlign: 'right', width: '22%' }}>Combined %</th>
                  <th style={{ textAlign: 'right', width: '22%' }}>vs Benchmark</th>
                </tr>
              </thead>
              <tbody>
                {visibleReds.map(v => (
                  <tr key={v.id} onClick={() => onSelectVenue(v.id)} style={{ cursor: 'pointer' }}>
                    <td style={{ maxWidth: '280px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      <div style={{ fontWeight: 600, color: 'var(--navy)' }}>{v.name}</div>
                      <div style={{ fontSize: '10.5px', color: 'var(--ink-3)', fontFamily: 'JetBrains Mono', marginTop: 2 }}>ID: {v.id}</div>
                    </td>
                    <td className="num" style={{ fontWeight: 600, color: '#ef4444' }}>
                      {(v.redShare * 100).toFixed(1)}%
                    </td>
                    <td className="num">
                      <span style={{ color: '#dc2626', fontWeight: 700, background: '#fef2f2', padding: '2px 8px', borderRadius: '4px', fontSize: '11.5px' }}>
                        ▲ +{(v.redDiff * 100).toFixed(1)}pp
                      </span>
                    </td>
                  </tr>
                ))}
                {venueDiagnostics.reds.length === 0 && (
                  <tr>
                    <td colSpan="3" style={{ textAlign: 'center', padding: '30px 0', color: 'var(--ink-4)', fontStyle: 'italic' }}>
                      No venues are over-indexing on Yellow & Red segments.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>

            {/* Show More Button */}
            {venueDiagnostics.reds.length > 10 && (
              <div style={{ display: 'flex', justifyContent: 'center', marginTop: 16 }}>
                <button 
                  className="logout-btn" 
                  style={{ background: 'var(--navy-50)', color: 'var(--navy)', border: '1px solid var(--line)', padding: '6px 16px', fontWeight: 600 }}
                  onClick={() => setShowMoreReds(!showMoreReds)}
                >
                  {showMoreReds ? 'Show Less' : `Show More (+${venueDiagnostics.reds.length - 10} venues)`}
                </button>
              </div>
            )}
          </div>
        </div>

      </div>
    </div>
  );
}

window.VenuesView = VenuesView;
