import { useMemo } from 'react'
import './BudgetTab.css'

// ─── Price parsers ────────────────────────────────────────────────────────────

function extractPrices(details) {
  if (!details || !details.length) return {}
  const text = details.join(' ')
  const prices = {}

  // Per-person package: "Apple exact-date quote: $2,016 pp" / "Costco package: $1,678.99 pp"
  const ppMatch = text.match(/\$([\d,]+(?:\.\d{2})?)\s*(?:pp|per person|per-person)/i)
  if (ppMatch) prices.perPerson = parseFloat(ppMatch[1].replace(/,/g, ''))

  // Per-night: "KAYAK from $212/night" / "KAYAK exact-date room rate: $335/night"
  const pnMatch = text.match(/\$([\d,]+(?:\.\d{2})?)\s*(?:\/night|per night|per-night)/i)
  if (pnMatch) prices.perNight = parseFloat(pnMatch[1].replace(/,/g, ''))

  // Group-total with size: "Pool island for 4: $884" / "Gold package for 16 guests: $1,700"
  // Group-total with size: "Pool island for 4: $884" / "Gold package for 16 guests: $1,700"
  const groupMatch = text.match(/(?:for|at)\s+(\d+)[^\d$]*\$([\d,]+(?:\.\d{2})?)/i)
    || text.match(/\$([\d,]+(?:\.\d{2})?)\s+(?:total|for\s+\d+)/i)
  if (groupMatch) {
    prices.groupTotal = parseFloat((groupMatch[2] || groupMatch[1]).replace(/,/g, ''))
    const sizeMatch = text.match(/for\s+(\d+)\s*[^\d$]*/i)
    if (sizeMatch) prices.groupSize = parseInt(sizeMatch[1])
  }

  // Simple "From $1,504 total"
  if (!prices.groupTotal) {
    const totalMatch = text.match(/(?:from\s+)?\$([\d,]+(?:\.\d{2})?)\s+total/i)
    if (totalMatch) prices.groupTotal = parseFloat(totalMatch[1].replace(/,/g, ''))
  }

  // Per-person from group total: "About $188 pp at 8"
  const ppAtMatch = text.match(/\$\d+[\d,.]*\s*(?:pp|per person).*?at\s+(\d+)/i)
    || text.match(/about?\$([\d,]+(?:\.\d{2})?)\s*(?:pp|per person).*?at\s+(\d+)/i)
  if (ppAtMatch) {
    prices.perPerson = parseFloat(ppAtMatch[1].replace(/,/g, ''))
    prices.atGroupSize = parseInt(ppAtMatch[2])
  }

  // Planning number: "Use about $180 as current planning number"
  const planMatch = text.match(/use\s+(?:about\s+)?\$([\d,]+(?:\.\d{2})?)\s+(?:as\s+)?(?:the\s+)?(?:current\s+)?planning/i)
  if (planMatch && !prices.perPerson) prices.planningRate = parseFloat(planMatch[1].replace(/,/g, ''))

  // Flat per-person: "From $76" — only if no other signals
  if (!prices.perPerson && !prices.perNight && !prices.groupTotal && !prices.planningRate) {
    const flatMatch = text.match(/(?:from\s+)?\$([\d,]+(?:\.\d{2})?)\b(?!.*\b(?:pp|per|total|for\b)/i)
    if (flatMatch) {
      const val = parseFloat(flatMatch[1].replace(/,/g, ''))
      if (val > 20) prices.perPerson = val
    }
  }

  return prices
}

// ─── Check whether an option has real scraped pricing ─────────────────────────

function hasRealPricing(option) {
  const p = extractPrices(option.details || [])
  // Has at least one real price signal (not just a planning estimate or generic text)
  return !!(p.perPerson || p.perNight || p.groupTotal || p.planningRate)
}

// ─── Resolve per-person cost for an option ───────────────────────────────────

function resolvePerPerson(option, fallback) {
  const p = extractPrices(option.details || [])
  if (p.perPerson) return p.perPerson
  if (p.perNight) return p.perNight * 3  // assume 3-night stay
  if (p.groupTotal && p.groupSize) return Math.round(p.groupTotal / p.groupSize)
  if (p.groupTotal && p.atGroupSize) {
    // scale to 8-person group as baseline
    return Math.round(p.groupTotal / p.atGroupSize)
  }
  if (p.groupTotal) return Math.round(p.groupTotal / 8)
  if (p.planningRate) return p.planningRate
  return fallback
}

// ─── Fixed costs ─────────────────────────────────────────────────────────────

const FLIGHT_PP = 350
const FOOD_BUFFER = 275

// ─── Per-person costs from real scraped data (used when details are empty) ──

const FALLBACK_HOTEL = { budget: 450, balanced: 850, splurge: 1250 }
const FALLBACK_GOLF = { budget: 130, balanced: 180, splurge: 250 }
const FALLBACK_NIGHTLIFE = { budget: 40, balanced: 100, splurge: 200 }
const FALLBACK_EXCURSION = { budget: 76, balanced: 110, splurge: 188 }
const FALLBACK_TRANSFER = { budget: 33, balanced: 83, splurge: 183 }

// ─── Tier classification by hotel price signal ──────────────────────────────

function classifyTier(optionId, perPerson) {
  // Use the actual scraped per-person package prices as ground truth
  const KNOWN_PP = {
    // Hotels — package prices
    'hotel-corazon': null,           // no live rate
    'hotel-breathless': 1678.99,    // Costco package
    'hotel-grand-fiesta': null,      // no Costco live, Apple $2,111
    'hotel-secrets': 2005.80,        // Costco package
    'hotel-pacifica': null,          // no live rate
    'hotel-dreams': null,
    // Hotels — nightly rates → scaled to 3-night
    // KAYAK per-night rates × 3 nights
  }
  if (KNOWN_PP[optionId] !== undefined && KNOWN_PP[optionId] !== null) {
    const pp = KNOWN_PP[optionId]
    if (pp <= 1000) return 'budget'
    if (pp <= 1900) return 'balanced'
    return 'splurge'
  }
  // Nightly rate proxies (×3 nights)
  if (perPerson <= 300) return 'budget'
  if (perPerson <= 900) return 'balanced'
  return 'splurge'
}

// ─── Category label / emoji ──────────────────────────────────────────────────

const CAT_LABELS = {
  hotel: '🏨 Hotel',
  golf: '⛳ Golf',
  nightlife: '🎧 Nightlife',
  excursion: '🚤 Excursion',
}

const GROUP_SIZES = [8, 10, 12]

// ─── Main component ─────────────────────────────────────────────────────────

function getWinningOption(options, categoryId) {
  const catOpts = options.filter(o => o.categoryId === categoryId && o.approved)
  if (!catOpts.length) return null
  return catOpts.reduce((best, o) =>
    (o.votes?.length || 0) > (best.votes?.length || 0) ? o : best
  , catOpts[0])
}

function dominantTier(tiers) {
  const counts = { budget: 0, balanced: 0, splurge: 0 }
  Object.values(tiers).forEach(t => { if (t) counts[t] = (counts[t] || 0) + 1 })
  if (counts.splurge >= 2) return 'splurge'
  if (counts.budget >= 2) return 'budget'
  return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] || 'balanced'
}

function formatPrice(v) {
  if (!v) return '—'
  return '$' + v.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 })
}

function getPriceLabel(option) {
  const p = extractPrices(option.details || [])
  const text = (option.details || []).join(' ')

  if (p.perPerson) {
    // Prefer package price label
    const pkgMatch = text.match(/(Costco|Apple).*?\$[\d,]+(?:\.\d{2})?\s*(?:pp|per person)/i)
    if (pkgMatch) {
      const m = text.match(/\$([\d,]+(?:\.\d{2})?)\s*(?:pp|per person)/i)
      if (m) return `pkg ${formatPrice(parseFloat(m[1].replace(/,/g, '')))}/pp`
    }
    return formatPrice(p.perPerson) + '/pp'
  }
  if (p.perNight) {
    const nights = 3
    return formatPrice(p.perNight) + '/night → ' + formatPrice(p.perNight * nights) + ' for 3 nights'
  }
  if (p.groupTotal && p.groupSize) {
    const pp = Math.round(p.groupTotal / p.groupSize)
    return formatPrice(p.groupTotal) + ' total ÷ ' + p.groupSize + ' = ' + formatPrice(pp) + '/pp'
  }
  if (p.groupTotal) {
    const pp = Math.round(p.groupTotal / 8)
    return formatPrice(p.groupTotal) + ' group total (~' + formatPrice(pp) + '/pp)'
  }
  if (p.planningRate) return '~$' + Math.round(p.planningRate) + '/pp planning'
  return null
}

export default function BudgetTab({ options, categories }) {
  const votingCategories = ['hotel', 'golf', 'nightlife', 'excursion']

  const leaders = useMemo(() => {
    const result = {}
    votingCategories.forEach(cat => {
      result[cat] = getWinningOption(options, cat)
    })
    return result
  }, [options])

  // Only include leaders that have actual scraped pricing
  const pricedLeaders = useMemo(() => {
    const result = {}
    votingCategories.forEach(cat => {
      const leader = leaders[cat]
      if (leader && hasRealPricing(leader)) result[cat] = leader
    })
    return result
  }, [leaders])

  // Determine tier per category based on actual prices
  const tiers = useMemo(() => {
    const t = {}
    votingCategories.forEach(cat => {
      const leader = pricedLeaders[cat]
      if (!leader) { t[cat] = 'balanced'; return }
      const pp = resolvePerPerson(leader, null)
      t[cat] = classifyTier(leader.id, pp)
    })
    return t
  }, [pricedLeaders])

  const overallTier = useMemo(() => dominantTier(tiers), [tiers])

  // Build the cost breakdown from real prices only
  const costRows = useMemo(() => {
    const rows = {}

    votingCategories.forEach(cat => {
      const leader = pricedLeaders[cat]
      if (!leader) return  // skip categories without priced leaders
      const pp = resolvePerPerson(leader, null)
      rows[cat] = { label: CAT_LABELS[cat], pp, source: leader.name }
    })

    // Transfer depends on tier (only show if we have at least a hotel)
    if (Object.keys(pricedLeaders).length > 0) {
      rows.transfer = { label: '🚗 Transfers', pp: FALLBACK_TRANSFER[overallTier], source: 'shared shuttle estimate' }
    }
    rows.flight = { label: '✈️ Flights', pp: FLIGHT_PP, source: 'group average estimate' }
    rows.food = { label: '🍽️ Food + drinks', pp: FOOD_BUFFER, source: 'buffer for 3 days' }

    return rows
  }, [pricedLeaders, overallTier])

  const totals = useMemo(() => {
    return GROUP_SIZES.map(size => {
      const sum = Object.values(costRows).reduce((acc, row) => acc + (row.pp || 0), 0)
      return { size, perPerson: Math.round(sum), total: Math.round(sum * size) }
    })
  }, [costRows])

  const hasPricedLeaders = Object.keys(pricedLeaders).length > 0

  const tierColor = { budget: '#22c55e', balanced: '#3b82f6', splurge: '#f97316' }
  const tierLabel = { budget: '💰 Budget', balanced: '⚖️ Balanced', splurge: '💎 Splurge' }

  return (
    <div className="budget-tab">
      <div className="budget-header">
        <h2>Trip Budget Calculator</h2>
        <p>Prices sourced from live travel data — updates as votes come in</p>
      </div>

      {/* Category leaders with real prices */}
      <div className="budget-leaders">
        <h3>Current Leaders — Live Prices</h3>
        {Object.keys(pricedLeaders).length > 0 ? (
          <div className="leaders-grid">
            {votingCategories.map(cat => {
              const leader = pricedLeaders[cat]
              if (!leader) return null
              const catTier = tiers[cat]
              const priceLabel = getPriceLabel(leader)
              return (
                <div key={cat} className="leader-card" style={{ '--cat-color': tierColor[catTier] }}>
                  <div className="leader-cat">{CAT_LABELS[cat]}</div>
                  <div className="leader-name">{leader.name}</div>
                  {priceLabel && <div className="leader-price">{priceLabel}</div>}
                  <div className="leader-tier" style={{ color: tierColor[catTier] }}>
                    {tierLabel[catTier]}
                  </div>
                  <div className="leader-votes">
                    {leader.votes?.length > 0
                      ? `${leader.votes.length} vote${leader.votes.length !== 1 ? 's' : ''}`
                      : 'no votes yet'}
                  </div>
                </div>
              )
            })}
          </div>
        ) : (
          <div className="budget-placeholder">
            <div className="placeholder-icon">⏳</div>
            <p>Waiting for pricing data. Options without live prices from travel sites are hidden until the scraper updates them.</p>
          </div>
        )}
      </div>

      {/* Tier summary pills */}
      <div className="budget-tiers">
        {['budget', 'balanced', 'splurge'].map(tier => (
          <div
            key={tier}
            className={`tier-card ${overallTier === tier ? 'active' : ''}`}
            style={{ '--tier-color': tierColor[tier] }}
          >
            <div className="tier-label">{tierLabel[tier]}</div>
            {overallTier === tier && <div className="tier-badge">Current</div>}
          </div>
        ))}
      </div>

      {/* Dynamic cost breakdown */}
      {hasPricedLeaders ? (
        <div className="budget-breakdown">
          <h3>Estimated Cost — {tierLabel[overallTier]} Tier</h3>
          <div className="breakdown-table">
            <div className="breakdown-row header-row">
              <span>Line Item</span>
              <span>Source</span>
              {GROUP_SIZES.map(s => <span key={s}>{s} guys</span>)}
            </div>

            {[
              costRows.flight,
              costRows.hotel,
              costRows.golf,
              costRows.nightlife,
              costRows.excursion,
              costRows.transfer,
              costRows.food,
            ].map(row => row && (
              <div className="breakdown-row" key={row.label}>
                <span>{row.label}</span>
                <span className="source-cell">{row.source || '—'}</span>
                {GROUP_SIZES.map(s => (
                  <span key={s}>{formatPrice(row.pp)}</span>
                ))}
              </div>
            ))}

            <div className="breakdown-row total-row">
              <span>Est. Per Person</span>
              <span className="source-cell">sum</span>
              {totals.map(t => (
                <span key={t.size} style={{ color: tierColor[overallTier], fontWeight: 700 }}>
                  {formatPrice(t.perPerson)}
                </span>
              ))}
            </div>
            <div className="breakdown-row group-row">
              <span>Est. Group Total</span>
              <span className="source-cell"></span>
              {totals.map(t => (
                <span key={t.size} style={{ color: tierColor[overallTier], fontWeight: 700 }}>
                  {formatPrice(t.total)}
                </span>
              ))}
            </div>
          </div>
          <p className="budget-note">
            * Prices from live scraped data. Hotel rates are package or nightly × 3 nights.
            Per-person costs shown are the same for all group sizes. Add bar tabs and tips separately.
          </p>
        </div>
      ) : (
        <div className="budget-placeholder">
          <div className="placeholder-icon">🗳️</div>
          <p>No votes cast yet. Vote in the Hotel, Golf, Nightlife, and Excursion tabs and the budget will update automatically using real scraped prices.</p>
        </div>
      )}
    </div>
  )
}
