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

import { AnimationState, Character, CharacterAnimationConfig } from '../types';

interface CharacterAnimatorProps {
  state: AnimationState;
  character: Character;
  className?: string;
  style?: React.CSSProperties;
  imageClassName?: string;
}

const DEFAULT_ANIMATIONS: Record<AnimationState, CharacterAnimationConfig> = {
  [AnimationState.ACQUIRE]: { frames: 1, prefix: 'acquire', folder: 'acquire' },
  [AnimationState.ATTACK]: { frames: 1, prefix: 'Attack', folder: 'attack' },
  [AnimationState.RUN]: { frames: 1, prefix: 'Run', folder: 'run' },
  [AnimationState.DOUBLE_JUMP]: { frames: 1, prefix: 'double jump', folder: 'double jump' },
  [AnimationState.JUMP_ATTACK]: { frames: 1, prefix: 'jump attack', folder: 'jump attack' },
  [AnimationState.DASH]: { frames: 1, prefix: 'dash', folder: 'dash' },
  [AnimationState.HURT]: { frames: 1, prefix: 'hurt', folder: 'hurt' },
  [AnimationState.DIE]: { frames: 1, prefix: 'die', folder: 'die' },
  [AnimationState.CLIMB]: { frames: 1, prefix: 'Climb', folder: 'climb' },
  [AnimationState.SKILL1]: { frames: 1, prefix: 'skill1', folder: 'skill1' },
  [AnimationState.SKILL1_JUMP]: { frames: 1, prefix: 'skill1 jump', folder: 'skill1 jump' },
  [AnimationState.SKILL1_BULLET]: { frames: 1, prefix: 'skill1 bullet', folder: 'skill1 bullet' },
  [AnimationState.SKILL1_BULLET_FX]: { frames: 1, prefix: 'skill1 bullet FX', folder: 'skill1 bullet FX' },
  [AnimationState.SKILL2]: { frames: 1, prefix: 'skill2', folder: 'skill2' },
  [AnimationState.SKILL2_JUMP]: { frames: 1, prefix: 'skill2 jump', folder: 'skill2 jump' },
  [AnimationState.SKILL3]: { frames: 1, prefix: 'skill3', folder: 'skill3' },
  [AnimationState.SKILL3_JUMP]: { frames: 1, prefix: 'skill3 jump', folder: 'skill3 jump' },
  [AnimationState.SKILL3_BULLET]: { frames: 1, prefix: 'skill3 bullet', folder: 'skill3 bullet' },
  [AnimationState.SKILL3_BULLET_FX]: { frames: 1, prefix: 'skill3 bullet FX', folder: 'skill3 bullet FX' },
  [AnimationState.SKILL4]: { frames: 1, prefix: 'skill4', folder: 'skill4' },
  [AnimationState.WALL_SLIDE]: { frames: 1, prefix: 'Wall Slide', folder: 'Wall Slide' },
  [AnimationState.IDLE]: { frames: 1, prefix: 'Idle', folder: 'idle' },
  [AnimationState.JUMP]: { frames: 1, prefix: 'Jump', folder: 'jump' },
};

export const CharacterAnimator: React.FC<CharacterAnimatorProps> = ({
  state,
  character,
  className,
  style,
  imageClassName,
}) => {
  const [frameIndex, setFrameIndex] = useState(1);
  const config =
    character.animationMap?.[state] ??
    DEFAULT_ANIMATIONS[state] ??
    character.animationMap?.[AnimationState.IDLE] ??
    DEFAULT_ANIMATIONS[AnimationState.IDLE];

  useEffect(() => {
    setFrameIndex(config.startFrame || 1);

    if (config.frames <= 1) return;

    const interval = setInterval(() => {
      setFrameIndex(prev => {
        const start = config.startFrame || 1;
        const end = start + config.frames - 1;
        return prev >= end ? start : prev + 1;
      });
    }, 100);

    return () => clearInterval(interval);
  }, [config]);

  const frameNumber = frameIndex.toString().padStart(2, '0');
  const normalizedBasePath = config.basePath?.replace(/\/+$/u, '');
  const imagePath = normalizedBasePath
    ? config.file
      ? `${normalizedBasePath}/${encodeURIComponent(config.file)}`
      : `${normalizedBasePath}/${config.prefix}${frameNumber}.${config.extension ?? 'png'}`
    : (() => {
        const folder = encodeURIComponent(character.assetFolder);
        const variant = encodeURIComponent(character.assetVariant);
        const animationFolder = encodeURIComponent(config.folder);
        return config.file
          ? `/character/${folder}/${variant}/Hero/${animationFolder}/${encodeURIComponent(config.file)}`
          : `/character/${folder}/${variant}/Hero/${animationFolder}/${config.prefix}${frameNumber}.${config.extension ?? 'png'}`;
      })();
  const resolvedImageClassName = `h-full w-full object-contain pixelated ${imageClassName ?? ''}`.trim();

  return (
    <div className={`relative ${className ?? ''}`} style={style}>
      <img
        src={imagePath}
        alt={`${character.name} ${state} animation`}
        className={resolvedImageClassName}
        style={{ imageRendering: 'pixelated' }}
        onError={(e) => {
          const target = e.target as HTMLImageElement;
          target.src = character.portrait;
          target.className = resolvedImageClassName;
        }}
      />
    </div>
  );
};
