/**
 * ProRank SEO - CharacterBar Component
 *
 * Visual character count indicator with color zones
 * Shows optimal, warning, and danger zones for SEO titles/descriptions
 *
 * @package ProRank\SEO
 */

import { useState, useEffect } from '@wordpress/element';

/**
 * Get zone color based on current count and limits
 */
const getZoneStatus = (current, min, optimal, max) => {
  if (current === 0) {
    return {
      color: 'var(--pr-text-muted, #9CA3AF)',
      status: 'empty',
      message: 'Start typing...'
    };
  }
  if (current < min) {
    return {
      color: 'var(--pr-char-warning, #F59E0B)',
      status: 'short',
      message: 'Too short'
    };
  }
  if (current <= optimal) {
    return {
      color: 'var(--pr-char-optimal, #3b82f6)',
      status: 'optimal',
      message: 'Optimal length'
    };
  }
  if (current <= max) {
    return {
      color: 'var(--pr-char-safe, #3b82f6)',
      status: 'good',
      message: 'Good length'
    };
  }
  return {
    color: 'var(--pr-char-danger, #EF4444)',
    status: 'truncated',
    message: (current - max) + ' chars over limit'
  };
};

/**
 * CharacterBar Component
 */
const CharacterBar = ({
  current = 0,
  min = 30,
  optimal = 50,
  max = 60,
  showZones = true,
  showCount = true,
  showStatus = false,
  animate = true,
  label,
  className = '',
}) => {
  const [animatedWidth, setAnimatedWidth] = useState(0);
  const zoneInfo = getZoneStatus(current, min, optimal, max);

  const percentage = Math.min((current / max) * 100, 110);
  const minZoneWidth = (min / max) * 100;
  const optimalZoneWidth = (optimal / max) * 100;

  useEffect(() => {
    if (!animate) {
      setAnimatedWidth(percentage);
      return;
    }

    const duration = 300;
    const startValue = animatedWidth;
    const endValue = percentage;
    const startTime = Date.now();

    const animateWidth = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / duration, 1);
      const eased = 1 - Math.pow(1 - progress, 2);
      setAnimatedWidth(startValue + (endValue - startValue) * eased);

      if (progress < 1) {
        requestAnimationFrame(animateWidth);
      }
    };

    requestAnimationFrame(animateWidth);
  }, [percentage, animate]);

  const wrapperStyle = {
    display: 'flex',
    flexDirection: 'column',
    gap: '6px',
  };

  const headerStyle = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
  };

  const labelStyle = {
    fontSize: '12px',
    fontWeight: 500,
    color: 'var(--pr-text-secondary, #6B7280)',
  };

  const countStyle = {
    fontSize: '12px',
    fontWeight: 600,
    fontVariantNumeric: 'tabular-nums',
    transition: 'color 150ms ease',
    color: zoneInfo.color,
  };

  const barStyle = {
    position: 'relative',
    height: '6px',
    background: 'var(--pr-border, #E5E7EB)',
    borderRadius: '3px',
    overflow: 'visible',
  };

  const zonesStyle = {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    display: 'flex',
    borderRadius: '3px',
    overflow: 'hidden',
  };

  const fillStyle = {
    position: 'absolute',
    top: 0,
    left: 0,
    height: '100%',
    borderRadius: zoneInfo.status === 'truncated' ? '3px 0 0 3px' : '3px',
    transition: 'width 250ms ease, background-color 150ms ease',
    width: Math.min(animatedWidth, 100) + '%',
    backgroundColor: zoneInfo.color,
  };

  const markerStyle = {
    position: 'absolute',
    top: '-2px',
    width: '2px',
    height: '10px',
    background: 'var(--pr-char-optimal, #3b82f6)',
    borderRadius: '1px',
    transform: 'translateX(-50%)',
    opacity: 0.6,
    left: optimalZoneWidth + '%',
  };

  const statusStyle = {
    display: 'flex',
    alignItems: 'center',
    gap: '4px',
    fontSize: '11px',
    fontWeight: 500,
    color: zoneInfo.color,
  };

  return (
    <div className={'pr:char-bar-wrapper ' + className} style={wrapperStyle}>
      {(label || showCount) && (
        <div style={headerStyle}>
          {label && <span style={labelStyle}>{label}</span>}
          {showCount && (
            <span style={countStyle}>
              <span>{current}</span>
              <span style={{ opacity: 0.5, margin: '0 1px' }}>/</span>
              <span style={{ opacity: 0.7 }}>{max}</span>
            </span>
          )}
        </div>
      )}

      <div style={barStyle}>
        {showZones && (
          <div style={zonesStyle}>
            <div style={{ height: '100%', opacity: 0.12, background: 'var(--pr-char-warning, #F59E0B)', width: minZoneWidth + '%' }} />
            <div style={{ height: '100%', opacity: 0.12, background: 'var(--pr-char-optimal, #3b82f6)', width: (optimalZoneWidth - minZoneWidth) + '%' }} />
            <div style={{ height: '100%', opacity: 0.12, background: 'var(--pr-char-safe, #3b82f6)', width: (100 - optimalZoneWidth) + '%' }} />
          </div>
        )}
        <div style={fillStyle} />
        {current > max && (
          <div style={{
            position: 'absolute',
            top: 0,
            right: 0,
            height: '100%',
            background: 'var(--pr-char-danger, #EF4444)',
            borderRadius: '0 3px 3px 0',
            opacity: 0.5,
            width: Math.min((current - max) / max * 100, 10) + '%',
          }} />
        )}
        <div style={markerStyle} title={'Optimal: ' + optimal + ' chars'} />
      </div>

      {showStatus && (
        <div style={statusStyle}>
          {zoneInfo.status === 'optimal' && (
            <svg width="12" height="12" viewBox="0 0 20 20" fill="currentColor">
              <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
            </svg>
          )}
          {zoneInfo.status === 'truncated' && (
            <svg width="12" height="12" viewBox="0 0 20 20" fill="currentColor">
              <path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
            </svg>
          )}
          <span>{zoneInfo.message}</span>
        </div>
      )}
    </div>
  );
};

/**
 * Preset configurations for common SEO fields
 */
export const CharacterBarPresets = {
  seoTitle: { min: 30, optimal: 55, max: 60, label: 'SEO Title' },
  metaDescription: { min: 120, optimal: 150, max: 160, label: 'Meta Description' },
  ogTitle: { min: 40, optimal: 60, max: 90, label: 'OG Title' },
  ogDescription: { min: 100, optimal: 150, max: 200, label: 'OG Description' },
  twitterTitle: { min: 40, optimal: 55, max: 70, label: 'Twitter Title' },
  twitterDescription: { min: 100, optimal: 150, max: 200, label: 'Twitter Description' },
};

export default CharacterBar;
export { getZoneStatus };
