import {
  DotsThreeIcon,
  FlagIcon,
  ProhibitInsetIcon,
  SignOutIcon,
  SpinnerGapIcon,
} from '@phosphor-icons/react'
import classNames from 'classnames'
import React, { useCallback, useEffect, useId, useRef, useState } from 'react'
import type { Channel as ChannelType, ChannelMemberResponse } from 'stream-chat'

import { useChannelModerationActions } from '../../hooks/useChannelModerationActions'
import ActionButton from '../ActionButton'

export interface ChannelActionsMenuProps {
  channel: ChannelType
  participant: ChannelMemberResponse | undefined
  showDeleteConversation?: boolean
  /**
   * Show the Block/Unblock action. Defaults to true.
   * Set false to hide it (e.g. the Linktree official channel).
   */
  showBlockParticipant?: boolean
  /**
   * Show the Report action. Defaults to true.
   * Set false to hide it (e.g. the Linktree official channel).
   */
  showReportParticipant?: boolean
  onLeaveConversation?: (channel: ChannelType) => void
  onBlockParticipant?: (participantId?: string) => void
  onDeleteConversationClick?: () => void
  onBlockParticipantClick?: () => void
  onReportParticipantClick?: () => void
  customChannelActions?: React.ReactNode
  /** Classes applied to the trigger ("...") button so it matches the header. */
  triggerClassName?: string
}

/**
 * Conversation overflow ("...") menu rendered as an anchored popover.
 *
 * Replaces the slide-in sidebar dialog for moderation actions: the trigger
 * opens a small popover that lists the available options (delete, block,
 * report) inline with their icons.
 */
export const ChannelActionsMenu: React.FC<ChannelActionsMenuProps> = ({
  channel,
  participant,
  showDeleteConversation = true,
  showBlockParticipant = true,
  showReportParticipant = true,
  onLeaveConversation,
  onBlockParticipant,
  onDeleteConversationClick,
  onBlockParticipantClick,
  onReportParticipantClick,
  customChannelActions,
  triggerClassName,
}) => {
  const [isOpen, setIsOpen] = useState(false)
  const containerRef = useRef<HTMLDivElement>(null)
  const menuId = useId()

  const close = useCallback(() => setIsOpen(false), [])

  const {
    isParticipantBlocked,
    isCheckingBlockedStatus,
    isLeaving,
    isUpdatingBlockStatus,
    handleLeaveConversation,
    handleBlockUser,
    handleUnblockUser,
    handleReportUser,
  } = useChannelModerationActions({
    channel,
    participant,
    showBlockParticipant,
    enabled: isOpen,
    onLeaveConversation,
    onBlockParticipant,
    onDeleteConversationClick,
    onBlockParticipantClick,
    onReportParticipantClick,
    onActionComplete: close,
    logLabel: 'ChannelActionsMenu',
  })

  // Close the popover on outside click or Escape.
  useEffect(() => {
    if (!isOpen) return

    const handlePointerDown = (event: MouseEvent) => {
      if (
        containerRef.current &&
        !containerRef.current.contains(event.target as Node)
      ) {
        setIsOpen(false)
      }
    }

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setIsOpen(false)
      }
    }

    document.addEventListener('mousedown', handlePointerDown)
    document.addEventListener('keydown', handleKeyDown)

    return () => {
      document.removeEventListener('mousedown', handlePointerDown)
      document.removeEventListener('keydown', handleKeyDown)
    }
  }, [isOpen])

  if (!participant) return null

  const hasActions =
    showDeleteConversation ||
    showBlockParticipant ||
    showReportParticipant ||
    Boolean(customChannelActions)

  if (!hasActions) return null

  return (
    <div ref={containerRef} className="relative">
      <button
        className={triggerClassName}
        type="button"
        aria-haspopup="true"
        aria-expanded={isOpen}
        aria-controls={isOpen ? menuId : undefined}
        onClick={() => setIsOpen((open) => !open)}
      >
        <DotsThreeIcon className="size-5 text-black/90" />
        <span className="sr-only">More options</span>
      </button>

      {isOpen && (
        <div
          id={menuId}
          aria-label="Conversation options"
          className={classNames(
            'absolute right-0 top-full z-50 mt-2 w-56 overflow-hidden',
            'rounded-lg border border-sand bg-white p-1 shadow-max-elevation-light'
          )}
        >
          <ul className="flex flex-col gap-1">
            {showDeleteConversation && (
              <li>
                <ActionButton
                  onClick={handleLeaveConversation}
                  disabled={isLeaving}
                  aria-busy={isLeaving}
                >
                  {isLeaving ? (
                    <SpinnerGapIcon className="h-5 w-5 animate-spin" />
                  ) : (
                    <SignOutIcon className="h-5 w-5" />
                  )}
                  <span>Delete Conversation</span>
                </ActionButton>
              </li>
            )}
            {showBlockParticipant && (
              <li>
                {isCheckingBlockedStatus ? (
                  // Block status not yet resolved — show a disabled placeholder
                  // so a premature click can't act on a stale block state.
                  <ActionButton disabled aria-busy>
                    <SpinnerGapIcon className="h-5 w-5 animate-spin" />
                    <span>Block</span>
                  </ActionButton>
                ) : isParticipantBlocked ? (
                  <ActionButton
                    onClick={handleUnblockUser}
                    disabled={isUpdatingBlockStatus}
                    aria-busy={isUpdatingBlockStatus}
                  >
                    {isUpdatingBlockStatus ? (
                      <SpinnerGapIcon className="h-5 w-5 animate-spin" />
                    ) : (
                      <ProhibitInsetIcon className="h-5 w-5" />
                    )}
                    <span>Unblock</span>
                  </ActionButton>
                ) : (
                  <ActionButton
                    onClick={handleBlockUser}
                    disabled={isUpdatingBlockStatus}
                    aria-busy={isUpdatingBlockStatus}
                  >
                    {isUpdatingBlockStatus ? (
                      <SpinnerGapIcon className="h-5 w-5 animate-spin" />
                    ) : (
                      <ProhibitInsetIcon className="h-5 w-5" />
                    )}
                    <span>Block</span>
                  </ActionButton>
                )}
              </li>
            )}
            {showReportParticipant && (
              <li>
                <ActionButton variant="danger" onClick={handleReportUser}>
                  <FlagIcon className="h-5 w-5" />
                  <span>Report</span>
                </ActionButton>
              </li>
            )}
            {customChannelActions}
          </ul>
        </div>
      )}
    </div>
  )
}
