import type { CSSProperties } from 'react';
import { useMediaQuery } from '../hooks/useMediaQuery';

export interface VibeProfile {
  energy?: number;
  noveltyHunger?: number;
  explorationCoefficient?: number;
  discoveryRadius?: number;
  sessionGoal?: { type?: string; progress?: number; target?: number };
}

const clamp = (value: number | undefined, fallback: number) =>
  Math.min(1, Math.max(0, typeof value === 'number' ? value : fallback));

function describeProfile(energy: number, novelty: number) {
  const energyLabel = energy < 0.36 ? 'settled' : energy > 0.68 ? 'charged' : 'flowing';
  const discoveryLabel = novelty < 0.36 ? 'familiar' : novelty > 0.64 ? 'adventurous' : 'balanced';
  return { energyLabel, discoveryLabel };
}

/** An ambient representation of the live recommendation profile. */
export function VibeAura({ profile, ambient = false }: { profile: VibeProfile; ambient?: boolean }) {
  // The displacement pass is desktop-only; see the comment in the ambient
  // branch below. Same breakpoint the layout already uses for this element.
  const plasma = useMediaQuery('(min-width: 640px)');
  const energy = clamp(profile.energy, 0.5);
  const novelty = clamp(profile.noveltyHunger ?? profile.explorationCoefficient, 0.3);
  const { energyLabel, discoveryLabel } = describeProfile(energy, novelty);
  // Hue is discovery alone: ember red when the Vibe stays familiar, gold when it
  // reaches. Energy is deliberately absent — it already drives four motion
  // channels below, and mixing it in here cancelled half the novelty swing.
  // Warm range only; the old 205 base put a teal-blue glow in a warm brown room.
  const hue = Math.round(15 + novelty * 40);
  const style = {
    '--vibe-hue': String(hue),
    '--vibe-pulse': `${(4.8 - energy * 2.3).toFixed(2)}s`,
    '--vibe-orbit': `${(11 - energy * 4).toFixed(2)}s`,
    '--vibe-scale': String((0.9 + energy * 0.16).toFixed(2)),
    '--vibe-core-opacity': ambient ? '0.38' : '1',
  } as CSSProperties;

  const aura = (
    <div className="grid h-16 w-16 place-items-center rounded-full">
      <div className="vibe-aura-halo" />
      <div className="vibe-aura-orbit vibe-aura-orbit-one" />
      <div className="vibe-aura-orbit vibe-aura-orbit-two" />
      <div className="vibe-aura-core" style={{ opacity: 'var(--vibe-core-opacity, 1)' }}>
        <span className="vibe-aura-spark vibe-aura-spark-one" />
        <span className="vibe-aura-spark vibe-aura-spark-two" />
        <span className="vibe-aura-heart" />
      </div>
      {!ambient && (
        <div className="pointer-events-none absolute right-0 top-[calc(100%+0.4rem)] z-10 w-44 rounded-md border border-border bg-surface1 px-3 py-2 text-xs leading-relaxed text-muted opacity-0 shadow-xl transition-opacity group-hover:opacity-100 group-focus:opacity-100">
          <span className="block font-medium text-text">Your Vibe is {energyLabel}</span>
          <span>Leaning {discoveryLabel}; it shifts as you listen.</span>
        </div>
      )}
    </div>
  );

  if (ambient) {
    // Displacing clean gradients by animated fractal noise is what separates a
    // plasma from a blurred blob. baseFrequency is animated in SMIL rather than
    // CSS because no CSS property reaches inside an SVG filter primitive.
    //
    // That pass is also why the Vibe page crawled on a phone. An SVG filter is
    // rasterised on the CPU, and animating baseFrequency regenerates the whole
    // turbulence field every frame — for a 420x380 element, under a blur, over
    // three counter-rotating layers. Below the breakpoint the filter is not
    // mounted at all and the same layers churn behind a plain blur, which is
    // the difference between a heavy effect and a scrolling page.
    return (
      <div
        className="vibe-aura-blob pointer-events-none absolute z-0 h-[380px] w-[420px] -translate-x-1/2 -translate-y-1/2 opacity-85 mix-blend-screen sm:h-[560px] sm:w-[660px] sm:opacity-95"
        style={style}
        role="img"
        aria-label={`Current Vibe: ${energyLabel} energy and ${discoveryLabel} discovery`}
      >
        {plasma && (
          <svg aria-hidden className="absolute h-0 w-0">
            <filter id="vibe-plasma" x="-30%" y="-30%" width="160%" height="160%">
              <feTurbulence
                type="fractalNoise"
                baseFrequency="0.009 0.014"
                numOctaves={3}
                seed={7}
                result="noise"
              >
                <animate
                  attributeName="baseFrequency"
                  dur={`${(18 - energy * 8).toFixed(1)}s`}
                  values="0.009 0.014; 0.021 0.007; 0.009 0.014"
                  repeatCount="indefinite"
                />
              </feTurbulence>
              <feDisplacementMap
                in="SourceGraphic"
                in2="noise"
                scale={String(Math.round(46 + energy * 70))}
                xChannelSelector="R"
                yChannelSelector="G"
              />
            </filter>
          </svg>
        )}
        <div className={plasma ? 'vibe-aura-stack vibe-aura-stack-plasma' : 'vibe-aura-stack'}>
          <div className="vibe-aura-layer vibe-aura-rays-layer" />
          <div className="vibe-aura-layer vibe-aura-swirl-layer" />
          <div className="vibe-aura-layer vibe-aura-core-layer" />
        </div>
      </div>
    );
  }

  return (
    <div
      className="group relative grid h-16 w-16 shrink-0 place-items-center rounded-full focus:outline-none"
      style={style}
      role="img"
      tabIndex={0}
      aria-label={`Current Vibe: ${energyLabel} energy and ${discoveryLabel} discovery`}
      title={`Current Vibe: ${energyLabel} energy, ${discoveryLabel} discovery`}
    >
      {aura}
    </div>
  );
}
