/**
 * StylePanel Component
 * 
 * Dynamic style controls panel that appears when an element is selected.
 * Renders different control groups based on the element's category.
 * Allows real-time editing of inline styles on the selected DOM element.
 */

import React, { useState, useCallback, useEffect } from 'react';
import { SelectedElement, StyleProperty, StyleGroup } from '../types/editor';
import { 
  getStyleGroupsForCategory, 
  parseStyleValue, 
  formatStyleValue,
  rgbToHex,
  getFontDisplayName 
} from '../config/styleConfig';
import { getElementPath, getElementTextPreview } from '../utils/selector';

interface StylePanelProps {
  selectedElement: SelectedElement | null;
  onStyleChange: (property: string, value: string) => void;
  onDeselect: () => void;
}

// Styles for the panel (inline to avoid external dependencies)
const panelStyles: { [key: string]: React.CSSProperties } = {
  container: {
    width: '320px',
    height: '100%',
    backgroundColor: '#1a1a1a',
    borderLeft: '1px solid #2a2a2a',
    display: 'flex',
    flexDirection: 'column',
    fontFamily: 'system-ui, -apple-system, sans-serif',
    fontSize: '13px',
    color: '#e5e5e5',
    overflow: 'hidden'
  },
  header: {
    padding: '16px',
    borderBottom: '1px solid #2a2a2a',
    backgroundColor: '#222'
  },
  headerTitle: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: '8px'
  },
  tagBadge: {
    backgroundColor: '#2563eb',
    color: 'white',
    padding: '4px 10px',
    borderRadius: '4px',
    fontSize: '12px',
    fontWeight: '600',
    textTransform: 'uppercase' as const
  },
  closeButton: {
    background: 'none',
    border: 'none',
    color: '#888',
    cursor: 'pointer',
    padding: '4px 8px',
    fontSize: '18px',
    lineHeight: 1
  },
  elementPath: {
    fontSize: '11px',
    color: '#666',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap' as const
  },
  content: {
    flex: 1,
    overflowY: 'auto' as const,
    padding: '8px 0'
  },
  group: {
    marginBottom: '8px'
  },
  groupHeader: {
    padding: '12px 16px 8px',
    fontSize: '11px',
    fontWeight: '600',
    color: '#888',
    textTransform: 'uppercase' as const,
    letterSpacing: '0.5px'
  },
  propertyRow: {
    display: 'flex',
    alignItems: 'center',
    padding: '6px 16px',
    gap: '12px'
  },
  propertyLabel: {
    flex: '0 0 90px',
    fontSize: '12px',
    color: '#aaa'
  },
  propertyControl: {
    flex: 1,
    display: 'flex',
    alignItems: 'center',
    gap: '4px'
  },
  input: {
    flex: 1,
    backgroundColor: '#2a2a2a',
    border: '1px solid #3a3a3a',
    borderRadius: '4px',
    padding: '6px 8px',
    color: '#e5e5e5',
    fontSize: '12px',
    outline: 'none'
  },
  select: {
    flex: 1,
    backgroundColor: '#2a2a2a',
    border: '1px solid #3a3a3a',
    borderRadius: '4px',
    padding: '6px 8px',
    color: '#e5e5e5',
    fontSize: '12px',
    cursor: 'pointer',
    outline: 'none'
  },
  colorInput: {
    width: '32px',
    height: '32px',
    padding: '2px',
    backgroundColor: '#2a2a2a',
    border: '1px solid #3a3a3a',
    borderRadius: '4px',
    cursor: 'pointer'
  },
  colorHex: {
    flex: 1,
    backgroundColor: '#2a2a2a',
    border: '1px solid #3a3a3a',
    borderRadius: '4px',
    padding: '6px 8px',
    color: '#e5e5e5',
    fontSize: '12px',
    fontFamily: 'monospace'
  },
  unitLabel: {
    fontSize: '11px',
    color: '#666',
    minWidth: '20px'
  },
  emptyState: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    height: '100%',
    color: '#666',
    textAlign: 'center' as const,
    padding: '40px'
  }
};

export const StylePanel: React.FC<StylePanelProps> = ({
  selectedElement,
  onStyleChange,
  onDeselect
}) => {
  // Track expanded groups
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  
  // Initialize all groups as expanded when element changes
  useEffect(() => {
    if (selectedElement) {
      const groups = getStyleGroupsForCategory(selectedElement.category);
      setExpandedGroups(new Set(groups.map(g => g.title)));
    }
  }, [selectedElement?.category]);
  
  const toggleGroup = useCallback((title: string) => {
    setExpandedGroups(prev => {
      const next = new Set(prev);
      if (next.has(title)) {
        next.delete(title);
      } else {
        next.add(title);
      }
      return next;
    });
  }, []);
  
  // Get current computed style value for a property
  const getStyleValue = useCallback((property: string): string => {
    if (!selectedElement) return '';
    
    // First check inline style
    const inlineValue = selectedElement.node.style.getPropertyValue(property);
    if (inlineValue) return inlineValue;
    
    // Fall back to computed style
    const computed = selectedElement.computedStyles.getPropertyValue(property);
    return computed || '';
  }, [selectedElement]);
  
  // Render empty state when nothing is selected
  if (!selectedElement) {
    return (
      <div style={panelStyles.container}>
        <div style={panelStyles.emptyState}>
          <div>
            <div style={{ fontSize: '24px', marginBottom: '12px' }}>🎯</div>
            <div style={{ fontWeight: '500', marginBottom: '8px' }}>No Element Selected</div>
            <div style={{ fontSize: '12px', color: '#555' }}>
              Click on an element in the canvas to edit its styles
            </div>
          </div>
        </div>
      </div>
    );
  }
  
  const styleGroups = getStyleGroupsForCategory(selectedElement.category);
  const elementPath = getElementPath(selectedElement.node);
  const textPreview = getElementTextPreview(selectedElement.node);
  
  return (
    <div style={panelStyles.container}>
      {/* Header with element info */}
      <div style={panelStyles.header}>
        <div style={panelStyles.headerTitle}>
          <span style={panelStyles.tagBadge}>
            {selectedElement.tagName}
          </span>
          <button 
            style={panelStyles.closeButton}
            onClick={onDeselect}
            title="Deselect element"
          >
            ×
          </button>
        </div>
        <div style={panelStyles.elementPath} title={elementPath.join(' > ')}>
          {elementPath.slice(-3).join(' › ')}
        </div>
        {textPreview && (
          <div style={{ ...panelStyles.elementPath, marginTop: '4px', fontStyle: 'italic' }}>
            "{textPreview}"
          </div>
        )}
      </div>
      
      {/* Scrollable content area with style groups */}
      <div style={panelStyles.content}>
        {styleGroups.map(group => (
          <StyleGroupComponent
            key={group.title}
            group={group}
            isExpanded={expandedGroups.has(group.title)}
            onToggle={() => toggleGroup(group.title)}
            getStyleValue={getStyleValue}
            onStyleChange={onStyleChange}
          />
        ))}
      </div>
    </div>
  );
};

// Individual style group component
interface StyleGroupComponentProps {
  group: StyleGroup;
  isExpanded: boolean;
  onToggle: () => void;
  getStyleValue: (property: string) => string;
  onStyleChange: (property: string, value: string) => void;
}

const StyleGroupComponent: React.FC<StyleGroupComponentProps> = ({
  group,
  isExpanded,
  onToggle,
  getStyleValue,
  onStyleChange
}) => {
  return (
    <div style={panelStyles.group}>
      <div 
        style={{
          ...panelStyles.groupHeader,
          cursor: 'pointer',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between'
        }}
        onClick={onToggle}
      >
        <span>{group.title}</span>
        <span style={{ fontSize: '10px' }}>{isExpanded ? '▼' : '▶'}</span>
      </div>
      
      {isExpanded && group.properties.map(property => (
        <StylePropertyControl
          key={property.cssProperty}
          property={property}
          value={getStyleValue(property.cssProperty)}
          onChange={(value) => onStyleChange(property.cssProperty, value)}
        />
      ))}
    </div>
  );
};

// Individual property control component
interface StylePropertyControlProps {
  property: StyleProperty;
  value: string;
  onChange: (value: string) => void;
}

const StylePropertyControl: React.FC<StylePropertyControlProps> = ({
  property,
  value,
  onChange
}) => {
  // Local state for input value (allows typing without losing focus)
  const [localValue, setLocalValue] = useState(value);
  
  // Sync local value when external value changes
  useEffect(() => {
    setLocalValue(value);
  }, [value]);
  
  const handleInputChange = (newValue: string) => {
    setLocalValue(newValue);
  };
  
  const handleInputBlur = () => {
    if (localValue !== value) {
      onChange(localValue);
    }
  };
  
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      onChange(localValue);
    }
  };
  
  // Render different control types
  const renderControl = () => {
    switch (property.type) {
      case 'color':
        return <ColorControl value={value} onChange={onChange} />;
        
      case 'select':
        return (
          <select
            style={panelStyles.select}
            value={value}
            onChange={(e) => onChange(e.target.value)}
          >
            {property.options?.map(option => (
              <option key={option} value={option}>
                {property.cssProperty === 'fontFamily' 
                  ? getFontDisplayName(option)
                  : option}
              </option>
            ))}
          </select>
        );
        
      case 'unit':
        return (
          <UnitControl
            value={localValue}
            unit={property.unit || 'px'}
            onChange={handleInputChange}
            onBlur={handleInputBlur}
            onKeyDown={handleKeyDown}
          />
        );
        
      case 'number':
        return (
          <input
            type="number"
            style={panelStyles.input}
            value={parseStyleValue(localValue).value || ''}
            onChange={(e) => handleInputChange(e.target.value)}
            onBlur={handleInputBlur}
            onKeyDown={handleKeyDown}
          />
        );
        
      case 'slider':
        const sliderValue = parseStyleValue(localValue).value;
        return (
          <div style={{ ...panelStyles.propertyControl, flexDirection: 'column', alignItems: 'stretch', gap: '4px' }}>
            <input
              type="range"
              min={property.min ?? 0}
              max={property.max ?? 100}
              step={property.step ?? 1}
              value={sliderValue}
              onChange={(e) => onChange(formatStyleValue(Number(e.target.value), property.unit || ''))}
              style={{ width: '100%' }}
            />
            <div style={{ fontSize: '10px', textAlign: 'right', color: '#666' }}>
              {sliderValue}{property.unit}
            </div>
          </div>
        );
        
      default:
        return (
          <input
            type="text"
            style={panelStyles.input}
            value={localValue}
            onChange={(e) => handleInputChange(e.target.value)}
            onBlur={handleInputBlur}
            onKeyDown={handleKeyDown}
          />
        );
    }
  };
  
  return (
    <div style={panelStyles.propertyRow}>
      <label style={panelStyles.propertyLabel}>{property.name}</label>
      <div style={panelStyles.propertyControl}>
        {renderControl()}
      </div>
    </div>
  );
};

// Color picker control
interface ColorControlProps {
  value: string;
  onChange: (value: string) => void;
}

const ColorControl: React.FC<ColorControlProps> = ({ value, onChange }) => {
  const hexValue = rgbToHex(value);
  const [localHex, setLocalHex] = useState(hexValue);
  
  useEffect(() => {
    setLocalHex(rgbToHex(value));
  }, [value]);
  
  return (
    <>
      <input
        type="color"
        style={panelStyles.colorInput}
        value={hexValue}
        onChange={(e) => {
          setLocalHex(e.target.value);
          onChange(e.target.value);
        }}
      />
      <input
        type="text"
        style={panelStyles.colorHex}
        value={localHex}
        onChange={(e) => setLocalHex(e.target.value)}
        onBlur={() => onChange(localHex)}
        onKeyDown={(e) => e.key === 'Enter' && onChange(localHex)}
        maxLength={7}
      />
    </>
  );
};

// Unit input control (value + unit)
interface UnitControlProps {
  value: string;
  unit: string;
  onChange: (value: string) => void;
  onBlur: () => void;
  onKeyDown: (e: React.KeyboardEvent) => void;
}

const UnitControl: React.FC<UnitControlProps> = ({ 
  value, 
  unit, 
  onChange, 
  onBlur,
  onKeyDown 
}) => {
  const parsed = parseStyleValue(value);
  const displayValue = parsed.value || '';
  const displayUnit = parsed.unit || unit;
  
  return (
    <>
      <input
        type="number"
        style={panelStyles.input}
        value={displayValue}
        onChange={(e) => {
          const numValue = e.target.value;
          onChange(numValue ? `${numValue}${displayUnit}` : '');
        }}
        onBlur={onBlur}
        onKeyDown={onKeyDown}
      />
      {displayUnit && (
        <span style={panelStyles.unitLabel}>{displayUnit}</span>
      )}
    </>
  );
};

export default StylePanel;
