/**
 * Chat Header Component
 * Shows bot info and action buttons
 * 
 * @since 1.5.0 - Added full appearance preset support
 */

import React from 'react';
import { motion } from 'framer-motion';
import {
  Bot,
  RotateCcw,
  ShoppingCart,
  type LucideIcon,
} from 'lucide-react';
import { useChatStore } from '@/store/chatStore';
import { resolveValue, resolveTypography, GlobalValues, clampTypography, clampHeight } from '@/utils/resolveAppearance';
import { t } from '@/lib/i18n';
import { HEADER_LUCIDE_ICON_MAP } from '@/utils/headerLucideIconMap'
import { cartDebugLog, getWooCartCount } from '@/utils/cart';
import { getResolvedCartAppearance } from './cart/cartAppearance';

export function ChatHeader() {
  const { config, toggleChat, isTyping, clearChat, cart, isCartOpen, toggleCart } = useChatStore();
  
  // Get appearance settings
  const globalValues = (config.appearance_preset?.global_values || {}) as GlobalValues;
  const headerSettings = config.element_settings?.header || config.appearance_preset?.element_settings?.header;
  
  // Resolve all header settings with clamping
  const background = resolveValue(headerSettings?.background, globalValues, config.primary_color || '#3BC2D0');
  const textColor = resolveValue(headerSettings?.text, globalValues, '#FFFFFF');
  const rawHeight = resolveValue(headerSettings?.height, globalValues, '60px');
  const height = clampHeight(rawHeight, 'header', '60px');
  const padding = resolveValue(headerSettings?.padding, globalValues, '0 16px');
  const headerBorderRadius = resolveValue(headerSettings?.borderRadius, globalValues, '16px');
  const headerBorderStyle = headerSettings?.borderStyle || 'none';
  const headerBorderWidth = (() => {
    const raw = headerSettings?.borderWidth as unknown;
    if (raw && typeof raw === 'object') {
      const o = raw as Record<string, unknown>;
      if (typeof o.top === 'string' && typeof o.right === 'string' && typeof o.bottom === 'string' && typeof o.left === 'string') {
        return { top: o.top, right: o.right, bottom: o.bottom, left: o.left };
      }
    }
    const v = resolveValue(headerSettings?.borderWidth as any, globalValues, '0px');
    return { top: v, right: v, bottom: v, left: v };
  })();
  const headerBorderColor = resolveValue(headerSettings?.borderColor, globalValues, 'transparent');

  const parseRadius = (input: string): { topLeft: string; topRight: string; bottomRight: string; bottomLeft: string } => {
    const raw = (input || '').trim();
    const tokens = raw.split(/\s+/).filter(Boolean);
    if (tokens.length === 0) return { topLeft: '0px', topRight: '0px', bottomRight: '0px', bottomLeft: '0px' };
    if (tokens.length === 1) return { topLeft: tokens[0], topRight: tokens[0], bottomRight: tokens[0], bottomLeft: tokens[0] };
    if (tokens.length === 2) return { topLeft: tokens[0], topRight: tokens[1], bottomRight: tokens[0], bottomLeft: tokens[1] };
    if (tokens.length === 3) return { topLeft: tokens[0], topRight: tokens[1], bottomRight: tokens[2], bottomLeft: tokens[1] };
    return { topLeft: tokens[0], topRight: tokens[1], bottomRight: tokens[2], bottomLeft: tokens[3] };
  };
  const headerCorners = parseRadius(headerBorderRadius);
  
  // Resolve typography and clamp to header limits
  const rawTypography = resolveTypography(
    headerSettings?.typography as Record<string, import('@/utils/resolveAppearance').FieldValue | undefined> | undefined,
    globalValues,
    {
      fontFamily: globalValues?.typography?.fontFamily || 'inherit',
      fontSize: '15px',
      fontWeight: '600',
      lineHeight: '1.3',
    }
  );
  
  // Apply header-specific clamping (max 32px font size, etc.)
  const typography = clampTypography(rawTypography, 'header');
  
  // Content comes from bot settings (NOT from style system)
  const title = config.bot_name || 'BoostBot';
  const subtitle = isTyping ? t('Typing...') : t('Online');
  const logoUrl = config.avatar_url;
  
  // Button visibility
  const showCloseButton = headerSettings?.showCloseButton !== false;
  const showMinimizeButton = headerSettings?.showMinimizeButton === true;

  // Avatar wrapper styles (styles only)
  const avatarSize = resolveValue(headerSettings?.avatarSize, globalValues, '40px');
  const avatarBackground = resolveValue(headerSettings?.avatarBackground, globalValues, 'rgba(255,255,255,0.2)');
  const avatarBorderRadius = resolveValue(headerSettings?.avatarBorderRadius, globalValues, '9999px');
  const avatarBorderWidth = (() => {
    const raw = headerSettings?.avatarBorderWidth as unknown;
    if (raw && typeof raw === 'object') {
      const o = raw as Record<string, unknown>;
      if (typeof o.top === 'string' && typeof o.right === 'string' && typeof o.bottom === 'string' && typeof o.left === 'string') {
        return { top: o.top, right: o.right, bottom: o.bottom, left: o.left };
      }
    }
    const v = resolveValue(headerSettings?.avatarBorderWidth as any, globalValues, '2px');
    return { top: v, right: v, bottom: v, left: v };
  })();
  const avatarBorderColor = resolveValue(headerSettings?.avatarBorderColor, globalValues, 'rgba(255,255,255,0.2)');
  const avatarIconColor = resolveValue(headerSettings?.avatarIconColor, globalValues, textColor);
  const avatarIcon = headerSettings?.avatarIcon || 'bot';
  const avatarBorderStyle = headerSettings?.avatarBorderStyle || 'solid';
  const avatarIconSizeRaw = resolveValue(headerSettings?.avatarIconSize, globalValues, '18px');
  const avatarIconSize = Number.parseInt(String(avatarIconSizeRaw), 10) || 18;
  const statusIndicatorSize = resolveValue(headerSettings?.statusIndicatorSize, globalValues, '12px');
  const statusIndicatorBackground = resolveValue(headerSettings?.statusIndicatorBackground, globalValues, '#4ADE80');
  const statusIndicatorBorderWidth = resolveValue(headerSettings?.statusIndicatorBorderWidth, globalValues, '2px');
  const statusIndicatorBorderColor = resolveValue(headerSettings?.statusIndicatorBorderColor, globalValues, '#FFFFFF');

  const AvatarIcon = (() => {
    const raw = String(avatarIcon);
    const legacyMap: Record<string, string> = {
      robot: 'bot',
      chat: 'message-circle',
      message: 'message-circle',
    };
    const normalized = legacyMap[raw] || raw;
    return (HEADER_LUCIDE_ICON_MAP[normalized] || Bot) as LucideIcon;
  })();

  // Subtitle typography (styles only)
  const subtitleTypography = resolveTypography(
    headerSettings?.subtitleTypography as Record<string, import('@/utils/resolveAppearance').FieldValue | undefined> | undefined,
    globalValues,
    {
      fontFamily: typography.fontFamily as string | undefined,
      fontSize: '12px',
      fontWeight: '400',
      lineHeight: '1.2',
    }
  );

  // Header action button styling (styles only)
  const actionButtonMinSize = resolveValue(headerSettings?.actionButtonSize, globalValues, '36px');
  const actionIconSizeRaw = resolveValue(headerSettings?.actionIconSize, globalValues, '18px');
  const actionIconSize = Number.parseInt(String(actionIconSizeRaw), 10) || 18;
  const resetButtonStyle = headerSettings?.resetButtonStyle;
  const closeButtonStyle = headerSettings?.closeButtonStyle;
  const minimizeButtonStyle = headerSettings?.minimizeButtonStyle;
  const cartAppearance = getResolvedCartAppearance(config);
  const showCartButton = config.woocommerce?.active === true && config.woocommerce?.show_cart_button === true;
  const cartCount = getWooCartCount(cart);
  const cartButtonLabel = t(isCartOpen ? 'Close cart' : 'Open cart');

  React.useEffect(() => {
    if (!showCartButton) {
      return;
    }

    cartDebugLog('badge render', {
      count: cartCount,
      items: cart?.items.length ?? 0,
      is_open: isCartOpen,
    });
  }, [cart, isCartOpen, showCartButton]);

  const [isResetHover, setIsResetHover] = React.useState(false);
  const [isCloseHover, setIsCloseHover] = React.useState(false);
  const [isMinimizeHover, setIsMinimizeHover] = React.useState(false);

  const buttonCss = (style: typeof resetButtonStyle | undefined, hovered: boolean) => {
    const bg = resolveValue(style?.backgroundColor, globalValues, 'transparent');
    const fg = resolveValue(style?.textColor, globalValues, textColor);
    const borderType = style?.borderType || 'none';
    const borderColor = resolveValue(style?.borderColor, globalValues, 'transparent');
    const boxShadow = resolveValue(style?.boxShadow, globalValues, 'none');

    const hover = style?.hover;
    const hBg = resolveValue(hover?.backgroundColor, globalValues, bg);
    const hFg = resolveValue(hover?.iconColor || hover?.textColor, globalValues, fg);
    const hBorderColor = resolveValue(hover?.borderColor, globalValues, borderColor);
    const hShadow = resolveValue(hover?.boxShadow, globalValues, boxShadow);

    const bw = style?.borderWidth;
    const br = style?.borderRadius;
    const pad = style?.padding;
    const duration = style?.transitionDuration || '150ms';

    // Theme reset protection: some WP themes apply default button border-radius/padding/border styles.
    // We must always output a valid borderRadius string (even when the preset stores a global FieldValue).
    const borderRadiusCss = (() => {
      if (!br) return '9999px';
      const anyBr = br as any;
      if (typeof anyBr === 'string') return anyBr;
      if (typeof anyBr === 'object') {
        if (typeof anyBr.topLeft === 'string') {
          return `${anyBr.topLeft} ${anyBr.topRight} ${anyBr.bottomRight} ${anyBr.bottomLeft}`;
        }
        if (typeof anyBr.type === 'string') {
          // FieldValue (custom/global)
          return resolveValue(anyBr as any, globalValues, '9999px');
        }
      }
      return '9999px';
    })();

    const css: React.CSSProperties = {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      minWidth: actionButtonMinSize,
      minHeight: actionButtonMinSize,
      backgroundColor: hovered ? hBg : bg,
      color: hovered ? hFg : fg,
      borderStyle: borderType === 'none' ? 'none' : borderType,
      borderColor: hovered ? hBorderColor : borderColor,
      boxShadow: (hovered ? hShadow : boxShadow) === 'none' ? undefined : (hovered ? hShadow : boxShadow),
      transition: `all ${duration} ease`,
      borderWidth: bw ? `${bw.top} ${bw.right} ${bw.bottom} ${bw.left}` : undefined,
      borderRadius: borderRadiusCss,
      padding: pad ? `${pad.top} ${pad.right} ${pad.bottom} ${pad.left}` : undefined,
    };

    return css;
  };

  // Helper to get icon component, size, and colors from ButtonStyleSettings.icon
  // Returns resolved icon colors so they can be applied directly to the icon element
  const getButtonIcon = (style: typeof resetButtonStyle | undefined, fallbackIcon: string, fallbackSize: number, isHovered: boolean) => {
    const iconSettings = style?.icon as { icon?: string; size?: string; color?: any; hoverColor?: any } | undefined;
    const iconName = iconSettings?.icon || fallbackIcon;
    const iconSizeRaw = iconSettings?.size || `${fallbackSize}px`;
    const iconSize = Number.parseInt(String(iconSizeRaw), 10) || fallbackSize;
    const IconComponent = (HEADER_LUCIDE_ICON_MAP[iconName] || HEADER_LUCIDE_ICON_MAP[fallbackIcon] || RotateCcw) as LucideIcon;
    
    // Resolve icon colors - fallback to button textColor if not explicitly set
    // This matches ChatSimulator's renderButtonIcon() behavior
    const buttonTextColor = resolveValue(style?.textColor, globalValues, textColor);
    const buttonHoverTextColor = resolveValue(style?.hover?.iconColor || style?.hover?.textColor, globalValues, buttonTextColor);
    
    const normalColor = iconSettings?.color 
      ? resolveValue(iconSettings.color, globalValues, buttonTextColor)
      : buttonTextColor;
    const hoverColor = iconSettings?.hoverColor 
      ? resolveValue(iconSettings.hoverColor, globalValues, normalColor)
      : buttonHoverTextColor;
    
    const iconColor = isHovered ? hoverColor : normalColor;
    
    return { IconComponent, iconSize, iconColor };
  };
  
  return (
    <div 
      className="bb-header flex items-center justify-between flex-shrink-0 overflow-hidden"
      style={{
        // Keep frontend consistent with ChatSimulator + preset expectation: "background" is a solid header background
        backgroundColor: background,
        color: textColor,
        height,
        padding,
        // Header should only round the top corners to avoid seams with the window body
        borderRadius: `${headerCorners.topLeft} ${headerCorners.topRight} 0 0`,
        borderStyle: headerBorderStyle === 'none' ? 'none' : headerBorderStyle,
        borderTopWidth: headerBorderStyle === 'none' ? undefined : headerBorderWidth.top,
        borderRightWidth: headerBorderStyle === 'none' ? undefined : headerBorderWidth.right,
        borderBottomWidth: headerBorderStyle === 'none' ? undefined : headerBorderWidth.bottom,
        borderLeftWidth: headerBorderStyle === 'none' ? undefined : headerBorderWidth.left,
        borderColor: headerBorderStyle === 'none' ? undefined : headerBorderColor,
        ...typography,
      }}
    >
      {/* Avatar and Info */}
      <div className="flex items-center gap-3 flex-1 min-w-0">
        <div className="relative flex-shrink-0">
          {logoUrl ? (
            <img 
              src={logoUrl}
              alt={title}
              className="bb-header-avatar object-cover"
              style={{
                width: avatarSize,
                height: avatarSize,
                borderRadius: avatarBorderRadius,
                borderTopWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.top,
                borderRightWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.right,
                borderBottomWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.bottom,
                borderLeftWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.left,
                borderStyle: (avatarBorderStyle === 'none' ? 'none' : avatarBorderStyle) as React.CSSProperties['borderStyle'],
                borderColor: avatarBorderColor,
                backgroundColor: avatarBackground,
              }}
            />
          ) : (
            <div
              className="bb-header-avatar flex items-center justify-center"
              style={{
                width: avatarSize,
                height: avatarSize,
                borderRadius: avatarBorderRadius,
                borderTopWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.top,
                borderRightWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.right,
                borderBottomWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.bottom,
                borderLeftWidth: avatarBorderStyle === 'none' ? '0px' : avatarBorderWidth.left,
                borderStyle: (avatarBorderStyle === 'none' ? 'none' : avatarBorderStyle) as React.CSSProperties['borderStyle'],
                borderColor: avatarBorderColor,
                backgroundColor: avatarBackground,
              }}
            >
              <AvatarIcon style={{ width: avatarIconSize, height: avatarIconSize, color: avatarIconColor }} />
            </div>
          )}
          {/* Online indicator */}
          <span
            className="absolute bottom-0 right-0 rounded-full"
            style={{
              width: statusIndicatorSize,
              height: statusIndicatorSize,
              backgroundColor: statusIndicatorBackground,
              borderWidth: statusIndicatorBorderWidth,
              borderColor: statusIndicatorBorderColor,
              borderStyle: 'solid',
              boxSizing: 'border-box',
            }}
          />
        </div>
        
        <div className="flex-1 min-w-0">
          {/* Avoid semantic heading tags (h1-h6) because theme reset.css often overrides line-height/margins */}
          <div
            className="bb-header-title truncate"
            role="heading"
            aria-level={3}
            style={{
              // Ensure theme CSS cannot inject margins/line-height
              margin: 0,
              lineHeight: (typography.lineHeight as string | undefined) || '1.3',
            }}
          >
            {title}
          </div>
          {/* Avoid <p> because theme reset.css often injects margins */}
          <div
            className="bb-header-subtitle truncate"
            style={{
              opacity: 0.8,
              color: textColor,
              margin: 0,
              ...subtitleTypography,
            }}
          >
            {isTyping ? (
              <motion.span 
                className="flex items-center gap-1"
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
              >
                <span>{t('Typing')}</span>
                <TypingDots color={textColor} />
              </motion.span>
            ) : (
              subtitle
            )}
          </div>
        </div>
      </div>
      
      {/* Action buttons */}
      <div className="flex items-center gap-1 flex-shrink-0">
        {showCartButton && (
          <button
            type="button"
            onClick={toggleCart}
            className="relative inline-flex items-center justify-center focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
            aria-label={cartButtonLabel}
            title={cartButtonLabel}
            style={{
              minWidth: cartAppearance.badge.minWidth,
              height: cartAppearance.badge.height,
              borderRadius: cartAppearance.badge.borderRadius,
              background: cartAppearance.badge.background,
              color: cartAppearance.badge.iconColor,
              paddingInline: '10px',
            }}
          >
            <ShoppingCart className="h-4 w-4" />
            {cartCount > 0 && (
              <span
                className="ms-2 inline-flex min-w-5 items-center justify-center rounded-full px-1.5 text-[11px] font-semibold"
                style={{
                  background: cartAppearance.header.countBackground,
                  color: cartAppearance.header.countColor,
                }}
              >
                {cartCount}
              </span>
            )}
          </button>
        )}

        {/* Clear chat - uses dynamic icon from ButtonStyleSettings.icon */}
        {(() => {
          const { IconComponent: ResetIcon, iconSize: resetIconSize, iconColor: resetIconColor } = getButtonIcon(resetButtonStyle, 'rotate-ccw', actionIconSize, isResetHover);
          return (
            <button
              onClick={() => {
                if (window.confirm(t('Clear the conversation?'))) {
                  clearChat();
                }
              }}
              className="bb-header-reset focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
              style={buttonCss(resetButtonStyle, isResetHover)}
              onMouseEnter={() => setIsResetHover(true)}
              onMouseLeave={() => setIsResetHover(false)}
              aria-label={t('Clear chat')}
              title={t('Clear chat')}
            >
              <ResetIcon style={{ width: resetIconSize, height: resetIconSize, color: resetIconColor }} />
            </button>
          );
        })()}
        
        {/* Minimize button */}
        {showMinimizeButton && (
          (() => {
            const { IconComponent: MinimizeIcon, iconSize: minimizeIconSize, iconColor: minimizeIconColor } = getButtonIcon(minimizeButtonStyle, 'minus', actionIconSize, isMinimizeHover);
            return (
              <button
                onClick={toggleChat}
                className="bb-header-minimize focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
                style={buttonCss(minimizeButtonStyle, isMinimizeHover)}
                onMouseEnter={() => setIsMinimizeHover(true)}
                onMouseLeave={() => setIsMinimizeHover(false)}
                aria-label={t('Minimize')}
                title={t('Minimize')}
              >
                <MinimizeIcon style={{ width: minimizeIconSize, height: minimizeIconSize, color: minimizeIconColor }} />
              </button>
            );
          })()
        )}
        
        {/* Close button - uses dynamic icon from ButtonStyleSettings.icon */}
        {showCloseButton && (() => {
          const { IconComponent: CloseIcon, iconSize: closeIconSize, iconColor: closeIconColor } = getButtonIcon(closeButtonStyle, 'x', actionIconSize, isCloseHover);
          return (
            <button
              onClick={toggleChat}
              className="bb-header-close focus:outline-none focus-visible:ring-2 focus-visible:ring-white"
              style={buttonCss(closeButtonStyle, isCloseHover)}
              onMouseEnter={() => setIsCloseHover(true)}
              onMouseLeave={() => setIsCloseHover(false)}
              aria-label={t('Close chat')}
              title={t('Close')}
            >
              <CloseIcon style={{ width: closeIconSize, height: closeIconSize, color: closeIconColor }} />
            </button>
          );
        })()}
      </div>
    </div>
  );
}

/**
 * Typing dots animation
 */
function TypingDots({ color }: { color: string }) {
  return (
    <span className="inline-flex gap-0.5">
      {[0, 1, 2].map((i) => (
        <motion.span
          key={i}
          className="w-1 h-1 rounded-full"
          style={{ backgroundColor: color, opacity: 0.8 }}
          animate={{ opacity: [0.4, 1, 0.4] }}
          transition={{
            duration: 0.8,
            repeat: Infinity,
            delay: i * 0.2,
          }}
        />
      ))}
    </span>
  );
}
