import React, { CSSProperties } from 'react';
import { useNode, UserComponent } from '@craftjs/core';
import { cssPropsToString } from '../../utils/style-helpers';
import { escapeAttr, safeUrl, cssValue } from '../../utils/escape';

interface SocialLink {
  platform: string;
  url: string;
}

interface SocialLinksProps {
  links?: SocialLink[];
  iconSize?: string;
  iconColor?: string;
  iconBgColor?: string;
  iconShape?: 'none' | 'circle' | 'square' | 'rounded';
  gap?: string;
  alignment?: 'left' | 'center' | 'right';
  style?: CSSProperties;
  animation?: string;
  animationDelay?: string;
  hideOnDesktop?: boolean;
  hideOnTablet?: boolean;
  hideOnMobile?: boolean;
}

const platformIcons: Record<string, string> = {
  facebook: 'fa-facebook',
  twitter: 'fa-twitter',
  instagram: 'fa-instagram',
  linkedin: 'fa-linkedin',
  youtube: 'fa-youtube',
  github: 'fa-github',
  tiktok: 'fa-music',
  pinterest: 'fa-pinterest',
  snapchat: 'fa-snapchat',
  whatsapp: 'fa-whatsapp',
  spotify: 'fa-spotify',
  twitch: 'fa-twitch',
};

const platformLabels: Record<string, string> = {
  facebook: 'Facebook',
  twitter: 'Twitter / X',
  instagram: 'Instagram',
  linkedin: 'LinkedIn',
  youtube: 'YouTube',
  github: 'GitHub',
  tiktok: 'TikTok',
  pinterest: 'Pinterest',
  snapchat: 'Snapchat',
  whatsapp: 'WhatsApp',
  spotify: 'Spotify',
  twitch: 'Twitch',
};

const defaultLinks: SocialLink[] = [
  { platform: 'facebook', url: '#' },
  { platform: 'twitter', url: '#' },
  { platform: 'instagram', url: '#' },
  { platform: 'linkedin', url: '#' },
];

const getShapeStyle = (shape: string, size: string): CSSProperties => {
  if (shape === 'none') return {};
  const numSize = parseInt(size) || 24;
  const boxSize = `${numSize + 16}px`;
  const base: CSSProperties = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: boxSize,
    height: boxSize,
  };
  if (shape === 'circle') return { ...base, borderRadius: '50%' };
  if (shape === 'square') return { ...base, borderRadius: '0' };
  if (shape === 'rounded') return { ...base, borderRadius: '6px' };
  return base;
};

const alignMap: Record<string, string> = {
  left: 'flex-start',
  center: 'center',
  right: 'flex-end',
};

export const SocialLinks: UserComponent<SocialLinksProps> = ({
  links = defaultLinks,
  iconSize = '20px',
  iconColor = '#ffffff',
  iconBgColor = '#374151',
  iconShape = 'circle',
  gap = '10px',
  alignment = 'center',
  style = {},
}) => {
  const {
    connectors: { connect, drag },
    selected,
  } = useNode((node) => ({
    selected: node.events.selected,
  }));

  return (
    <div
      ref={(ref: HTMLDivElement | null): void => { if (ref) connect(drag(ref)); }}
      style={{
        display: 'flex',
        flexWrap: 'wrap',
        gap,
        justifyContent: alignMap[alignment] || 'center',
        alignItems: 'center',
        outline: selected ? '2px solid #3b82f6' : 'none',
        ...style,
      }}
    >
      {links.map((link, i) => {
        const iconClass = platformIcons[link.platform] || 'fa-link';
        const shapeStyle = getShapeStyle(iconShape, iconSize);
        const hasBg = iconShape !== 'none';

        return (
          <a
            key={i}
            href={link.url || '#'}
            target="_blank"
            rel="noopener noreferrer"
            onClick={(e) => e.preventDefault()}
            title={platformLabels[link.platform] || link.platform}
            style={{
              textDecoration: 'none',
              color: iconColor,
              backgroundColor: hasBg ? iconBgColor : 'transparent',
              transition: 'opacity 0.2s',
              ...shapeStyle,
            }}
          >
            <i className={`fa ${iconClass}`} style={{ fontSize: iconSize }} />
          </a>
        );
      })}
    </div>
  );
};

/* ---------- Craft config ---------- */

SocialLinks.craft = {
  displayName: 'Social Links',
  props: {
    links: defaultLinks,
    iconSize: '20px',
    iconColor: '#ffffff',
    iconBgColor: '#374151',
    iconShape: 'circle',
    gap: '10px',
    alignment: 'center',
    style: {},
    animation: '',
    animationDelay: '',
    hideOnDesktop: false,
    hideOnTablet: false,
    hideOnMobile: false,
  },
  rules: {
    canDrag: () => true,
    canMoveIn: () => false,
    canMoveOut: () => true,
  },
};

/* ---------- HTML export ---------- */

(SocialLinks as any).toHtml = (props: SocialLinksProps, _childrenHtml: string) => {
  const links = props.links || defaultLinks;
  // Sanitized -- raw string-interpolation sinks in aStyle/getShapeStr below.
  const iconSize = cssValue(props.iconSize) || '20px';
  const iconColor = cssValue(props.iconColor) || '#ffffff';
  const iconBgColor = cssValue(props.iconBgColor) || '#374151';
  const iconShape = props.iconShape || 'circle';
  const gap = props.gap || '10px';
  const alignment = props.alignment || 'center';
  const hasBg = iconShape !== 'none';

  const wrapperStyle = cssPropsToString({
    display: 'flex',
    flexWrap: 'wrap',
    gap,
    justifyContent: alignMap[alignment] || 'center',
    alignItems: 'center',
    ...props.style,
  });

  const numSize = parseInt(iconSize) || 20;
  const boxSize = `${numSize + 16}px`;

  const getShapeStr = (): string => {
    const parts: string[] = [
      `display:inline-flex`,
      `align-items:center`,
      `justify-content:center`,
      `width:${boxSize}`,
      `height:${boxSize}`,
    ];
    if (iconShape === 'circle') parts.push('border-radius:50%');
    else if (iconShape === 'square') parts.push('border-radius:0');
    else if (iconShape === 'rounded') parts.push('border-radius:6px');
    return parts.join(';');
  };

  const linksHtml = links.map((link) => {
    const iconClass = platformIcons[link.platform] || 'fa-link';
    const title = platformLabels[link.platform] || link.platform;
    let aStyle = `text-decoration:none;color:${iconColor};background-color:${hasBg ? iconBgColor : 'transparent'}`;
    if (hasBg) {
      aStyle += `;${getShapeStr()}`;
    }
    // The link's only content is the icon glyph, so the glyph itself is
    // aria-hidden and the accessible name lives on the link (aria-label,
    // mirroring the existing `title` tooltip since title support in
    // screen readers is inconsistent).
    return `<a href="${escapeAttr(safeUrl(link.url || '#'))}" target="_blank" rel="noopener noreferrer" title="${escapeAttr(title)}" aria-label="${escapeAttr(title)}" style="${aStyle}"><i class="fa ${escapeAttr(iconClass)}" style="font-size:${iconSize}" aria-hidden="true"></i></a>`;
  }).join('\n  ');

  return {
    html: `<div${wrapperStyle ? ` style="${wrapperStyle}"` : ''}>
  ${linksHtml}
</div>`,
  };
};
