import React from 'react';
import './APRSSymbol.scss';

export interface APRSSymbolProps {
  /**
   * APRS symbol as 2-character string: table + code
   * Examples: "/!" (police station), "\!" (emergency), "/-" (house)
   *
   * First character is table identifier:
   * - '/' for primary table
   * - '\' for secondary table
   * - alphanumeric (0-9, A-Z) for overlay
   *
   * Second character is the symbol code
   */
  symbol: string;

  /**
   * Symbol size in pixels (default: 24)
   * Available sizes: 24, 32, 48, 56, 64, 128, 256
   */
  size?: 24 | 32 | 48 | 56 | 64 | 128 | 256;

  /**
   * Alternative text for accessibility
   */
  alt?: string;

  /**
   * Additional CSS class name
   */
  className?: string;
}

/**
 * Get the table ID for the sprite filename
 * - Primary table (/): 0
 * - Secondary table (\): 1
 * - Overlay characters: 2
 */
const getTableId = (table: string): number => {
  if (table === '/') return 0;
  if (table === '\\') return 1;
  return 2; // Overlay
};

/**
 * Calculate sprite position based on ASCII character code
 * Symbols are arranged in a 16-column grid, ordered by ASCII value
 */
const getSymbolPosition = (table: string, code: string): { row: number; col: number } | null => {
  if (!code || code.length !== 1) return null;

  const charCode = code.charCodeAt(0);

  // Primary and secondary tables use characters from ! (33) to } (125)
  if (table === '/' || table === '\\') {
    if (charCode < 33 || charCode > 125) return null;
    const index = charCode - 33;
    return {
      row: Math.floor(index / 16),
      col: index % 16
    };
  }

  // Overlay characters: 0-9 (48-57), A-Z (65-90)
  if (charCode >= 48 && charCode <= 57) {
    // 0-9
    const index = charCode - 48;
    return {
      row: Math.floor(index / 16),
      col: index % 16
    };
  } else if (charCode >= 65 && charCode <= 90) {
    // A-Z
    const index = 10 + (charCode - 65);
    return {
      row: Math.floor(index / 16),
      col: index % 16
    };
  }

  return null;
};

/**
 * React component for rendering APRS symbols from sprite sheets
 */
export const APRSSymbol: React.FC<APRSSymbolProps> = ({
  symbol,
  size = 24,
  alt,
  className = ''
}) => {
  // Parse the symbol string (format: table + code)
  if (!symbol || symbol.length < 2) {
    // Return empty div if symbol is invalid
    return <div className={`aprs-symbol aprs-symbol-${size} ${className}`} title={alt} />;
  }

  const table = symbol.charAt(0);
  const code = symbol.charAt(1);

  const tableId = getTableId(table);
  const position = getSymbolPosition(table, code);

  if (!position) {
    // Return empty div if symbol is invalid
    return <div className={`aprs-symbol aprs-symbol-${size} ${className}`} title={alt} />;
  }

  const { row, col } = position;

  // Build image paths for different resolutions
  const imagePath1x = `/image/protocol/aprs/aprs-symbols-${size}-${tableId}.png`;
  const imagePath2x = `/image/protocol/aprs/aprs-symbols-${size}-${tableId}@2x.png`;
  const imagePath3x = `/image/protocol/aprs/aprs-symbols-${size}-${tableId}@3x.png`;

  // Calculate background position
  const bgX = -(col * size);
  const bgY = -(row * size);

  // Use image-set for retina display support
  const backgroundImage = [
    `-webkit-image-set(url('${imagePath1x}') 1x, url('${imagePath2x}') 2x, url('${imagePath3x}') 3x)`,
    `image-set(url('${imagePath1x}') 1x, url('${imagePath2x}') 2x, url('${imagePath3x}') 3x)`,
    `url('${imagePath1x}')` // Fallback
  ].join(', ');

  const style: React.CSSProperties = {
    backgroundImage,
    backgroundPosition: `${bgX}px ${bgY}px`,
    width: `${size}px`,
    height: `${size}px`
  };

  return (
    <div
      className={`aprs-symbol aprs-symbol-${size} ${className}`}
      style={style}
      title={alt || `APRS symbol: ${symbol}`}
      role="img"
      aria-label={alt || `APRS symbol: ${symbol}`}
    />
  );
};

export default APRSSymbol;
