'use client';

import { useEffect, useMemo, useState } from 'react';

export type CoachAvatarState =
  | 'idle'
  | 'listening'
  | 'thinking'
  | 'speaking';

export type CoachAvatarSize = 'sm' | 'md' | 'lg';

interface SehatAvatarProps {
  state?: CoachAvatarState;
  size?: CoachAvatarSize;
  className?: string;
}

interface CoachAvatarFrameConfig {
  id: string;
  label: string;
  url: string;
  enabled: boolean;
}

interface CoachAvatarConfig {
  durationMs: number;
  sequence: string[];
  sequences: Record<CoachAvatarState, string[]>;
  states: Record<string, CoachAvatarFrameConfig>;
}

const SIZE_PX: Record<CoachAvatarSize, number> = { sm: 48, md: 64, lg: 88 };

const STATE_CLASS: Record<CoachAvatarState, string> = {
  idle: 'coach-agent-idle',
  listening: 'coach-agent-listening',
  thinking: 'coach-agent-thinking',
  speaking: 'coach-agent-speaking',
};

const FALLBACK_FRAME: CoachAvatarFrameConfig = {
  id: 'idle',
  label: 'Idle',
  url: '/brand/sehat-ai-agent-idle.png',
  enabled: true,
};

const DEFAULT_AVATAR_CONFIG: CoachAvatarConfig = {
  durationMs: 5600,
  sequence: ['idle', 'idle-bright', 'sleepy', 'calm', 'wave', 'listen', 'explain', 'present', 'happy', 'hands', 'thumbs'],
  sequences: {
    idle: ['idle', 'idle-bright', 'sleepy', 'calm'],
    listening: ['idle', 'listen', 'idle-bright', 'calm'],
    thinking: ['idle', 'sleepy', 'calm', 'idle-bright'],
    speaking: ['wave', 'explain', 'present', 'happy', 'thumbs'],
  },
  states: {
    idle: FALLBACK_FRAME,
    'idle-bright': { id: 'idle-bright', label: 'Idle bright', url: '/brand/sehat-ai-agent-idle-bright.png', enabled: true },
    sleepy: { id: 'sleepy', label: 'Sleepy blink', url: '/brand/sehat-ai-agent-sleepy.png', enabled: true },
    calm: { id: 'calm', label: 'Calm blink', url: '/brand/sehat-ai-agent-calm.png', enabled: true },
    wave: { id: 'wave', label: 'Wave', url: '/brand/sehat-ai-agent-wave.png', enabled: true },
    listen: { id: 'listen', label: 'Listening', url: '/brand/sehat-ai-agent-listen.png', enabled: true },
    explain: { id: 'explain', label: 'Explaining', url: '/brand/sehat-ai-agent-explain.png', enabled: true },
    present: { id: 'present', label: 'Presenting', url: '/brand/sehat-ai-agent-present.png', enabled: true },
    happy: { id: 'happy', label: 'Happy', url: '/brand/sehat-ai-agent-happy.png', enabled: true },
    hands: { id: 'hands', label: 'Hands folded', url: '/brand/sehat-ai-agent-hands.png', enabled: true },
    thumbs: { id: 'thumbs', label: 'Thumbs up', url: '/brand/sehat-ai-agent-thumbs.png', enabled: true },
  },
};

export function SehatAvatar({
  state = 'idle',
  size = 'md',
  className,
}: SehatAvatarProps) {
  const [config, setConfig] = useState<CoachAvatarConfig>(DEFAULT_AVATAR_CONFIG);
  const [frameIndex, setFrameIndex] = useState(0);
  const dim = SIZE_PX[size];
  const classes = [
    'coach-agent-avatar',
    `coach-agent-${size}`,
    STATE_CLASS[state],
    className,
  ]
    .filter(Boolean)
    .join(' ');
  const frames = useMemo(() => {
    const ids =
      config.sequences[state]?.length > 0
        ? config.sequences[state]
        : config.sequence;
    const selected = ids
      .map((id) => config.states[id])
      .filter((frame): frame is CoachAvatarFrameConfig => Boolean(frame?.url && frame.enabled !== false));
    return selected.length ? selected : [FALLBACK_FRAME];
  }, [config, state]);
  const sequenceKey = frames.map((frame) => frame.id).join('|');
  const currentFrame = frames[frameIndex % frames.length] ?? FALLBACK_FRAME;

  useEffect(() => {
    let alive = true;
    fetch('/api/coach-avatar', { cache: 'no-store' })
      .then((res) => (res.ok ? res.json() : null))
      .then((next) => {
        if (alive && isCoachAvatarConfig(next)) setConfig(next);
      })
      .catch(() => undefined);
    return () => {
      alive = false;
    };
  }, []);

  useEffect(() => {
    setFrameIndex(0);
    if (frames.length <= 1) return;
    const intervalMs = Math.max(160, Math.round(config.durationMs / frames.length));
    const timer = window.setInterval(() => {
      setFrameIndex((current) => (current + 1) % frames.length);
    }, intervalMs);
    return () => window.clearInterval(timer);
  }, [config.durationMs, frames.length, sequenceKey]);

  return (
    <span
      className={classes}
      style={{ width: dim, height: dim }}
      aria-hidden="true"
    >
      <span
        className="coach-agent-character"
        style={{ backgroundImage: `url("${currentFrame.url}")` }}
      />
    </span>
  );
}

function isCoachAvatarConfig(value: unknown): value is CoachAvatarConfig {
  if (!value || typeof value !== 'object') return false;
  const candidate = value as Partial<CoachAvatarConfig>;
  return (
    typeof candidate.durationMs === 'number' &&
    Array.isArray(candidate.sequence) &&
    Boolean(candidate.sequences) &&
    Boolean(candidate.states)
  );
}
