import * as React from 'react';
import { FC, CSSProperties, useContext, MouseEvent, KeyboardEvent } from 'react';
import { style } from 'typestyle';
import { StoreContext } from '../../services/store';
import InstagramIcon from '../Icons/Instagram';
import TikTokIcon from '../Icons/TikTok';
import { onKeyDownEventCallback } from '../../utils/onKeyDown';

interface UserNameProps {
  color: string;
  padding?: string;
  hideUsername?: boolean;
  backgroundColor?: string;
  username?: string;
  source?: string;
  postUrl?: string;
}

const UserName: FC<UserNameProps> = ({
  color,
  padding,
  hideUsername: propsHideUsername,
  backgroundColor = 'rgba(255, 255, 255, 0.1)',
  username: propsUsername,
  source: propsSource,
  postUrl: propsPostUrl,
}) => {
  const context = useContext(StoreContext);
  const { 
    post, 
    data: { 
      settings: { username_link, type, display_name },
      id 
    },
    triggerEvent,
    config,
    isMobile
  } = context;
  
  // Use context values if available, otherwise fall back to props
  const username = post?.username || propsUsername;
  const source = post?.source || propsSource;
  const postUrl = post?.post || propsPostUrl;
  const hideUsername = propsHideUsername;

  const shouldHideComponent = isMobile && 
                             (type === 'mosaic' || type === 'wall') && 
                             display_name && 
                             !username_link;
  if (shouldHideComponent) {
    return null;
  }

  const icon = {
    instagram: <InstagramIcon color={color} />,
    tiktok: <TikTokIcon color={color} />,
  }[source as 'instagram' | 'tiktok'];

  const onUsernameClick = (e: MouseEvent<HTMLAnchorElement> | KeyboardEvent<HTMLAnchorElement>) => {
    triggerEvent(
      'socialProfileOpened',
      {
        originalEvent: e.nativeEvent as Event,
        post: post!,
      },
      id,
    );
  };

  const userUrl = (): string | undefined => {
    if (!username) {
      return postUrl;
    }

    if (source === 'instagram' && postUrl) {
      return postUrl.slice(0, postUrl.indexOf('p/')) + username;
    }

    // TODO update this part (was Twitter before)
    if (source === 'tiktok' && postUrl) {
      return postUrl.slice(0, postUrl.indexOf('status/'));
    }
    return undefined;
  };

  const iconStyles = hideUsername ? iconStyle : iconWithUsernameStyle;
  
  const content = (
    <>
      <span style={iconStyles}>{icon}</span>
      {username && !hideUsername ? (
        <b className={textClass}>{username}</b>
      ) : null}
    </>
  );

  return (
    <div
      className={`${config.classPrefix}-postviewer-details-username 
      ${pillClass(color, backgroundColor, padding)}`}
    >
      {username_link ? (
        <a
          className={linkClass(color, true)}
          href={userUrl()}
          target='_blank'
          onClick={onUsernameClick}
          onKeyDown={(e) => onKeyDownEventCallback(e, onUsernameClick)}
          tabIndex={0}
          role='link'
          aria-label={`go to ${username ? username : 'social'}'s profile on ${source}`}
        >
          {content}
        </a>
      ) : (
        <div className={linkClass(color, false)}>
          {content}
        </div>
      )}
    </div>
  );
};

const pillClass = (color: string, backgroundColor: string, padding?: string) =>
  style({
    backgroundColor,
    backdropFilter: 'blur(3px)',
    '-webkit-backdrop-filter': 'blur(3px)',
    padding: padding || '6px 12px',
    borderRadius: '99px',
    color,
  });

const textClass = style({
  fontFamily: "'Fustat', sans-serif",
  fontWeight: 300,
  marginRight: 4,
  all: 'revert',
  fontSize: 12,
});

const iconStyle: CSSProperties = {
  verticalAlign: 'middle',
};

const iconWithUsernameStyle: CSSProperties = {
  verticalAlign: 'middle',
  marginRight: 5,
};

const linkClass = (color: string, isClickable: boolean) => style({
  textDecoration: 'none',
  color: color,
  cursor: isClickable ? 'pointer' : 'default',
  display: 'flex',
  alignItems: 'center',
  $nest: isClickable ? {
    '&:hover': {
      color: 'gray',
    },
  } : {},
});

export default UserName;
