import { memo, useMemo } from 'react';
import type { BattleToken } from '@/shared/types';
import { cn } from '@/shared/lib/utils';

interface TokenProps {
  token: BattleToken;
  cellSize: number;
  isSelected?: boolean;
  isGM?: boolean;
  onSelect?: () => void;
  onDragStart?: (e: React.DragEvent | React.TouchEvent) => void;
}

// Token size in grid cells based on PF2e creature sizes
const SIZE_MULTIPLIER: Record<number, number> = {
  1: 1,   // Medium
  2: 2,   // Large
  3: 3,   // Huge
  4: 4,   // Gargantuan
};

// HP percentage thresholds for visual indicators
function getHealthClass(hpCurrent: number, hpMax: number): string {
  const percentage = (hpCurrent / hpMax) * 100;
  if (percentage <= 0) return 'bg-gray-600';
  if (percentage <= 20) return 'bg-red-600';
  if (percentage <= 50) return 'bg-yellow-600';
  return 'bg-green-600';
}

export const Token = memo(function Token({
  token,
  cellSize,
  isSelected,
  isGM,
  onSelect,
  onDragStart,
}: TokenProps) {
  const sizeMultiplier = SIZE_MULTIPLIER[token.size] ?? 1;
  const tokenSize = cellSize * sizeMultiplier;
  const padding = 2;

  // Calculate position
  const style = useMemo(() => ({
    left: `${token.positionX * cellSize + padding}px`,
    top: `${token.positionY * cellSize + padding}px`,
    width: `${tokenSize - padding * 2}px`,
    height: `${tokenSize - padding * 2}px`,
  }), [token.positionX, token.positionY, cellSize, tokenSize, padding]);

  // Get initials for token
  const initials = useMemo(() => {
    const words = token.name.split(' ');
    if (words.length >= 2) {
      return (words[0][0] + words[1][0]).toUpperCase();
    }
    return token.name.substring(0, 2).toUpperCase();
  }, [token.name]);

  // Determine if this is a PC or NPC/Monster
  const isPC = !!token.characterId;
  const healthClass = getHealthClass(token.hpCurrent, token.hpMax);

  return (
    <div
      className={cn(
        'absolute rounded-full cursor-pointer transition-all duration-100',
        'flex items-center justify-center',
        'border-2 shadow-lg',
        isSelected ? 'ring-2 ring-primary ring-offset-2 ring-offset-black z-20' : 'z-10',
        isPC ? 'border-blue-400' : 'border-red-400',
        'hover:scale-110',
      )}
      style={style}
      onClick={onSelect}
      draggable={isGM}
      onDragStart={onDragStart}
      onTouchStart={onDragStart}
      title={`${token.name}${token.initiative !== null ? ` (Init: ${token.initiative})` : ''}`}
    >
      {/* Background with health indicator */}
      <div className={cn(
        'absolute inset-0 rounded-full',
        isPC ? 'bg-blue-900' : 'bg-red-900',
      )} />

      {/* HP bar */}
      <div
        className={cn(
          'absolute bottom-0 left-0 right-0 h-1 rounded-b-full transition-all',
          healthClass,
        )}
        style={{ width: `${Math.max(0, Math.min(100, (token.hpCurrent / token.hpMax) * 100))}%` }}
      />

      {/* Token content */}
      <div className="relative z-10 flex flex-col items-center justify-center">
        <span className="text-xs font-bold text-white drop-shadow-lg">
          {initials}
        </span>
        {/* Show HP for GM, or for PCs */}
        {(isGM || isPC) && (
          <span className="text-[10px] text-white/80">
            {token.hpCurrent}/{token.hpMax}
          </span>
        )}
      </div>

      {/* Initiative badge */}
      {token.initiative !== null && token.initiative !== undefined && (
        <div className="absolute -top-1 -right-1 w-4 h-4 rounded-full bg-primary text-[10px] font-bold text-white flex items-center justify-center">
          {token.initiative}
        </div>
      )}

      {/* Conditions indicator */}
      {token.conditions.length > 0 && (
        <div className="absolute -bottom-1 -right-1 w-4 h-4 rounded-full bg-yellow-500 text-[10px] font-bold text-black flex items-center justify-center">
          {token.conditions.length}
        </div>
      )}
    </div>
  );
});
