import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { InfoOutlined, LockOutlined, PeopleOutlined, PublicRounded } from '@mui/icons-material';

import { ACCESS_LEVEL_ENUM, ACCESS_USER_ROLE } from './constants';

import { getUserIdSelector } from '@/modules/@common/user/redux/selectors';

import {
  Button,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Stack,
  Tooltip,
  Typography,
  UserAvatar,
} from '@/mui/components';

import styles from './index.module.scss';

const getLevelIconComponent = (level) => {
  const map = {
    [ACCESS_LEVEL_ENUM.site]: PeopleOutlined,
    [ACCESS_LEVEL_ENUM.private]: LockOutlined,
    [ACCESS_LEVEL_ENUM.public]: PublicRounded,
  };

  return map[level];
};

const getOwner = (users, userId) => {
  if (!users?.length) return {};

  const owner = users.find((user) => user.role === ACCESS_USER_ROLE.owner);
  const isOwnerCurrentUser = +(owner?.id ?? 0) === userId;
  const displayMaxOwnerName = owner?.name?.slice(0, 17) ?? '';
  const MAX_LENGTH_OWNER_NAME = 20;

  return {
    ownerName: owner?.name,
    isOwnerCurrentUser,
    MAX_LENGTH_OWNER_NAME,
    displayMaxOwnerName,
  };
};

const getSharedWithUsers = (users) => {
  if (!users?.length) return {};

  const sharedWith = users.filter((user) => user.role !== ACCESS_USER_ROLE.owner);
  const displayUsers = sharedWith.slice(0, 4);
  const otherUsers = sharedWith.slice(4);

  return {
    displayUsers,
    otherUsers,
  };
};

const getSites = (sites) => {
  if (!sites?.length) return {};

  const displaySite = sites[0];
  const otherSites = sites.slice(1);

  return {
    displaySite,
    otherSites,
  };
};

const formatOwnerName = (ownerName, maxLengthOwnerName, displayMaxOwnerName) =>
  ownerName.length >= maxLengthOwnerName ? `${displayMaxOwnerName}...` : ownerName;

const getTooltipText = (access, isOwnerCurrentUser) => {
  const tooltips = [
    {
      text: 'Your video is set to private. Only you and the people you shared the video with will be able to view it',
      isActive: access === ACCESS_LEVEL_ENUM.private && isOwnerCurrentUser,
    },
    {
      text: 'This private video was shared with you',
      isActive: access === ACCESS_LEVEL_ENUM.private && !isOwnerCurrentUser,
    },
    {
      text: 'This syndication video is available to anyone with an AnyClip account',
      isActive: access === ACCESS_LEVEL_ENUM.public,
    },
    {
      text: 'This video is available to anyone registered to this hub and to users it was shared with',
      isActive: access === ACCESS_LEVEL_ENUM.site,
    },
  ];

  const tooltip = tooltips.find((item) => item.isActive);

  return tooltip?.text || '';
};

function AccessControlView({ access = {}, ...props }) {
  const LevelIconComponent = getLevelIconComponent(access?.level);

  const userId = useSelector(getUserIdSelector);

  const { ownerName, isOwnerCurrentUser, MAX_LENGTH_OWNER_NAME, displayMaxOwnerName } = getOwner(access?.users, userId);

  const { displayUsers, otherUsers } = getSharedWithUsers(access?.users);
  const { displaySite, otherSites } = getSites(access?.sites);

  const MAX_LENGTH_LIST = 15;
  const MAX_LENGTH_USER_NAME = 30;

  const shouldShowOwner =
    ownerName && [ACCESS_LEVEL_ENUM.private, ACCESS_LEVEL_ENUM.site, ACCESS_LEVEL_ENUM.public].includes(access.level);
  const shouldShowSharedWith =
    access.level === ACCESS_LEVEL_ENUM.private && isOwnerCurrentUser && !!displayUsers?.length;
  const shouldShowSite = access.level === ACCESS_LEVEL_ENUM.site && !!access.sites?.length;

  const tooltipText = getTooltipText(access.level, isOwnerCurrentUser);

  return (
    <Stack direction="row" spacing={2} alignItems="center" className={styles.Wrapper}>
      <Typography variant="caption" color="text.secondary" className={styles.NoLineHeight}>
        <Stack direction="row" spacing={1} alignItems="center">
          {LevelIconComponent && <LevelIconComponent fontSize="xSmall" />}

          {access.level === ACCESS_LEVEL_ENUM.public && !shouldShowOwner && <span>Syndication</span>}

          {shouldShowOwner && (
            <Typography variant="caption" noWrap title={ownerName}>
              {`Owner ${formatOwnerName(ownerName, MAX_LENGTH_OWNER_NAME, displayMaxOwnerName)}`}
              {isOwnerCurrentUser ? ' (you)' : ''}
            </Typography>
          )}
        </Stack>
      </Typography>

      {shouldShowSite && (
        <>
          <Chip size="xSmall" color="neutral" variant="filled" shape="circular" label={displaySite.name} />

          {!!otherSites.length && (
            <Tooltip
              interactive="true"
              placement="top"
              title={
                <div>
                  {otherSites.length >= MAX_LENGTH_LIST && (
                    <Button
                      fullWidth
                      variant="outlined"
                      size="small"
                      color="primary"
                      shape="rounded"
                      label="Open full list"
                      onClick={() => props.setShowListOfSitePopup(true)}
                    >
                      Open full list
                    </Button>
                  )}
                  {otherSites.slice(0, MAX_LENGTH_LIST).map((site) => (
                    <Typography key={site.id} variant="subtitle2" color="text.primary">
                      {site.name}
                    </Typography>
                  ))}
                  {otherSites.length >= MAX_LENGTH_LIST && <div>...</div>}
                </div>
              }
            >
              <Typography variant="captionSmall" color="text.primary">
                {`+${otherSites.length}`}
              </Typography>
            </Tooltip>
          )}
        </>
      )}

      <Tooltip placement="top" arrow title={<div>{tooltipText}</div>}>
        <InfoOutlined fontSize="info.main" />
      </Tooltip>

      {shouldShowSharedWith && (
        <>
          <Typography variant="caption" color="text.secondary">
            | Shared with:
          </Typography>

          {displayUsers.map((sharedWith) => (
            <Tooltip key={sharedWith.id} placement="top" title={sharedWith.name}>
              <Stack direction="row" spacing={1} alignItems="center">
                <UserAvatar
                  size="xSmall"
                  id={sharedWith.id}
                  firstName={sharedWith.firstName}
                  lastName={sharedWith.lastName}
                />
              </Stack>
            </Tooltip>
          ))}

          {!!otherUsers.length && (
            <Tooltip
              interactive="true"
              placement="top"
              title={
                <div>
                  {otherUsers.length >= MAX_LENGTH_LIST && (
                    <Button
                      fullWidth
                      variant="outlined"
                      size="small"
                      color="primary"
                      shape="rounded"
                      label="Open full list"
                      onClick={() => props.setShowListOfUserPopup(true)}
                    >
                      Open full list
                    </Button>
                  )}
                  {otherUsers.slice(0, MAX_LENGTH_LIST).map((user) => (
                    <Typography key={user.id} variant="subtitle2" color="text.primary">
                      {user.name && user.name.length > MAX_LENGTH_USER_NAME
                        ? user.name.slice(0, MAX_LENGTH_USER_NAME).concat('...')
                        : user.name}
                    </Typography>
                  ))}
                  {otherUsers.length >= MAX_LENGTH_LIST && <div>...</div>}
                </div>
              }
            >
              <Typography variant="captionSmall" color="text.primary">
                {`+${otherUsers.length}`}
              </Typography>
            </Tooltip>
          )}
        </>
      )}

      {props.showListOfSitePopup && (
        <Dialog open onClose={() => props.setShowListOfSitePopup(false)} maxWidth="lg">
          <DialogTitle onClose={() => props.setShowListOfSitePopup(false)}>List of Hubs</DialogTitle>
          <DialogContent>
            {otherSites.map((site) => (
              <Typography key={site.id} variant="subtitle2" color="text.primary">
                {site.name}
              </Typography>
            ))}
          </DialogContent>
          <DialogActions>
            <Button
              size="small"
              variant="contained"
              color="primary"
              onClick={() => props.setShowListOfSitePopup(false)}
            >
              Close
            </Button>
          </DialogActions>
        </Dialog>
      )}

      {props.showListOfUserPopup && (
        <Dialog open onClose={() => props.setShowListOfUserPopup(false)} maxWidth="lg">
          <DialogTitle onClose={() => props.setShowListOfUserPopup(false)}>List of Users</DialogTitle>
          <DialogContent>
            {otherUsers.map((user) => (
              <Typography key={user.id} variant="subtitle2" color="text.primary">
                {user.name}
              </Typography>
            ))}
          </DialogContent>
          <DialogActions>
            <Button
              size="small"
              variant="contained"
              color="primary"
              onClick={() => props.setShowListOfUserPopup(false)}
            >
              Close
            </Button>
          </DialogActions>
        </Dialog>
      )}
    </Stack>
  );
}

AccessControlView.propTypes = {
  access: PropTypes.shape({
    level: PropTypes.oneOf([ACCESS_LEVEL_ENUM.public, ACCESS_LEVEL_ENUM.private, ACCESS_LEVEL_ENUM.site]),
    users: PropTypes.arrayOf(
      PropTypes.shape({
        id: PropTypes.string.isRequired,
        role: PropTypes.oneOf([ACCESS_USER_ROLE.owner, ACCESS_USER_ROLE.read, ACCESS_USER_ROLE.readWrite]),
      }),
    ),
    sites: PropTypes.arrayOf(
      PropTypes.shape({
        id: PropTypes.string.isRequired,
        name: PropTypes.string.isRequired,
      }),
    ),
  }),
  showListOfSitePopup: PropTypes.bool.isRequired,
  setShowListOfSitePopup: PropTypes.func.isRequired,
  showListOfUserPopup: PropTypes.bool.isRequired,
  setShowListOfUserPopup: PropTypes.func.isRequired,
};

export default AccessControlView;
