/*
 * Copyright (C) 2021 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import I18n from 'i18n!discussion_posts'
import PropTypes from 'prop-types'
import React, {useMemo} from 'react'

import {Menu} from '@instructure/ui-menu'
import {
  IconMoreLine,
  IconNextUnreadLine,
  IconDiscussionLine,
  IconEditLine,
  IconTrashLine,
  IconSpeedGraderLine,
  IconMarkAsReadSolid,
  IconMarkAsReadLine,
  IconWarningBorderlessSolid
} from '@instructure/ui-icons'

import {IconButton} from '@instructure/ui-buttons'
import {Text} from '@instructure/ui-text'
import {Flex} from '@instructure/ui-flex'

// Reason: <Menu> in v6 of InstUI requires a ref to bind too or errors
// are produced by the menu causing the page to scroll all over the place
export const ThreadActions = props => {
  const menuItems = useMemo(() => {
    return getMenuConfigs({
      onMarkAllAsRead: props.onMarkAllAsRead,
      onMarkAllAsUnread: props.onMarkAllAsUnread,
      isUnread: props.isUnread,
      onToggleUnread: props.onToggleUnread,
      goToTopic: props.goToTopic,
      goToParent: props.goToParent,
      onEdit: props.onEdit,
      onDelete: props.onDelete,
      onOpenInSpeedGrader: props.onOpenInSpeedGrader,
      onMarkThreadAsRead: props.onMarkThreadAsRead,
      onReport: props.onReport,
      isReported: props.isReported
    }).map(config => renderMenuItem({...config}, props.id))
  }, [props])

  return (
    <Flex justifyItems="end">
      <Flex.Item>
        {!props.isSearch && (
          <Menu
            placement="bottom"
            key={`threadActionMenu-${props.id}`}
            trigger={
              <IconButton
                size="small"
                screenReaderLabel={I18n.t('Manage Discussion')}
                renderIcon={IconMoreLine}
                withBackground={false}
                withBorder={false}
                data-testid="thread-actions-menu"
              />
            }
          >
            {menuItems}
          </Menu>
        )}
      </Flex.Item>
    </Flex>
  )
}

const getMenuConfigs = props => {
  const options = []
  if (props.onMarkAllAsRead) {
    options.push({
      key: 'markAllAsRead',
      icon: <IconNextUnreadLine />,
      label: I18n.t('Mark All as Read'),
      selectionCallback: props.onMarkAllAsRead
    })
  }
  if (props.onMarkAllAsUnread) {
    options.push({
      key: 'markAllAsUnRead',
      icon: <IconNextUnreadLine />,
      label: I18n.t('Mark All as Unread'),
      selectionCallback: props.onMarkAllAsUnread
    })
  }
  if (props.isUnread) {
    options.push({
      key: 'markAsRead',
      icon: <IconNextUnreadLine />,
      label: I18n.t('Mark as Read'),
      selectionCallback: props.onToggleUnread
    })
  } else {
    options.push({
      key: 'markAsUnread',
      icon: <IconNextUnreadLine />,
      label: I18n.t('Mark as Unread'),
      selectionCallback: props.onToggleUnread
    })
  }
  if (props.onMarkThreadAsRead) {
    options.push({
      key: 'markThreadAsRead',
      icon: <IconMarkAsReadLine />,
      label: I18n.t('Mark Thread as Read'),
      selectionCallback: () => {
        props.onMarkThreadAsRead(true)
      }
    })
  }
  if (props.onMarkThreadAsRead) {
    options.push({
      key: 'markThreadAsUnRead',
      icon: <IconMarkAsReadSolid />,
      label: I18n.t('Mark Thread as Unread'),
      selectionCallback: () => {
        props.onMarkThreadAsRead(false)
      }
    })
  }
  if (props.goToTopic) {
    options.push({
      key: 'toTopic',
      icon: <IconDiscussionLine />,
      label: I18n.t('Go To Topic'),
      selectionCallback: props.goToTopic
    })
  }
  if (props.goToParent) {
    options.push({
      key: 'toParent',
      icon: <IconDiscussionLine />,
      label: I18n.t('Go To Parent'),
      selectionCallback: props.goToParent
    })
  }
  if (props.onEdit) {
    options.push({
      key: 'edit',
      icon: <IconEditLine />,
      label: I18n.t('Edit'),
      selectionCallback: props.onEdit
    })
  }
  if (props.onDelete) {
    options.push({
      key: 'delete',
      icon: <IconTrashLine />,
      label: I18n.t('Delete'),
      selectionCallback: props.onDelete
    })
  }
  if (props.onOpenInSpeedGrader) {
    options.push({
      key: 'inSpeedGrader',
      icon: <IconSpeedGraderLine />,
      label: I18n.t('Open in SpeedGrader'),
      selectionCallback: props.onOpenInSpeedGrader
    })
  }
  if (props.onReport) {
    options.push({
      separator: true
    })
    options.push({
      key: 'report',
      icon: <IconWarningBorderlessSolid />,
      label: props.isReported ? I18n.t('Reported') : I18n.t('Report'),
      selectionCallback: props.onReport,
      disabled: props.isReported,
      color: 'warning'
    })
  }
  return options
}

const renderMenuItem = (
  {selectionCallback, icon, label, key, separator = false, disabled = false, color = 'primary'},
  id
) => {
  return separator ? (
    <Menu.Separator />
  ) : (
    <Menu.Item
      key={`${key}-${id}`}
      onSelect={() => {
        selectionCallback(key)
      }}
      data-testid={key}
      disabled={disabled}
    >
      <Text color={color}>
        <Flex>
          <Flex.Item>{icon}</Flex.Item>
          <Flex.Item padding="0 0 0 xx-small">
            <Text>{label}</Text>
          </Flex.Item>
        </Flex>
      </Text>
    </Menu.Item>
  )
}

ThreadActions.propTypes = {
  id: PropTypes.string.isRequired,
  onMarkAllAsUnread: PropTypes.func,
  onMarkAllAsRead: PropTypes.func,
  onMarkThreadAsRead: PropTypes.func,
  onToggleUnread: PropTypes.func.isRequired,
  isUnread: PropTypes.bool,
  goToTopic: PropTypes.func,
  goToParent: PropTypes.func,
  onEdit: PropTypes.func,
  onDelete: PropTypes.func,
  onOpenInSpeedGrader: PropTypes.func,
  onReport: PropTypes.func,
  isReported: PropTypes.bool,
  isSearch: PropTypes.bool
}

ThreadActions.defaultProps = {
  isUnread: false,
  isSearch: false,
  isReported: false
}

export default ThreadActions

@@ -5022,24 +5022,48 @@
 ions.push(%7B%0A
+      key: 'separator',%0A
       separa
@@ -5539,16 +5539,26 @@
 eparator
+ key=%7Bkey%7D
  /%3E%0A  ) 

Fix unique key prop console error in ThreadActions