import {
  isAgeSafetySystemType,
  isDmAgentSystemType,
  type AgeSafetySystemType,
  type DmAgentSystemType,
} from '@linktr.ee/messaging-taxonomy'
import { ProhibitIcon, SparkleIcon } from '@phosphor-icons/react'
import { MessageTimestamp, type EventComponentProps } from 'stream-chat-react'

const DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT: Record<DmAgentSystemType, string> =
  {
    SYSTEM_DM_AGENT_PAUSED: 'DM Agent has left the conversation',
    SYSTEM_DM_AGENT_RESUMED: 'DM Agent has rejoined the conversation',
  }

/**
 * System-message timestamps are hidden by default. A semantic type must opt in
 * here to render one, so new/unknown system types stay timestamp-less until
 * explicitly added. Keep in sync with the mobile client (cerberus
 * `CustomMessageSystem`); there is no shared package between the two surfaces.
 */
const SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES: readonly AgeSafetySystemType[] = [
  'SYSTEM_AGE_SAFETY_BLOCKED',
]

const AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT: Record<
  AgeSafetySystemType,
  string
> = {
  SYSTEM_AGE_SAFETY_BLOCKED:
    'This user isn’t able to reply because they don’t meet our age safety guidelines.',
}

const AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS = 'age safety guidelines.'
const AGE_SAFETY_SYSTEM_MESSAGE_URL = 'https://linktr.ee/s/about/contact'

const isShowTimestampSystemType = (
  value: string | undefined
): value is (typeof SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES)[number] => {
  return SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES.includes(
    value as (typeof SHOW_SYSTEM_MESSAGE_TIMESTAMP_TYPES)[number]
  )
}

const shouldShowSystemMessageTimestamp = (
  message: EventComponentProps['message']
): boolean => {
  return isShowTimestampSystemType(message.metadata?.custom_type)
}

type CustomSystemMessageVariant =
  | {
      kind: 'dm-agent'
      type: DmAgentSystemType
    }
  | {
      kind: 'age-safety'
      type: AgeSafetySystemType
    }

const getCustomSystemMessageVariant = (
  message: EventComponentProps['message']
): CustomSystemMessageVariant | undefined => {
  const metadataCustomType = message.metadata?.custom_type
  if (isDmAgentSystemType(metadataCustomType)) {
    return {
      kind: 'dm-agent',
      type: metadataCustomType,
    }
  }

  if (isAgeSafetySystemType(metadataCustomType)) {
    return {
      kind: 'age-safety',
      type: metadataCustomType,
    }
  }

  const fallbackType = message.dm_agent_system_type
  if (isDmAgentSystemType(fallbackType)) {
    return {
      kind: 'dm-agent',
      type: fallbackType,
    }
  }

  return undefined
}

const renderAgeSafetyMessageText = (messageText: string): React.ReactNode => {
  const emphasisIndex = messageText.indexOf(AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS)
  if (emphasisIndex === -1) {
    return messageText
  }

  const emphasisEndIndex =
    emphasisIndex + AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS.length

  return (
    <>
      {messageText.slice(0, emphasisIndex)}
      <a
        href={AGE_SAFETY_SYSTEM_MESSAGE_URL}
        target="_blank"
        rel="noopener noreferrer"
        className="mes-age-safety-system-message__emphasis font-medium text-inherit underline"
      >
        {AGE_SAFETY_SYSTEM_MESSAGE_EMPHASIS}
      </a>
      {messageText.slice(emphasisEndIndex)}
    </>
  )
}

export const CustomSystemMessage: React.FC<EventComponentProps> = (props) => {
  const isDateHidden = !shouldShowSystemMessageTimestamp(props.message)
  const customSystemMessageVariant = getCustomSystemMessageVariant(
    props.message
  )

  if (customSystemMessageVariant?.kind === 'dm-agent') {
    const messageText =
      props.message.text?.trim() ||
      DM_AGENT_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type]

    return (
      <div className="str-chat__message--system" data-testid="message-system">
        <div
          className="mes-dm-agent-system-message mx-auto mb-2 inline-flex w-fit max-w-[min(100%,480px)] items-center justify-center gap-[10px] rounded-[12px] border border-[rgba(0,0,0,0.08)] p-3 text-[rgba(0,0,0,0.55)]"
          data-testid="dm-agent-system-message"
          data-dm-agent-system-type={customSystemMessageVariant.type}
        >
          <SparkleIcon
            size={16}
            weight="regular"
            aria-hidden
            className="mes-dm-agent-system-message__sparkle shrink-0"
          />
          <p className="mes-dm-agent-system-message__text m-0 text-center text-[14px] font-normal leading-5 tracking-[0.21px]">
            {messageText}
          </p>
        </div>
        {!isDateHidden && <MessageTimestamp message={props.message} />}
      </div>
    )
  }

  if (customSystemMessageVariant?.kind === 'age-safety') {
    const messageText =
      props.message.text?.trim() ||
      AGE_SAFETY_SYSTEM_MESSAGE_FALLBACK_TEXT[customSystemMessageVariant.type]

    return (
      <div className="str-chat__message--system" data-testid="message-system">
        <div
          className="mes-age-safety-system-message box-border mx-auto mb-2 flex w-full max-w-[329px] items-start justify-center gap-3 rounded-[12px] border border-[var(--border-secondary,rgba(0,0,0,0.08))] bg-[var(--bg-warning-subtle,#fef3c6)] px-2 py-4 pl-5 text-[color:var(--text-warning-on-warning,#894b00)]"
          data-testid="age-safety-system-message"
          data-age-safety-system-type={customSystemMessageVariant.type}
        >
          <ProhibitIcon
            size={24}
            weight="duotone"
            aria-hidden
            className="mes-age-safety-system-message__icon shrink-0 text-[color:var(--text-warning-on-warning,#894b00)]"
            data-testid="age-safety-system-message-icon"
          />
          <div className="mes-age-safety-system-message__content min-w-0 flex-[1_0_0]">
            <p className="m-0 text-balance text-left text-[12px] font-normal leading-4 tracking-[0.21px] text-[color:var(--text-warning-on-warning,#894b00)]">
              {renderAgeSafetyMessageText(messageText)}
            </p>
          </div>
        </div>
        {!isDateHidden && <MessageTimestamp message={props.message} />}
      </div>
    )
  }

  return (
    <div className="str-chat__message--system" data-testid="message-system">
      <div className="str-chat__message--system__text">
        <div className="str-chat__message--system__line"></div>
        <p>{props.message.text}</p>
        <div className="str-chat__message--system__line"></div>
      </div>
      {!isDateHidden && <MessageTimestamp message={props.message} />}
    </div>
  )
}
