import type { CSSProperties } from "react"

export type LoginCharacterMood = "idle" | "typing" | "peek" | "error" | "success"

type EyeKind = "eye" | "small-eye" | "pupil"

type FigureSpec = {
  id: "purple" | "black" | "orange" | "yellow"
  eyeKind: EyeKind
  mouth?: "purple" | "orange" | "yellow"
  marks?: number
}

const FIGURES: FigureSpec[] = [
  { id: "purple", eyeKind: "eye", mouth: "purple", marks: 3 },
  { id: "black", eyeKind: "small-eye", marks: 2 },
  { id: "orange", eyeKind: "pupil", mouth: "orange", marks: 2 },
  { id: "yellow", eyeKind: "pupil", mouth: "yellow", marks: 3 },
]

function Eyes({ figure, kind }: { figure: FigureSpec["id"]; kind: EyeKind }) {
  const className = kind === "pupil" ? "login-pupil" : kind === "small-eye" ? "login-eye login-eye--small" : "login-eye"

  return (
    <span className={`login-eyes login-eyes--${figure}`}>
      <span className={className} />
      <span className={className} />
    </span>
  )
}

function Mouth({ type }: { type: NonNullable<FigureSpec["mouth"]> }) {
  if (type === "yellow") {
    return (
      <span className="login-yellow-mouth">
        <svg width="80" height="20" viewBox="0 0 80 20" aria-hidden="true">
          <path d="M0 10 Q10 10, 20 10 Q30 10, 40 10 Q50 10, 60 10 Q70 10, 80 10" />
        </svg>
      </span>
    )
  }

  return <span className={`login-mouth login-mouth--${type}`} />
}

function Figure({ spec }: { spec: FigureSpec }) {
  return (
    <div className={`login-figure login-figure--${spec.id}`}>
      <span className="login-figure__rim" />
      <span className="login-figure__shine" />
      <span className="login-figure__panel" />
      <span className="login-figure__signal">
        {Array.from({ length: spec.marks ?? 0 }).map((_, index) => (
          <span key={index} />
        ))}
      </span>
      <Eyes figure={spec.id} kind={spec.eyeKind} />
      {spec.mouth ? <Mouth type={spec.mouth} /> : null}
    </div>
  )
}

export function AnimatedLoginCharacters({
  mood,
  eyeOffset,
}: {
  mood: LoginCharacterMood
  eyeOffset: { x: number; y: number }
}) {
  return (
    <div
      className="login-character-stage"
      data-mood={mood}
      aria-hidden="true"
      style={
        {
          "--eye-x": `${eyeOffset.x}px`,
          "--eye-y": `${eyeOffset.y}px`,
        } as CSSProperties
      }
    >
      <div className="login-stage-grid" />
      <div className="login-characters-container">
        <div className="login-character-base" />
        {FIGURES.map((spec) => (
          <Figure key={spec.id} spec={spec} />
        ))}
      </div>
    </div>
  )
}
