export type BurstMotionStyle =
  | 'explode'
  | 'bounce'
  | 'rise'
  | 'sparkle'
  | 'splash'
  | 'spiral'
  | 'punch'
  | 'scatter'
  | 'shower';

export type EmojiBurstProfile = {
  style: BurstMotionStyle;
  particleCount: number;
  gravity: number;
  drag: number;
  speedMin: number;
  speedMax: number;
  launchUpMin: number;
  launchUpMax: number;
  spinMin: number;
  spinMax: number;
  fontSizeMin: number;
  fontSizeMax: number;
  heroFontSizeMin: number;
  heroFontSizeMax: number;
  companions?: string[];
  companionChance?: number;
  /** Bias burst angle in radians. 0 = right, -π/2 = up. */
  angleBias?: number;
  /** Limit spawn to a cone (radians). Omit for full 360°. */
  angleSpread?: number;
  twinkle?: boolean;
  wobble?: boolean;
};

const DEFAULT_PROFILE: EmojiBurstProfile = {
  style: 'explode',
  particleCount: 36,
  gravity: 400,
  drag: 0.935,
  speedMin: 240,
  speedMax: 560,
  launchUpMin: 40,
  launchUpMax: 130,
  spinMin: -180,
  spinMax: 180,
  fontSizeMin: 14,
  fontSizeMax: 26,
  heroFontSizeMin: 26,
  heroFontSizeMax: 34,
};

const PROFILE_OVERRIDES: Record<string, Partial<EmojiBurstProfile>> = {
  '😆': {
    style: 'bounce',
    particleCount: 28,
    gravity: 520,
    speedMin: 180,
    speedMax: 360,
    launchUpMin: 120,
    launchUpMax: 220,
    spinMin: -240,
    spinMax: 240,
    wobble: true,
  },
  '😂': {
    style: 'bounce',
    particleCount: 30,
    gravity: 500,
    speedMin: 160,
    speedMax: 340,
    launchUpMin: 110,
    launchUpMax: 210,
    spinMin: -220,
    spinMax: 220,
    wobble: true,
  },
  '🤣': {
    style: 'bounce',
    particleCount: 32,
    gravity: 480,
    speedMin: 200,
    speedMax: 380,
    launchUpMin: 130,
    launchUpMax: 240,
    wobble: true,
  },
  '🔥': {
    style: 'rise',
    particleCount: 24,
    gravity: -120,
    drag: 0.96,
    speedMin: 80,
    speedMax: 200,
    launchUpMin: 60,
    launchUpMax: 160,
    spinMin: -90,
    spinMax: 90,
    fontSizeMin: 16,
    fontSizeMax: 28,
    twinkle: true,
    wobble: true,
    companions: ['✨'],
    companionChance: 0.35,
  },
  '❤️': {
    style: 'rise',
    particleCount: 22,
    gravity: -80,
    drag: 0.97,
    speedMin: 60,
    speedMax: 150,
    launchUpMin: 40,
    launchUpMax: 110,
    spinMin: -40,
    spinMax: 40,
    fontSizeMin: 14,
    fontSizeMax: 24,
    companions: ['💕', '💖'],
    companionChance: 0.4,
  },
  '💕': {
    style: 'rise',
    particleCount: 20,
    gravity: -70,
    drag: 0.97,
    speedMin: 50,
    speedMax: 140,
    launchUpMin: 35,
    launchUpMax: 100,
    spinMin: -35,
    spinMax: 35,
  },
  '💖': {
    style: 'rise',
    particleCount: 20,
    gravity: -90,
    drag: 0.968,
    speedMin: 55,
    speedMax: 150,
    launchUpMin: 45,
    launchUpMax: 115,
    twinkle: true,
  },
  '⭐': {
    style: 'sparkle',
    particleCount: 26,
    gravity: 40,
    drag: 0.94,
    speedMin: 100,
    speedMax: 260,
    launchUpMin: 20,
    launchUpMax: 80,
    spinMin: -120,
    spinMax: 120,
    twinkle: true,
    companions: ['✨'],
    companionChance: 0.5,
  },
  '✨': {
    style: 'sparkle',
    particleCount: 30,
    gravity: 30,
    drag: 0.945,
    speedMin: 90,
    speedMax: 240,
    launchUpMin: 15,
    launchUpMax: 70,
    spinMin: -200,
    spinMax: 200,
    twinkle: true,
  },
  '💀': {
    style: 'scatter',
    particleCount: 20,
    gravity: 620,
    drag: 0.92,
    speedMin: 200,
    speedMax: 420,
    launchUpMin: 20,
    launchUpMax: 90,
    spinMin: -360,
    spinMax: 360,
    fontSizeMin: 16,
    fontSizeMax: 28,
  },
  '🎉': {
    style: 'shower',
    particleCount: 40,
    gravity: 280,
    drag: 0.93,
    speedMin: 200,
    speedMax: 480,
    launchUpMin: 80,
    launchUpMax: 200,
    companions: ['🎊', '✨', '🎈'],
    companionChance: 0.45,
  },
  '🎊': {
    style: 'shower',
    particleCount: 38,
    gravity: 260,
    drag: 0.932,
    speedMin: 190,
    speedMax: 460,
    launchUpMin: 70,
    launchUpMax: 190,
    companions: ['🎉', '✨'],
    companionChance: 0.4,
  },
  '👏': {
    style: 'punch',
    particleCount: 18,
    gravity: 320,
    speedMin: 220,
    speedMax: 400,
    launchUpMin: 30,
    launchUpMax: 100,
    angleBias: -Math.PI / 2,
    angleSpread: Math.PI * 0.85,
    spinMin: -100,
    spinMax: 100,
  },
  '👍': {
    style: 'punch',
    particleCount: 14,
    gravity: 380,
    speedMin: 260,
    speedMax: 440,
    launchUpMin: 100,
    launchUpMax: 200,
    angleBias: -Math.PI / 2,
    angleSpread: Math.PI * 0.55,
    spinMin: -60,
    spinMax: 60,
  },
  '💯': {
    style: 'punch',
    particleCount: 16,
    gravity: 300,
    speedMin: 200,
    speedMax: 380,
    launchUpMin: 140,
    launchUpMax: 240,
    angleBias: -Math.PI / 2,
    angleSpread: Math.PI * 0.45,
    fontSizeMin: 16,
    fontSizeMax: 30,
    wobble: true,
  },
  '💦': {
    style: 'splash',
    particleCount: 32,
    gravity: 540,
    drag: 0.925,
    speedMin: 280,
    speedMax: 520,
    launchUpMin: 160,
    launchUpMax: 300,
    spinMin: -140,
    spinMax: 140,
    angleBias: -Math.PI / 2,
    angleSpread: Math.PI * 1.1,
  },
  '🌊': {
    style: 'splash',
    particleCount: 28,
    gravity: 420,
    drag: 0.93,
    speedMin: 220,
    speedMax: 460,
    launchUpMin: 100,
    launchUpMax: 220,
    angleBias: -Math.PI / 2,
    angleSpread: Math.PI,
    companions: ['💧'],
    companionChance: 0.3,
  },
  '⚡': {
    style: 'scatter',
    particleCount: 14,
    gravity: 180,
    drag: 0.88,
    speedMin: 380,
    speedMax: 680,
    launchUpMin: 10,
    launchUpMax: 60,
    spinMin: -30,
    spinMax: 30,
    fontSizeMin: 18,
    fontSizeMax: 32,
    angleSpread: Math.PI * 1.2,
  },
  '🌀': {
    style: 'spiral',
    particleCount: 24,
    gravity: 60,
    drag: 0.96,
    speedMin: 120,
    speedMax: 260,
    launchUpMin: 0,
    launchUpMax: 40,
    spinMin: -420,
    spinMax: 420,
  },
  '🤯': {
    style: 'explode',
    particleCount: 34,
    gravity: 360,
    speedMin: 280,
    speedMax: 580,
    launchUpMin: 60,
    launchUpMax: 160,
    companions: ['💥', '✨', '⭐'],
    companionChance: 0.5,
  },
  '😭': {
    style: 'splash',
    particleCount: 26,
    gravity: 480,
    drag: 0.94,
    speedMin: 140,
    speedMax: 300,
    launchUpMin: 40,
    launchUpMax: 120,
    angleBias: Math.PI / 2,
    angleSpread: Math.PI * 0.7,
    companions: ['💧'],
    companionChance: 0.55,
  },
  '🥳': {
    style: 'shower',
    particleCount: 36,
    gravity: 250,
    speedMin: 180,
    speedMax: 440,
    launchUpMin: 90,
    launchUpMax: 210,
    companions: ['🎉', '🎊', '🎈'],
    companionChance: 0.4,
  },
  '🐱': {
    style: 'bounce',
    particleCount: 20,
    gravity: 440,
    speedMin: 150,
    speedMax: 320,
    launchUpMin: 90,
    launchUpMax: 180,
    spinMin: -160,
    spinMax: 160,
  },
  '🐶': {
    style: 'bounce',
    particleCount: 20,
    gravity: 460,
    speedMin: 160,
    speedMax: 330,
    launchUpMin: 85,
    launchUpMax: 175,
    wobble: true,
  },
};

export function getEmojiBurstProfile(emoji: string): EmojiBurstProfile {
  const override = PROFILE_OVERRIDES[emoji];
  if (!override) return DEFAULT_PROFILE;
  return { ...DEFAULT_PROFILE, ...override };
}

export function pickParticleEmoji(profile: EmojiBurstProfile, primaryEmoji: string): string {
  if (!profile.companions?.length || !profile.companionChance) {
    return primaryEmoji;
  }
  if (Math.random() >= profile.companionChance) {
    return primaryEmoji;
  }
  const companion = profile.companions[Math.floor(Math.random() * profile.companions.length)];
  return companion ?? primaryEmoji;
}

export function sampleBurstAngle(profile: EmojiBurstProfile): number {
  if (profile.angleSpread === undefined) {
    return Math.random() * Math.PI * 2;
  }

  const bias = profile.angleBias ?? -Math.PI / 2;
  const halfSpread = profile.angleSpread / 2;
  return bias + (Math.random() - 0.5) * profile.angleSpread * (0.6 + Math.random() * 0.4);
}
