/* global sprintf */
/**
 * Character Counter Component
 *
 * Shows character count with visual indicators for optimal length.
 *
 * @package
 */

import { __, sprintf } from '@wordpress/i18n';
import { useMemo } from '@wordpress/element';

const CharacterCounter = ({
  value = '',
  recommended = 160,
  minimum = 0,
  type = 'text',
  softOverage = 1,
  hardOverage = 10,
  emptyMessage = null,
  showPixels = true,
  fallbackNote = null,
}) => {
  const length = value.length;
  const warningLimit = recommended + Math.max(0, softOverage);
  const hardLimit = recommended + Math.max(Math.max(0, softOverage), Math.max(0, hardOverage));

  // Calculate percentage for progress bar
  const percentage = useMemo(() => {
    if (length === 0) return 0;
    return Math.min((length / hardLimit) * 100, 100);
  }, [length, hardLimit]);

  // Determine status color
  const status = useMemo(() => {
    if (length === 0) return 'empty';
    if (length < minimum) return 'short';
    if (length <= warningLimit) return 'good';
    if (length < hardLimit) return 'warning';
    return 'long';
  }, [length, minimum, warningLimit, hardLimit]);

  // Get status message
  const statusMessage = useMemo(() => {
    switch (status) {
      case 'empty':
        if (emptyMessage !== null) {
          return emptyMessage;
        }
        return type === 'title'
          ? __('Add an SEO title', 'prorank-seo')
          : __('Add a meta description', 'prorank-seo');
      case 'short':
        return __('Too short', 'prorank-seo');
      case 'good':
        return __('Good length', 'prorank-seo');
      case 'warning':
        return __('Slightly long', 'prorank-seo');
      case 'long':
        return __('Too long', 'prorank-seo');
      default:
        return '';
    }
  }, [status, type, emptyMessage]);

  // Calculate pixel width approximation (rough estimate).
  // Titles render in Google's ~20px result font (~9.2px/char, same constant the
  // Headline Analyzer uses, so the two estimates agree); descriptions in ~13px (~6.5px/char).
  const pixelWidth = useMemo(() => {
    const avgCharWidth = type === 'title' ? 9.2 : 6.5;
    return Math.round(length * avgCharWidth);
  }, [length, type]);

  // Prepare translated strings
  const characterCountText = sprintf(
    /* translators: %1$d: current character count, %2$d: recommended character count */
    __('%1$d / %2$d characters', 'prorank-seo'),
    length,
    recommended
  );
  /* translators: %d: approximate pixel width */
  const pixelWidthText = sprintf(__('~%d pixels', 'prorank-seo'), pixelWidth);

  return (
    <div className={`prorank-character-counter prorank-character-counter--${status}`}>
      <div className="prorank-character-counter__bar">
        <div
          className="prorank-character-counter__progress"
          style={{
            width: `${percentage}%`,
            // Add min-width to ensure visibility even for small values
            minWidth: length > 0 ? '2px' : '0',
          }}
          role="progressbar"
          aria-valuenow={length}
          aria-valuemin={0}
          aria-valuemax={recommended}
          aria-label={__('Character count', 'prorank-seo')}
        />
      </div>

      <div className="prorank-character-counter__info">
        <span className="prorank-character-counter__count">{characterCountText}</span>

        {showPixels && (
          <span className="prorank-character-counter__pixels">{pixelWidthText}</span>
        )}

        <span className="prorank-character-counter__status">{statusMessage}</span>

        {fallbackNote && (
          <span className="prorank-character-counter__fallback">{fallbackNote}</span>
        )}
      </div>
    </div>
  );
};

export default CharacterCounter;
