import { rowIndexForState, type PetRuntimeState } from '../../lib/pets/petState';

const STATE_FRAME_DURATION: Record<PetRuntimeState, string> = {
  idle: '1.2s',
  running: '0.55s',
  runningAlt: '0.55s',
  dispatching: '0.6s',
  jumping: '0.5s',
  waiting: '1.4s',
  done: '0.8s',
  error: '0.55s',
};

export function PetSprite({
  name,
  imageUrl,
  frameWidth,
  frameHeight,
  gridCols,
  gridRows,
  framesPerRow,
  state,
  size,
  reducedMotion,
}: {
  name: string;
  imageUrl: string | null;
  frameWidth: number | null;
  frameHeight: number | null;
  gridCols: number | null;
  gridRows: number | null;
  framesPerRow: number[] | null;
  state: PetRuntimeState;
  size: number;
  reducedMotion: boolean;
}) {
  const className = [
    'pet-sprite',
    `pet-sprite-${state}`,
    reducedMotion ? 'pet-sprite-reduced' : '',
  ].filter(Boolean).join(' ');

  const useGridCrop = !!(imageUrl && gridCols && gridRows && gridCols > 0 && gridRows > 0);
  const useFrameCrop = !useGridCrop && !!(imageUrl && frameWidth && frameHeight);

  const stateRow = useGridCrop ? rowIndexForState(state, gridRows!) : 0;
  const bgPosY = useGridCrop && gridRows! > 1
    ? `${(stateRow / (gridRows! - 1)) * 100}%`
    : '0%';

  const detectedFrames = framesPerRow?.[stateRow];
  const rowFrameCount = Math.max(1, Math.min(8, detectedFrames ?? gridCols ?? 1));
  const cycleAnimation = useGridCrop && !reducedMotion && rowFrameCount > 1
    ? `petFrameCycle${rowFrameCount} ${STATE_FRAME_DURATION[state]} linear infinite`
    : undefined;

  return (
    <div
      className={className}
      style={{
        width: size,
        height: size,
        overflow: useGridCrop || useFrameCrop ? 'hidden' : undefined,
      }}
      aria-hidden="true"
      title={name}
    >
      {imageUrl ? (
        useGridCrop ? (
          <div
            className="pet-sprite-grid"
            style={{
              width: size,
              height: size,
              backgroundImage: `url(${imageUrl})`,
              backgroundRepeat: 'repeat-x',
              backgroundSize: `${gridCols! * 100}% ${gridRows! * 100}%`,
              backgroundPositionY: bgPosY,
              animation: cycleAnimation,
              imageRendering: 'auto',
            }}
          />
        ) : useFrameCrop ? (
          <img
            src={imageUrl}
            alt=""
            draggable={false}
            style={{
              width: 'auto',
              height: 'auto',
              maxWidth: 'none',
              maxHeight: 'none',
              objectFit: 'none',
              transformOrigin: '0 0',
              transform: `scale(${size / frameWidth!})`,
            }}
          />
        ) : (
          <img src={imageUrl} alt="" draggable={false} />
        )
      ) : (
        <div className="pet-sprite-fallback">
          <span />
          <span />
        </div>
      )}
    </div>
  );
}
