/* eslint-disable */
// Dealer panel — portraits, expression-driven, speech bubble — with Baccarat dialogue. The components are
// Three Card Poker's (tcp-dealer.jsx); the portraits are the shared casino dealers.

const BAC_DEALER_VOICES = {
  Melissa: {
    greet: [
      "Welcome to the baccarat table, {p}. Player, Banker, or a little Tie for luck?",
      "{p}! The shoe is fresh and the cards are behaving.",
      "Baccarat, {p}. No decisions after the deal, just nerves.",
      "Pull up a chair, {p}. Pick a side and we'll see who the cards like."
    ],
    idle: [
      "Bets on Player, Banker or Tie, {p}.",
      "Choose a chip, then tap where it goes.",
      "Banker or Player? The shoe is waiting.",
      "Side bets are open too, if you're feeling brave."
    ],
    idle_long: [
      "Whenever you're ready, {p}.",
      "Reading the roads? They don't predict a thing, but they're pretty.",
      "Take your time. The shoe's not going anywhere."
    ],
    bet_low: ["Easing in. Smart.", "A gentle start, {p}.", "Small and steady."],
    bet_high: ["Now we're playing.", "Ooh, real chips.", "{p}, you're making my night interesting."],
    bet_huge: ["Whew. High roller energy.", "The pit boss just looked over.", "That's a serious bet, {p}."],
    bet_tie: ["Tie pays eight to one. Long odds, big smile.", "A little Tie for luck? I love it.", "Tie bet down. Fingers crossed."],
    bet_side: ["Side bet placed. Feeling lucky?", "Ooh, a side bet. Spicy.", "Long shot on the side. Brave."],
    deal: ["Two for Player, two for Banker.", "Cards out. Here we go.", "Hold your breath, {p}.", "Dealing. No take-backs. ✨"],
    natural_player: ["A natural for Player! Nobody draws.", "Player turns over a natural.", "Natural on the Player side."],
    natural_banker: ["Banker shows a natural. That's the hand.", "Natural for Banker!", "Banker opens with a natural."],
    player_draws: ["Player draws a third card.", "Player takes one more.", "Third card for Player."],
    banker_draws: ["Banker draws.", "Banker takes a card.", "One more for Banker."],
    win_player: ["Player wins, and so do you, {p}!", "You backed Player. Smart.", "Player side pays. Nicely done."],
    win_banker: ["Banker wins, and you were on it, {p}!", "Banker pays even money. No commission here.", "Backing Banker pays off."],
    win_tie: ["A TIE! Eight to one, {p}!", "Tie! I told you it was lucky.", "Tie hits. That's the big one."],
    push_tie: ["A tie. Player and Banker bets come back.", "Tie hand. Nobody loses the main bets.", "Standoff. Your bets stay put."],
    lose: ["Not this time, {p}. Go again?", "The other side takes it.", "Tough one. The shoe turns, though.", "Mine this round. We'll get you next hand."],
    dragon_push: ["Banker wins on a three-card 7. That pushes your Banker bet.", "Three-card 7! Banker bets push.", "The Dragon showed up, so Banker pushes."],
    dragon_win: ["DRAGON 7! Forty to one, {p}!", "The Dragon! {p}, that's a big one!", "Forty to one. Tip your dealer. ✨"],
    pair_win: ["A pair! Eleven to one on your side bet.", "Pair hits. Eleven to one!", "Look at that pair, {p}."],
    new_shoe: ["Fresh shoe, {p}. Eight decks, freshly shuffled.", "New shoe. Roads start clean.", "Shuffling up a new shoe."],
    rebet: ["Same as last? Got it.", "The usual, {p}? Coming up.", "Repeat bet. Locked."],
    bankrupt: ["Out of chips, {p}. Reload?", "Empty rack, {p}."]
  },
  Marcus: {
    greet: ["{p}. Sit. Baccarat.", "Evening. Marcus dealing.", "Player, Banker, Tie. Pick one, {p}.", "Fresh shoe. Bet when ready."],
    idle: ["Bet up.", "Chips when ready.", "Your move, {p}.", "Player or Banker."],
    idle_long: ["Take your time.", "Roads don't predict anything. Just so you know.", "I'll be here."],
    bet_low: ["Modest.", "Fine.", "Low bet noted."],
    bet_high: ["Real bet.", "All right then.", "Now I'm awake."],
    bet_huge: ["Big swing.", "Statement bet.", "Pit's looking."],
    bet_tie: ["Tie. Eight to one. Fourteen percent edge.", "Tie bet. Bold.", "Long shot."],
    bet_side: ["Side bet. Noted.", "Long odds.", "Optional but expensive."],
    deal: ["Cards.", "Two each.", "Here they come."],
    natural_player: ["Player natural.", "Natural. Player.", "Player shows a natural."],
    natural_banker: ["Banker natural.", "Natural. Banker.", "Banker shows a natural."],
    player_draws: ["Player draws.", "Card for Player."],
    banker_draws: ["Banker draws.", "Card for Banker."],
    win_player: ["Player. You win.", "Yours.", "Player pays."],
    win_banker: ["Banker. You win.", "Banker pays.", "Yours."],
    win_tie: ["Tie. Eight to one.", "Tie hits. Pays eight.", "Tie. Well called."],
    push_tie: ["Tie. Bets stay.", "Push on the sides.", "Nobody wins."],
    lose: ["House.", "Other side.", "Not this time."],
    dragon_push: ["Three-card 7. Banker pushes.", "Dragon. Banker bets push.", "Banker seven, three cards. Push."],
    dragon_win: ["Dragon 7. Forty to one.", "Dragon pays forty.", "Dragon. Don't see that often."],
    pair_win: ["Pair. Eleven to one.", "Pair pays.", "Side bet hits."],
    new_shoe: ["New shoe.", "Fresh eight decks.", "Shuffle. Roads reset."],
    rebet: ["Same again.", "Repeat bet."],
    bankrupt: ["Out of chips. Reload?", "Rack's empty."]
  }
};

addScarlettVoice(BAC_DEALER_VOICES);
Object.assign(BAC_DEALER_VOICES.Scarlett, {
  greet: ["Welcome to baccarat, {p}. The shoe is ready when you are.", "Good evening, {p}. Player, Banker or Tie, the choice is yours."],
  idle: ["Choose a chip, then a spot, {p}."],
  bet_tie: ["Tie pays eight to one. A long shot, beautifully placed."],
  bet_side: ["Side bet placed."],
  deal: ["Two cards each. Let's see them."],
  natural_player: ["A natural for Player."], natural_banker: ["A natural for Banker."],
  player_draws: ["Player draws a third card."], banker_draws: ["Banker draws."],
  win_player: ["Player wins. Well chosen, {p}."], win_banker: ["Banker wins. Well chosen, {p}."],
  win_tie: ["A tie, at eight to one. Lovely, {p}."], push_tie: ["A tie. Your Player and Banker bets return."],
  lose: ["Not this hand, {p}."],
  dragon_push: ["A three-card 7 for Banker. The Banker bet pushes."], dragon_win: ["Dragon 7. Forty to one, {p}."],
  pair_win: ["Your pair pays eleven to one."], new_shoe: ["A fresh shoe, {p}. The roads begin again."]
});

function bacPickLine(key, ctx = {}) {
  const dealer = ctx.dealer || 'Melissa';
  const voice = BAC_DEALER_VOICES[dealer] || BAC_DEALER_VOICES.Melissa;
  const lines = voice[key] || voice.idle;
  const line = lines[Math.floor(Math.random() * lines.length)];
  // An unnamed player is "friend", capitalised when it opens a sentence.
  const p = ctx.player || '';
  return line
    .replace(/([.!?]\s+)?\{p\}/g, (m, stop, at) => (stop || '') + (p || (stop || at === 0 ? 'Friend' : 'friend')))
    .replace(/\{d\}/g, dealer);
}

function BacDealerPortrait({ expression = 'idle', shift = 0, gender = 'female', idle = false, mood = 0 }) {
  const file = expression;
  const src = `../assets/casino/dealers/${gender}/${file}.webp`;
  const [layers, setLayers] = React.useState(() => [{ key: 0, src, opacity: 1, blur: 0 }]);
  const counter = React.useRef(0);
  const lastSrc = React.useRef(src);

  React.useEffect(() => {
    if (lastSrc.current === src) return;
    lastSrc.current = src;
    counter.current += 1;
    const newKey = counter.current;
    setLayers(prev => [
      ...prev.map(l => ({ ...l, opacity: 0, blur: 6 })),
      { key: newKey, src, opacity: 0, blur: 6 }
    ]);
    const raf = requestAnimationFrame(() => {
      setLayers(prev => prev.map(l => l.key === newKey ? { ...l, opacity: 1, blur: 0 } : l));
    });
    const t = setTimeout(() => {
      setLayers(prev => prev.filter(l => l.key === newKey));
    }, 520);
    return () => { cancelAnimationFrame(raf); clearTimeout(t); };
  }, [src]);

  const m = Math.max(-1, Math.min(1, mood));
  const sat = (1.05 + m * 0.25).toFixed(3);
  const bright = (1 + m * 0.06).toFixed(3);

  return (
    <div style={{
      position: 'absolute', inset: 0,
      overflow: 'hidden',
      borderRadius: 'inherit'
    }}>
      {layers.map(layer => (
        <img
          key={layer.key}
          src={layer.src}
          alt="dealer"
          onError={(e) => { e.currentTarget.src = `../assets/casino/dealers/female/${file}.webp`; }}
          style={{
            position: 'absolute',
            left: '50%',
            top: `${shift}px`,
            transform: 'translateX(-50%)',
            height: `${120 * CASINO_DEALERS.portraitScale(layer.src)}%`,
            objectFit: 'cover',
            objectPosition: 'center top',
            opacity: layer.opacity,
            transition: 'opacity .45s ease, filter .45s ease',
            filter: `blur(${layer.blur}px) saturate(${sat}) contrast(1.02) brightness(${bright})`
          }}
        />
      ))}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'radial-gradient(ellipse at 50% 35%, transparent 50%, rgba(0,0,0,.55) 100%)',
        pointerEvents: 'none'
      }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, top: 0, height: 90,
        background: 'linear-gradient(180deg, rgba(0,0,0,.55), transparent)',
        pointerEvents: 'none'
      }} />
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, height: 220,
        background: 'linear-gradient(0deg, var(--ink-2) 8%, rgba(15,12,8,.85) 35%, transparent 100%)',
        pointerEvents: 'none'
      }} />
    </div>
  );
}

function BacSpeechBubble({ text, dealerName = 'Melissa' }) {
  const [shown, setShown] = React.useState('');
  const [done, setDone] = React.useState(false);
  React.useEffect(() => {
    setShown(''); setDone(false);
    let i = 0;
    const id = setInterval(() => {
      i++;
      setShown(text.slice(0, i));
      if (i >= text.length) { clearInterval(id); setDone(true); }
    }, 18);
    return () => clearInterval(id);
  }, [text]);

  return (
    <div className="chat-pop" key={text} style={{
      position: 'relative',
      opacity: 1,
      background: 'linear-gradient(180deg, rgba(255,253,246,.97), rgba(244,236,216,.97))',
      color: '#1a1410',
      padding: '14px 18px 16px',
      borderRadius: 14,
      boxShadow: '0 14px 30px rgba(0,0,0,.45), 0 2px 0 rgba(255,255,255,.5) inset, 0 0 0 1px rgba(201,162,106,.5)',
      maxWidth: 320,
      minHeight: 70
    }}>
      <div style={{
        fontSize: 11, fontWeight: 600, letterSpacing: '.16em',
        color: 'var(--brass-deep)', textTransform: 'uppercase', marginBottom: 4
      }}>{dealerName}</div>
      <div style={{
        fontFamily: "'Playfair Display', serif",
        fontSize: 17, lineHeight: 1.35,
        fontStyle: 'italic',
        color: '#1a1410'
      }} className={done ? '' : 'blink-cursor'}>
        {shown || ' '}
      </div>
      <div style={{
        position: 'absolute',
        top: -10, left: 36,
        width: 0, height: 0,
        borderLeft: '10px solid transparent',
        borderRight: '10px solid transparent',
        borderBottom: '12px solid rgba(255,253,246,.97)',
        filter: 'drop-shadow(0 -1px 1px rgba(0,0,0,.15))'
      }} />
    </div>
  );
}

function BacDealerNameplate({ name, gender = 'female' }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 10,
      padding: '6px 14px 6px 6px',
      background: 'linear-gradient(180deg, rgba(20,12,6,.85), rgba(10,6,3,.85))',
      border: '1px solid rgba(201,162,106,.45)',
      borderRadius: 999,
      backdropFilter: 'blur(6px)',
      boxShadow: '0 8px 18px rgba(0,0,0,.45)'
    }}>
      <img
        src={`../assets/casino/dealers/${gender}/avatar.webp`}
        alt=""
        style={{
          width: 30, height: 30, borderRadius: '50%',
          objectFit: 'cover', objectPosition: 'center top',
          boxShadow: '0 0 0 1px rgba(201,162,106,.55), 0 0 8px rgba(201,162,106,.35)'
        }}
      />
      <span style={{ fontSize: 11, lineHeight: 1, letterSpacing: '.18em', color: 'var(--ivory-dim)', textTransform: 'uppercase' }}>Your dealer</span>
      <span style={{
        fontFamily: "'Playfair Display', serif",
        fontSize: 19, lineHeight: 1, color: 'var(--brass-2)', fontWeight: 600, letterSpacing: '.02em'
      }}><DealerSelect name={name} /></span>
    </div>
  );
}

function DealerPanel({ name, expression, message, gender = 'female', isIdle = false, mood = 0, tight = false }) {
  return (
    <div style={{
      position: 'relative',
      width: 380,
      height: '100%',
      borderRadius: 18,
      overflow: 'hidden',
      background: '#1a1208',
      boxShadow: 'var(--shadow-deep), inset 0 0 0 1px rgba(201,162,106,.18)'
    }}>
      <BacDealerPortrait expression={expression} gender={gender} idle={isIdle} mood={mood} />

      <div style={{ position: 'absolute', top: 18, left: 18, right: 18, zIndex: 3 }}>
        <BacDealerNameplate name={name} gender={gender} />
      </div>

      <div style={{
        position: 'absolute', left: 22, right: 22, bottom: tight ? 100 : 70, zIndex: 4
      }}>
        {message && <BacSpeechBubble text={message} dealerName={name} />}
      </div>
    </div>
  );
}

// Upright phones: the portrait shrinks to an avatar beside the dealer's line.
// The player's name lives on the rail's profile pill, not here.
function DealerStrip({ name, message, gender = 'female' }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      padding: '6px 6px 6px 8px',
      borderRadius: 14,
      background: 'linear-gradient(180deg, rgba(26,16,8,.92), rgba(14,8,4,.92))',
      border: '1px solid rgba(201,162,106,.3)',
      boxShadow: '0 10px 24px rgba(0,0,0,.45), inset 0 1px 0 rgba(230,197,144,.12)',
      height: 70, flexShrink: 0 // fixed: a two-line remark must not shift the table below
    }}>
      <img
        src={CASINO_DEALERS.art(name, 'avatar')}
        alt=""
        style={{
          width: 46, height: 46, borderRadius: '50%', flexShrink: 0,
          objectFit: 'cover', objectPosition: 'center top',
          boxShadow: '0 0 0 1.5px rgba(201,162,106,.55), 0 0 10px rgba(201,162,106,.3)'
        }}
      />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 12, letterSpacing: '.14em', color: 'var(--brass)', textTransform: 'uppercase', fontWeight: 700 }}><DealerSelect name={name} /></div>
        <div style={{
          fontFamily: "'Playfair Display', serif", fontStyle: 'italic',
          fontSize: 15, lineHeight: 1.3, color: 'var(--ivory)',
          marginTop: 2,
          display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden'
        }}>{message || ' '}</div>
      </div>
    </div>
  );
}

Object.assign(window, { DealerPanel, DealerStrip, bacPickLine, BAC_DEALER_VOICES });
