import Link from '@tiptap/extension-link'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { formatDate } from 'date-fns'
import FsLightbox from 'fslightbox-react'
import { Filter, kinds, nip19, UnsignedEvent, Event } from 'nostr-tools'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { toast } from 'react-toastify'
import { BlogCard } from '../components/BlogCard'
import { LoadingSpinner } from '../components/LoadingSpinner'
import { ProfileSection } from '../components/ProfileSection'
import { ZapButtons, ZapPopUp, ZapPresets, ZapQR } from '../components/Zap'
import {
  MetadataController,
  RelayController,
  UserRelaysType,
  ZapController
} from '../controllers'
import { useAppSelector, useDidMount } from '../hooks'
import { getModsEditPageRoute } from '../routes'
import '../styles/comments.css'
import '../styles/downloads.css'
import '../styles/innerPage.css'
import '../styles/popup.css'
import '../styles/post.css'
import '../styles/reactions.css'
import '../styles/styles.css'
import '../styles/tabs.css'
import '../styles/tags.css'
import '../styles/write.css'
import { DownloadUrl, ModDetails, PaymentRequest } from '../types'
import {
  abbreviateNumber,
  copyTextToClipboard,
  downloadFile,
  extractModData,
  formatNumber,
  getFilenameFromUrl,
  log,
  LogType,
  now,
  npubToHex,
  sendDMUsingRandomKey,
  signAndPublish,
  unformatNumber
} from '../utils'
import { REACTIONS } from '../constants'

export const ModPage = () => {
  const { naddr } = useParams()
  const [modData, setModData] = useState<ModDetails>()
  const [isFetching, setIsFetching] = useState(true)

  useDidMount(async () => {
    if (naddr) {
      const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
      const { identifier, kind, pubkey, relays = [] } = decoded.data

      const filter: Filter = {
        '#a': [identifier],
        authors: [pubkey],
        kinds: [kind]
      }

      RelayController.getInstance()
        .fetchEvent(filter, relays)
        .then((event) => {
          if (event) {
            const extracted = extractModData(event)
            setModData(extracted)
          }
        })
        .catch((err) => {
          log(
            true,
            LogType.Error,
            'An error occurred in fetching mod details from relays',
            err
          )
          toast.error('An error occurred in fetching mod details from relays')
        })
        .finally(() => {
          setIsFetching(false)
        })
    }
  })

  const oldDownloadListRef = useRef<HTMLDivElement>(null)

  const handleViewOldLinks = () => {
    if (oldDownloadListRef.current) {
      // Toggle styles
      if (oldDownloadListRef.current.style.height === '0px') {
        // Enable styles
        oldDownloadListRef.current.style.padding = ''
        oldDownloadListRef.current.style.height = ''
        oldDownloadListRef.current.style.border = ''
      } else {
        // Disable styles
        oldDownloadListRef.current.style.padding = '0'
        oldDownloadListRef.current.style.height = '0'
        oldDownloadListRef.current.style.border = 'unset'
      }
    }
  }

  if (isFetching)
    return <LoadingSpinner desc='Fetching mod details from relays' />

  if (!modData) return null

  return (
    <div className='InnerBodyMain'>
      <div className='ContainerMain'>
        <div className='IBMSecMainGroup IBMSecMainGroupAlt'>
          <div className='IBMSMSplitMain'>
            <div className='IBMSMSplitMainBigSide'>
              <div className='IBMSMSplitMainBigSideSec'>
                <Game
                  naddr={naddr!}
                  game={modData.game}
                  author={modData.author}
                  aTag={modData.aTag}
                />
                <Body
                  featuredImageUrl={modData.featuredImageUrl}
                  title={modData.title}
                  body={modData.body}
                  screenshotsUrls={modData.screenshotsUrls}
                  tags={modData.tags}
                  nsfw={modData.nsfw}
                />
                <Interactions modDetails={modData} />
                <PublishDetails
                  published_at={modData.published_at}
                  edited_at={modData.edited_at}
                  site={modData.rTag}
                />
              </div>
              <div className='IBMSMSplitMainBigSideSec'>
                <div className='IBMSMSMBSSDownloadsWrapper'>
                  <h4 className='IBMSMSMBSSDownloadsTitle'>Mod Download</h4>
                  {modData.downloadUrls.length > 0 && (
                    <div className='IBMSMSMBSSDownloadsPrime'>
                      <Download {...modData.downloadUrls[0]} />
                    </div>
                  )}
                  {modData.downloadUrls.length > 1 && (
                    <>
                      <div className='IBMSMSMBSSDownloadsActions'>
                        <button
                          className='btn btnMain'
                          id='viewOldLinks'
                          type='button'
                          onClick={handleViewOldLinks}
                        >
                          View other links
                        </button>
                      </div>
                      <div
                        ref={oldDownloadListRef}
                        id='oldDownloadList'
                        className='IBMSMSMBSSDownloads'
                        style={{ padding: 0, height: '0px', border: 'unset' }}
                      >
                        {modData.downloadUrls
                          .slice(1)
                          .map((download, index) => (
                            <Download
                              key={`downloadUrl-${index}`}
                              {...download}
                            />
                          ))}
                      </div>
                    </>
                  )}
                </div>
              </div>
              <div className='IBMSMSplitMainBigSideSec'>
                <div className='IBMSMSMBSSPostsWrapper'>
                  <h4 className='IBMSMSMBSSPostsTitle'>
                    Creator's Blog Posts (WIP)
                  </h4>
                  <div className='IBMSMList IBMSMListAlt'>
                    <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
                    <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
                    <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
                  </div>
                </div>
              </div>
              <div className='IBMSMSplitMainBigSideSec'>
                <Comments />
              </div>
            </div>
            <ProfileSection pubkey={modData.author} />
          </div>
        </div>
      </div>
    </div>
  )
}

type GameProps = {
  naddr: string
  game: string
  author: string
  aTag: string
}

const Game = ({ naddr, game, author, aTag }: GameProps) => {
  const navigate = useNavigate()
  const userState = useAppSelector((state) => state.user)
  const [isLoading, setIsLoading] = useState(false)
  const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
  const [showReportPopUp, setShowReportPopUp] = useState(false)
  const [isBlocked, setIsBlocked] = useState(false)
  const [isAddedToNSFW, setIsAddedToNSFW] = useState(false)

  useEffect(() => {
    if (userState.auth && userState.user?.pubkey) {
      const pubkey = userState.user.pubkey as string

      const muteListFilter: Filter = {
        kinds: [kinds.Mutelist],
        authors: [pubkey]
      }

      RelayController.getInstance()
        .fetchEventFromUserRelays(muteListFilter, pubkey, UserRelaysType.Write)
        .then((event) => {
          if (event) {
            // get a list of tags
            const tags = event.tags
            const blocked =
              tags.findIndex((item) => item[0] === 'a' && item[1] === aTag) !==
              -1

            setIsBlocked(blocked)
          }
        })

      if (
        userState.user.npub &&
        userState.user.npub === import.meta.env.VITE_REPORTING_NPUB
      ) {
        const nsfwListFilter: Filter = {
          kinds: [kinds.Curationsets],
          authors: [pubkey],
          '#d': ['nsfw']
        }

        RelayController.getInstance()
          .fetchEventFromUserRelays(
            nsfwListFilter,
            pubkey,
            UserRelaysType.Write
          )
          .then((event) => {
            if (event) {
              // get a list of tags
              const tags = event.tags
              const existsInNSFWList =
                tags.findIndex(
                  (item) => item[0] === 'a' && item[1] === aTag
                ) !== -1

              setIsAddedToNSFW(existsInNSFWList)
            }
          })
      }
    }
  }, [userState, aTag])

  const handleBlock = async () => {
    let hexPubkey: string

    setIsLoading(true)
    setLoadingSpinnerDesc('Getting user pubkey')

    if (userState.auth && userState.user?.pubkey) {
      hexPubkey = userState.user.pubkey as string
    } else {
      hexPubkey = (await window.nostr?.getPublicKey()) as string
    }

    if (!hexPubkey) {
      toast.error('Could not get pubkey for updating mute list')
      setIsLoading(false)
      return
    }

    setLoadingSpinnerDesc(`Finding user's mute list`)

    // Define the event filter to search for the user's mute list events.
    // We look for events of a specific kind (Mutelist) authored by the given hexPubkey.
    const filter: Filter = {
      kinds: [kinds.Mutelist],
      authors: [hexPubkey]
    }

    // Fetch the mute list event from the relays. This returns the event containing the user's mute list.
    const muteListEvent =
      await RelayController.getInstance().fetchEventFromUserRelays(
        filter,
        hexPubkey,
        UserRelaysType.Write
      )

    let unsignedEvent: UnsignedEvent

    if (muteListEvent) {
      // get a list of tags
      const tags = muteListEvent.tags
      const alreadyExists =
        tags.findIndex((item) => item[0] === 'a' && item[1] === aTag) !== -1

      if (alreadyExists) {
        setIsLoading(false)
        setIsBlocked(true)
        return toast.warn(`Mod reference is already in user's mute list`)
      }

      tags.push(['a', aTag])

      unsignedEvent = {
        pubkey: muteListEvent.pubkey,
        kind: muteListEvent.kind,
        content: muteListEvent.content,
        created_at: now(),
        tags: [...tags]
      }
    } else {
      unsignedEvent = {
        pubkey: hexPubkey,
        kind: kinds.Mutelist,
        content: '',
        created_at: now(),
        tags: [['a', aTag]]
      }
    }

    setLoadingSpinnerDesc('Updating mute list event')

    const isUpdated = await signAndPublish(unsignedEvent)
    if (isUpdated) {
      setIsBlocked(true)
    }
    setIsLoading(false)
  }

  const handleUnblock = async () => {
    const pubkey = userState.user?.pubkey as string

    const filter: Filter = {
      kinds: [kinds.Mutelist],
      authors: [pubkey]
    }

    setIsLoading(true)
    setLoadingSpinnerDesc(`Finding user's mute list`)

    // Fetch the mute list event from the relays. This returns the event containing the user's mute list.
    const muteListEvent =
      await RelayController.getInstance().fetchEventFromUserRelays(
        filter,
        pubkey,
        UserRelaysType.Write
      )

    if (!muteListEvent) {
      toast.error(`Couldn't get user's mute list event from relays`)
      return
    }

    const tags = muteListEvent.tags

    const unsignedEvent: UnsignedEvent = {
      pubkey: muteListEvent.pubkey,
      kind: muteListEvent.kind,
      content: muteListEvent.content,
      created_at: now(),
      tags: tags.filter((item) => item[0] !== 'a' || item[1] !== aTag)
    }

    setLoadingSpinnerDesc('Updating mute list event')
    const isUpdated = await signAndPublish(unsignedEvent)
    if (isUpdated) {
      setIsBlocked(false)
    }

    setIsLoading(false)
  }

  const handleBlockNSFW = async () => {
    const pubkey = userState.user?.pubkey as string | undefined

    if (!pubkey) return

    const filter: Filter = {
      kinds: [kinds.Curationsets],
      authors: [pubkey],
      '#d': ['nsfw']
    }

    setIsLoading(true)
    setLoadingSpinnerDesc('Finding NSFW list')

    const nsfwListEvent =
      await RelayController.getInstance().fetchEventFromUserRelays(
        filter,
        pubkey,
        UserRelaysType.Write
      )

    let unsignedEvent: UnsignedEvent

    if (nsfwListEvent) {
      // get a list of tags
      const tags = nsfwListEvent.tags
      const alreadyExists =
        tags.findIndex((item) => item[0] === 'a' && item[1] === aTag) !== -1

      if (alreadyExists) {
        setIsLoading(false)
        setIsAddedToNSFW(true)
        return toast.warn(`Mod reference is already in user's nsfw list`)
      }

      tags.push(['a', aTag])

      unsignedEvent = {
        pubkey: nsfwListEvent.pubkey,
        kind: nsfwListEvent.kind,
        content: nsfwListEvent.content,
        created_at: now(),
        tags: [...tags]
      }
    } else {
      unsignedEvent = {
        pubkey: pubkey,
        kind: kinds.Curationsets,
        content: '',
        created_at: now(),
        tags: [
          ['a', aTag],
          ['d', 'nsfw']
        ]
      }
    }

    setLoadingSpinnerDesc('Updating nsfw list event')

    const isUpdated = await signAndPublish(unsignedEvent)
    if (isUpdated) {
      setIsAddedToNSFW(true)
    }
    setIsLoading(false)
  }

  const handleUnblockNSFW = async () => {
    const pubkey = userState.user?.pubkey as string

    const filter: Filter = {
      kinds: [kinds.Curationsets],
      authors: [pubkey],
      '#d': ['nsfw']
    }

    setIsLoading(true)
    setLoadingSpinnerDesc('Finding NSFW list')

    const nsfwListEvent =
      await RelayController.getInstance().fetchEventFromUserRelays(
        filter,
        pubkey,
        UserRelaysType.Write
      )

    if (!nsfwListEvent) {
      toast.error(`Couldn't get nsfw list event from relays`)
      return
    }

    const tags = nsfwListEvent.tags

    const unsignedEvent: UnsignedEvent = {
      pubkey: nsfwListEvent.pubkey,
      kind: nsfwListEvent.kind,
      content: nsfwListEvent.content,
      created_at: now(),
      tags: tags.filter((item) => item[0] !== 'a' || item[1] !== aTag)
    }

    setLoadingSpinnerDesc('Updating nsfw list event')
    const isUpdated = await signAndPublish(unsignedEvent)
    if (isUpdated) {
      setIsAddedToNSFW(false)
    }

    setIsLoading(false)
  }

  const isAdmin =
    userState.user?.npub &&
    userState.user.npub === import.meta.env.VITE_REPORTING_NPUB

  return (
    <>
      {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
      <div className='IBMSMSMBSSModFor'>
        <p className='IBMSMSMBSSModForPara'>
          Mod for:&nbsp;
          <a className='IBMSMSMBSSModForLink' href='search.html'>
            {game}
          </a>
        </p>
        <div className='dropdown dropdownMain' style={{ flexGrow: 'unset' }}>
          <button
            className='btn btnMain btnMainDropdown'
            aria-expanded='false'
            data-bs-toggle='dropdown'
            type='button'
            style={{
              borderRadius: '5px',
              background: 'unset',
              padding: '5px'
            }}
          >
            <svg
              xmlns='http://www.w3.org/2000/svg'
              viewBox='-192 0 512 512'
              width='1em'
              height='1em'
              fill='currentColor'
            >
              <path d='M64 360C94.93 360 120 385.1 120 416C120 446.9 94.93 472 64 472C33.07 472 8 446.9 8 416C8 385.1 33.07 360 64 360zM64 200C94.93 200 120 225.1 120 256C120 286.9 94.93 312 64 312C33.07 312 8 286.9 8 256C8 225.1 33.07 200 64 200zM64 152C33.07 152 8 126.9 8 96C8 65.07 33.07 40 64 40C94.93 40 120 65.07 120 96C120 126.9 94.93 152 64 152z'></path>
            </svg>
          </button>
          <div className={`dropdown-menu dropdown-menu-end dropdownMainMenu`}>
            {userState.auth && userState.user?.pubkey === author && (
              <a
                className='dropdown-item dropdownMainMenuItem'
                onClick={() => navigate(getModsEditPageRoute(naddr))}
              >
                <svg
                  xmlns='http://www.w3.org/2000/svg'
                  viewBox='0 0 512 512'
                  width='1em'
                  height='1em'
                  fill='currentColor'
                  className='IBMSMSMSSS_Author_Top_Icon'
                >
                  <path d='M362.7 19.32C387.7-5.678 428.3-5.678 453.3 19.32L492.7 58.75C517.7 83.74 517.7 124.3 492.7 149.3L444.3 197.7L314.3 67.72L362.7 19.32zM421.7 220.3L188.5 453.4C178.1 463.8 165.2 471.5 151.1 475.6L30.77 511C22.35 513.5 13.24 511.2 7.03 504.1C.8198 498.8-1.502 489.7 .976 481.2L36.37 360.9C40.53 346.8 48.16 333.9 58.57 323.5L291.7 90.34L421.7 220.3z'></path>
                </svg>
                Edit
              </a>
            )}

            <a
              className='dropdown-item dropdownMainMenuItem'
              onClick={() => {
                copyTextToClipboard(window.location.href).then((isCopied) => {
                  if (isCopied) toast.success('Url copied to clipboard!')
                })
              }}
            >
              <svg
                xmlns='http://www.w3.org/2000/svg'
                viewBox='0 0 512 512'
                width='1em'
                height='1em'
                fill='currentColor'
                className='IBMSMSMSSS_Author_Top_Icon'
              >
                <path d='M384 96L384 0h-112c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48H464c26.51 0 48-21.49 48-48V128h-95.1C398.4 128 384 113.6 384 96zM416 0v96h96L416 0zM192 352V128h-144c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h192c26.51 0 48-21.49 48-48L288 416h-32C220.7 416 192 387.3 192 352z'></path>
              </svg>
              Copy URL
            </a>
            <a className='dropdown-item dropdownMainMenuItem' href='#'>
              <svg
                xmlns='http://www.w3.org/2000/svg'
                viewBox='0 0 512 512'
                width='1em'
                height='1em'
                fill='currentColor'
                className='IBMSMSMSSS_Author_Top_Icon'
              >
                <path d='M503.7 226.2l-176 151.1c-15.38 13.3-39.69 2.545-39.69-18.16V272.1C132.9 274.3 66.06 312.8 111.4 457.8c5.031 16.09-14.41 28.56-28.06 18.62C39.59 444.6 0 383.8 0 322.3c0-152.2 127.4-184.4 288-186.3V56.02c0-20.67 24.28-31.46 39.69-18.16l176 151.1C514.8 199.4 514.8 216.6 503.7 226.2z'></path>
              </svg>
              Share
            </a>
            <a
              className='dropdown-item dropdownMainMenuItem'
              id='reportPost'
              onClick={() => setShowReportPopUp(true)}
            >
              <svg
                xmlns='http://www.w3.org/2000/svg'
                viewBox='0 0 512 512'
                width='1em'
                height='1em'
                fill='currentColor'
                className='IBMSMSMSSS_Author_Top_Icon'
              >
                <path d='M506.3 417l-213.3-364c-16.33-28-57.54-28-73.98 0l-213.2 364C-10.59 444.9 9.849 480 42.74 480h426.6C502.1 480 522.6 445 506.3 417zM232 168c0-13.25 10.75-24 24-24S280 154.8 280 168v128c0 13.25-10.75 24-23.1 24S232 309.3 232 296V168zM256 416c-17.36 0-31.44-14.08-31.44-31.44c0-17.36 14.07-31.44 31.44-31.44s31.44 14.08 31.44 31.44C287.4 401.9 273.4 416 256 416z'></path>
              </svg>
              Report
            </a>
            <a
              className='dropdown-item dropdownMainMenuItem'
              onClick={isBlocked ? handleUnblock : handleBlock}
            >
              <svg
                xmlns='http://www.w3.org/2000/svg'
                viewBox='-32 0 512 512'
                width='1em'
                height='1em'
                fill='currentColor'
                className='IBMSMSMSSS_Author_Top_Icon'
              >
                <path d='M323.5 51.25C302.8 70.5 284 90.75 267.4 111.1C240.1 73.62 206.2 35.5 168 0C69.75 91.12 0 210 0 281.6C0 408.9 100.2 512 224 512s224-103.1 224-230.4C448 228.4 396 118.5 323.5 51.25zM304.1 391.9C282.4 407 255.8 416 226.9 416c-72.13 0-130.9-47.73-130.9-125.2c0-38.63 24.24-72.64 65.13-83.3c10.14-2.656 19.94 4.78 19.94 15.27c0 6.941-4.469 13.16-11.16 15.19c-17.5 4.578-34.41 23.94-34.41 52.84c0 50.81 39.31 94.81 91.41 94.81c24.66 0 45.22-6.5 63.19-18.75c11.75-8 27.91 3.469 23.91 16.69C314.6 384.7 309.8 388.4 304.1 391.9z'></path>
              </svg>
              {isBlocked ? 'Unblock' : 'Block'} Post
            </a>
            {isAdmin && (
              <a
                className='dropdown-item dropdownMainMenuItem'
                onClick={isAddedToNSFW ? handleUnblockNSFW : handleBlockNSFW}
              >
                <svg
                  xmlns='http://www.w3.org/2000/svg'
                  viewBox='-32 0 512 512'
                  width='1em'
                  height='1em'
                  fill='currentColor'
                  className='IBMSMSMSSS_Author_Top_Icon'
                >
                  <path d='M323.5 51.25C302.8 70.5 284 90.75 267.4 111.1C240.1 73.62 206.2 35.5 168 0C69.75 91.12 0 210 0 281.6C0 408.9 100.2 512 224 512s224-103.1 224-230.4C448 228.4 396 118.5 323.5 51.25zM304.1 391.9C282.4 407 255.8 416 226.9 416c-72.13 0-130.9-47.73-130.9-125.2c0-38.63 24.24-72.64 65.13-83.3c10.14-2.656 19.94 4.78 19.94 15.27c0 6.941-4.469 13.16-11.16 15.19c-17.5 4.578-34.41 23.94-34.41 52.84c0 50.81 39.31 94.81 91.41 94.81c24.66 0 45.22-6.5 63.19-18.75c11.75-8 27.91 3.469 23.91 16.69C314.6 384.7 309.8 388.4 304.1 391.9z'></path>
                </svg>
                {isAddedToNSFW ? 'Un-mark' : 'Mark'} as NSFW
              </a>
            )}
          </div>
        </div>
      </div>
      {showReportPopUp && (
        <ReportPopup
          aTag={aTag}
          handleClose={() => setShowReportPopUp(false)}
        />
      )}
    </>
  )
}

type ReportPopupProps = {
  aTag: string
  handleClose: () => void
}

const ReportPopup = ({ aTag, handleClose }: ReportPopupProps) => {
  const userState = useAppSelector((state) => state.user)
  const [selectedOptions, setSelectedOptions] = useState({
    actuallyCP: false,
    spam: false,
    scam: false,
    notAGameMod: false,
    stolenGameMod: false,
    wasntTaggedNSFW: false,
    otherReason: false
  })
  const [isLoading, setIsLoading] = useState(false)
  const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')

  const handleCheckboxChange = (option: keyof typeof selectedOptions) => {
    setSelectedOptions((prevState) => ({
      ...prevState,
      [option]: !prevState[option]
    }))
  }

  const handleSubmit = async () => {
    const selectedOptionsCount = Object.values(selectedOptions).filter(
      (isSelected) => isSelected
    ).length

    if (selectedOptionsCount === 0) {
      toast.error('At least one option should be checked!')
      return
    }
    let hexPubkey: string

    setIsLoading(true)
    setLoadingSpinnerDesc('Getting user pubkey')

    if (userState.auth && userState.user?.pubkey) {
      hexPubkey = userState.user.pubkey as string
    } else {
      hexPubkey = (await window.nostr?.getPublicKey()) as string
    }

    if (!hexPubkey) {
      toast.error('Could not get pubkey for reporting mod!')
      setIsLoading(false)
      return
    }

    const metadataController = await MetadataController.getInstance()
    const reportingPubkey = npubToHex(metadataController.reportingNpub)

    if (reportingPubkey === hexPubkey) {
      setLoadingSpinnerDesc(`Finding user's mute list`)
      // Define the event filter to search for the user's mute list events.
      // We look for events of a specific kind (Mutelist) authored by the given hexPubkey.
      const filter: Filter = {
        kinds: [kinds.Mutelist],
        authors: [hexPubkey]
      }

      // Fetch the mute list event from the relays. This returns the event containing the user's mute list.
      const muteListEvent =
        await RelayController.getInstance().fetchEventFromUserRelays(
          filter,
          hexPubkey,
          UserRelaysType.Write
        )

      let unsignedEvent: UnsignedEvent

      if (muteListEvent) {
        // get a list of tags
        const tags = muteListEvent.tags
        const alreadyExists =
          tags.findIndex((item) => item[0] === 'a' && item[1] === aTag) !== -1

        if (alreadyExists) {
          setIsLoading(false)
          return toast.warn(`Mod reference is already in user's mute list`)
        }

        tags.push(['a', aTag])

        unsignedEvent = {
          pubkey: muteListEvent.pubkey,
          kind: muteListEvent.kind,
          content: muteListEvent.content,
          created_at: now(),
          tags: [...tags]
        }
      } else {
        unsignedEvent = {
          pubkey: hexPubkey,
          kind: kinds.Mutelist,
          content: '',
          created_at: now(),
          tags: [['a', aTag]]
        }
      }

      setLoadingSpinnerDesc('Updating mute list event')
      const isUpdated = await signAndPublish(unsignedEvent)
      if (isUpdated) handleClose()
    } else {
      const href = window.location.href
      let message = `I'd like to report ${href} due to following reasons:\n`

      Object.entries(selectedOptions).forEach(([key, value]) => {
        if (value) {
          message += `* ${key}\n`
        }
      })

      setLoadingSpinnerDesc('Sending report')
      const isSent = await sendDMUsingRandomKey(message, reportingPubkey!)
      if (isSent) handleClose()
    }
    setIsLoading(false)
  }

  return (
    <>
      {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
      <div className='popUpMain'>
        <div className='ContainerMain'>
          <div className='popUpMainCardWrapper'>
            <div className='popUpMainCard popUpMainCardQR'>
              <div className='popUpMainCardTop'>
                <div className='popUpMainCardTopInfo'>
                  <h3>Report Post</h3>
                </div>
                <div className='popUpMainCardTopClose' onClick={handleClose}>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='-96 0 512 512'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    style={{ zIndex: 1 }}
                  >
                    <path d='M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z'></path>
                  </svg>
                </div>
              </div>
              <div className='pUMCB_Zaps'>
                <div className='pUMCB_ZapsInside'>
                  <div className='inputLabelWrapperMain'>
                    <label
                      className='form-label labelMain'
                      style={{ fontWeight: 'bold' }}
                    >
                      Why are you reporting this?
                    </label>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>
                        Actually CP
                      </label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.actuallyCP}
                        onChange={() => handleCheckboxChange('actuallyCP')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>Spam</label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.spam}
                        onChange={() => handleCheckboxChange('spam')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>Scam</label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.scam}
                        onChange={() => handleCheckboxChange('scam')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>
                        Not a game mod
                      </label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.notAGameMod}
                        onChange={() => handleCheckboxChange('notAGameMod')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>
                        Stolen game mod
                      </label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.stolenGameMod}
                        onChange={() => handleCheckboxChange('stolenGameMod')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>
                        Wasn't tagged NSFW
                      </label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.wasntTaggedNSFW}
                        onChange={() => handleCheckboxChange('wasntTaggedNSFW')}
                      />
                    </div>
                    <div className='inputLabelWrapperMain inputLabelWrapperMainAlt'>
                      <label className='form-label labelMain'>
                        Other reason
                      </label>
                      <input
                        type='checkbox'
                        className='CheckboxMain'
                        name='reportOption'
                        checked={selectedOptions.otherReason}
                        onChange={() => handleCheckboxChange('otherReason')}
                      />
                    </div>
                  </div>
                  <button
                    className='btn btnMain pUMCB_Report'
                    type='button'
                    style={{ width: '100%' }}
                    onClick={handleSubmit}
                  >
                    Submit Report
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}

type BodyProps = {
  featuredImageUrl: string
  title: string
  body: string
  screenshotsUrls: string[]
  tags: string[]
  nsfw: boolean
}

const Body = ({
  featuredImageUrl,
  title,
  body,
  screenshotsUrls,
  tags,
  nsfw
}: BodyProps) => {
  const postBodyRef = useRef<HTMLDivElement>(null)
  const viewFullPostBtnRef = useRef<HTMLDivElement>(null)

  const [lightBoxController, setLightBoxController] = useState({
    toggler: false,
    slide: 1
  })

  const openLightBoxOnSlide = (slide: number) => {
    setLightBoxController((prev) => ({
      toggler: !prev.toggler,
      slide
    }))
  }

  const viewFullPost = () => {
    if (postBodyRef.current && viewFullPostBtnRef.current) {
      postBodyRef.current.style.maxHeight = 'unset'
      postBodyRef.current.style.padding = 'unset'
      viewFullPostBtnRef.current.style.display = 'none'
    }
  }

  const editor = useEditor({
    content: body,
    extensions: [StarterKit, Link],
    editable: false
  })

  return (
    <>
      <div className='IBMSMSMBSSPost'>
        <div
          className='IBMSMSMBSSPostPicture'
          style={{
            background: `url(${featuredImageUrl}) center / cover no-repeat`
          }}
        ></div>
        <div className='IBMSMSMBSSPostInside'>
          <div className='IBMSMSMBSSPostTitle'>
            <h1 className='IBMSMSMBSSPostTitleHeading'>{title}</h1>
          </div>
          <div
            ref={postBodyRef}
            className='IBMSMSMBSSPostBody'
            style={{ maxHeight: '250px', padding: '0 10px' }}
          >
            <EditorContent editor={editor} />
            <div ref={viewFullPostBtnRef} className='IBMSMSMBSSPostBodyHide'>
              <p onClick={viewFullPost}>View</p>
            </div>
          </div>
          <div className='IBMSMSMBSSShots'>
            {screenshotsUrls.map((url, index) => (
              <img
                className='IBMSMSMBSSShotsImg'
                src={url}
                alt={`ScreenShot-${index}`}
                key={url}
                onClick={() => openLightBoxOnSlide(index + 1)}
              />
            ))}
          </div>
          <div className='IBMSMSMBSSTags'>
            {nsfw && (
              <div className='IBMSMSMBSSTagsTag IBMSMSMBSSTagsTagNSFW'>
                <p>NSFW</p>
              </div>
            )}

            {tags.map((tag, index) => (
              <a className='IBMSMSMBSSTagsTag' href='#' key={`tag-${index}`}>
                {tag}
              </a>
            ))}
          </div>
        </div>
      </div>
      <FsLightbox
        toggler={lightBoxController.toggler}
        sources={screenshotsUrls}
        slide={lightBoxController.slide}
      />
    </>
  )
}

type InteractionsProps = {
  modDetails: ModDetails
}

const Interactions = ({ modDetails }: InteractionsProps) => {
  return (
    <div className='IBMSMSplitMainBigSideSec'>
      <div className='IBMSMSMBSS_Details'>
        <a
          href='#commentsArea'
          style={{ textDecoration: 'unset', color: 'unset' }}
        >
          <div className='IBMSMSMBSS_Details_Card IBMSMSMBSS_D_CComments'>
            <div className='IBMSMSMBSS_Details_CardVisual'>
              <svg
                xmlns='http://www.w3.org/2000/svg'
                viewBox='0 0 512 512'
                width='1em'
                height='1em'
                fill='currentColor'
                className='IBMSMSMBSS_Details_CardVisualIcon'
              >
                <path d='M256 31.1c-141.4 0-255.1 93.12-255.1 208c0 49.62 21.35 94.98 56.97 130.7c-12.5 50.37-54.27 95.27-54.77 95.77c-2.25 2.25-2.875 5.734-1.5 8.734c1.249 3 4.021 4.766 7.271 4.766c66.25 0 115.1-31.76 140.6-51.39c32.63 12.25 69.02 19.39 107.4 19.39c141.4 0 255.1-93.13 255.1-207.1S397.4 31.1 256 31.1zM127.1 271.1c-17.75 0-32-14.25-32-31.1s14.25-32 32-32s32 14.25 32 32S145.7 271.1 127.1 271.1zM256 271.1c-17.75 0-31.1-14.25-31.1-31.1s14.25-32 31.1-32s31.1 14.25 31.1 32S273.8 271.1 256 271.1zM383.1 271.1c-17.75 0-32-14.25-32-31.1s14.25-32 32-32s32 14.25 32 32S401.7 271.1 383.1 271.1z'></path>
              </svg>
            </div>
            <p className='IBMSMSMBSS_Details_CardText'>420</p>
          </div>
        </a>
        <Zap modDetails={modDetails} />
        <Reactions modDetails={modDetails} />
      </div>
    </div>
  )
}

type PublishDetailsProps = {
  published_at: number
  edited_at: number
  site: string
}

const PublishDetails = ({
  published_at,
  edited_at,
  site
}: PublishDetailsProps) => {
  return (
    <div className='IBMSMSplitMainBigSideSec'>
      <div className='IBMSMSMBSSPost_PostDetails'>
        <div
          data-bs-toggle='tooltip'
          data-bs-placement='left'
          className='IBMSMSMBSSPost_PDElement'
          title='Publish date'
        >
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 512 512'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSSPost_PDElementIcon'
            data-bs-toggle='tooltip'
            data-bss-tooltip
            aria-label='Publish date'
          >
            <path d='M480 32H128C110.3 32 96 46.33 96 64v336C96 408.8 88.84 416 80 416S64 408.8 64 400V96H32C14.33 96 0 110.3 0 128v288c0 35.35 28.65 64 64 64h384c35.35 0 64-28.65 64-64V64C512 46.33 497.7 32 480 32zM272 416h-96C167.2 416 160 408.8 160 400C160 391.2 167.2 384 176 384h96c8.836 0 16 7.162 16 16C288 408.8 280.8 416 272 416zM272 320h-96C167.2 320 160 312.8 160 304C160 295.2 167.2 288 176 288h96C280.8 288 288 295.2 288 304C288 312.8 280.8 320 272 320zM432 416h-96c-8.836 0-16-7.164-16-16c0-8.838 7.164-16 16-16h96c8.836 0 16 7.162 16 16C448 408.8 440.8 416 432 416zM432 320h-96C327.2 320 320 312.8 320 304C320 295.2 327.2 288 336 288h96C440.8 288 448 295.2 448 304C448 312.8 440.8 320 432 320zM448 208C448 216.8 440.8 224 432 224h-256C167.2 224 160 216.8 160 208v-96C160 103.2 167.2 96 176 96h256C440.8 96 448 103.2 448 112V208z' />
          </svg>
          <p className='IBMSMSMBSSPost_PDElementText'>
            {formatDate(
              (published_at !== -1 ? published_at : edited_at) * 1000,
              'dd/MM/yyyy hh:mm:ss aa'
            )}
          </p>
        </div>
        <div
          data-bs-toggle='tooltip'
          data-bs-placement='left'
          className='IBMSMSMBSSPost_PDElement'
          title='Last modified'
        >
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 512 512'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSSPost_PDElementIcon'
          >
            <path d='M362.7 19.32C387.7-5.678 428.3-5.678 453.3 19.32L492.7 58.75C517.7 83.74 517.7 124.3 492.7 149.3L444.3 197.7L314.3 67.72L362.7 19.32zM421.7 220.3L188.5 453.4C178.1 463.8 165.2 471.5 151.1 475.6L30.77 511C22.35 513.5 13.24 511.2 7.03 504.1C.8198 498.8-1.502 489.7 .976 481.2L36.37 360.9C40.53 346.8 48.16 333.9 58.57 323.5L291.7 90.34L421.7 220.3z' />
          </svg>
          <p className='IBMSMSMBSSPost_PDElementText'>
            {formatDate(edited_at * 1000, 'dd/MM/yyyy hh:mm:ss aa')}
          </p>
        </div>
        <a
          data-bs-toggle='tooltip'
          data-bs-placement='left'
          className='IBMSMSMBSSPost_PDElement IBMSMSMBSSPost_PDElementLink'
          href='#'
          title='Published on'
          target='_blank'
        >
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 -64 640 640'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSSPost_PDElementIcon'
          >
            <path d='M172.5 131.1C228.1 75.51 320.5 75.51 376.1 131.1C426.1 181.1 433.5 260.8 392.4 318.3L391.3 319.9C381 334.2 361 337.6 346.7 327.3C332.3 317 328.9 297 339.2 282.7L340.3 281.1C363.2 249 359.6 205.1 331.7 177.2C300.3 145.8 249.2 145.8 217.7 177.2L105.5 289.5C73.99 320.1 73.99 372 105.5 403.5C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4C265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2C188.1 505.3 110.2 498.7 60.21 448.8C3.741 392.3 3.741 300.7 60.21 244.3L172.5 131.1zM467.5 380C411 436.5 319.5 436.5 263 380C213 330 206.5 251.2 247.6 193.7L248.7 192.1C258.1 177.8 278.1 174.4 293.3 184.7C307.7 194.1 311.1 214.1 300.8 229.3L299.7 230.9C276.8 262.1 280.4 306.9 308.3 334.8C339.7 366.2 390.8 366.2 422.3 334.8L534.5 222.5C566 191 566 139.1 534.5 108.5C506.7 80.63 462.7 76.99 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58C374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.731 529.8 13.25 579.8 63.24C636.3 119.7 636.3 211.3 579.8 267.7L467.5 380z' />
          </svg>
          <p className='IBMSMSMBSSPost_PDElementText'>{site}</p>
        </a>
      </div>
    </div>
  )
}

const Download = ({
  url,
  hash,
  signatureKey,
  malwareScanLink,
  modVersion,
  customNote
}: DownloadUrl) => {
  const [showAuthDetails, setShowAuthDetails] = useState(false)

  const handleDownload = () => {
    // Get the filename from the URL
    const filename = getFilenameFromUrl(url)

    downloadFile(url, filename)
  }

  return (
    <div className='IBMSMSMBSSDownloadsElement'>
      <div className='IBMSMSMBSSDownloadsElementInside'>
        <button
          className='btn btnMain IBMSMSMBSSDownloadsElementBtn'
          type='button'
          onClick={handleDownload}
        >
          Download
        </button>
      </div>
      <div className='IBMSMSMBSSDownloadsElementInside'>
        <p>Ratings (WIP):</p>
        <div className='tabsMain'>
          <ul className='nav nav-tabs tabsMainTop' role='tablist'>
            <li className='nav-item tabsMainTopTab' role='presentation'>
              <a
                className='nav-link active tabsMainTopTabLink'
                role='tab'
                data-bs-toggle='tab'
                href='#tab-1'
              >
                WoT
              </a>
            </li>
            <li className='nav-item tabsMainTopTab' role='presentation'>
              <a
                className='nav-link tabsMainTopTabLink'
                role='tab'
                data-bs-toggle='tab'
                href='#tab-2'
              >
                All
              </a>
            </li>
          </ul>
          <div className='tab-content tabsMainBottom'>
            <div
              className='tab-pane active tabsMainBottomContent'
              role='tabpanel'
              id='tab-1'
            >
              <div className='IBMSMSMBSSDownloadsElementInsideReactions'>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement IBMSMSMBSSDEIReactionsElementActive'
                  title='Clean'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 0 512 512'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M512 165.4c0 127.9-70.05 235.3-175.3 270.1c-20.04 7.938-41.83 12.46-64.69 12.46c-64.9 0-125.2-36.51-155.7-94.47c-54.13 49.93-68.71 107-68.96 108.1C44.72 472.6 34.87 480 24.02 480c-1.844 0-3.727-.2187-5.602-.6562c-12.89-3.098-20.84-16.08-17.75-28.96c9.598-39.5 90.47-226.4 335.3-226.4C344.8 224 352 216.8 352 208S344.8 192 336 192C228.6 192 151 226.6 96.29 267.6c.1934-10.82 1.242-21.84 3.535-33.05c13.47-65.81 66.04-119 131.4-134.2c28.33-6.562 55.68-6.013 80.93-.0054c56 13.32 118.2-7.412 149.3-61.24c5.664-9.828 20.02-9.516 24.66 .8282C502.7 76.76 512 121.9 512 165.4z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>420</p>
                </div>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement'
                  title='Broken link'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 -64 640 640'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M185.7 120.3C242.5 75.82 324.7 79.73 376.1 131.1C420.1 175.1 430.9 239.6 406.7 293.5L438.6 318.4L534.5 222.5C566 191 566 139.1 534.5 108.5C506.7 80.63 462.7 76.1 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58C374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.732 529.8 13.25 579.8 63.24C636.3 119.7 636.3 211.3 579.8 267.7L489.3 358.2L630.8 469.1C641.2 477.3 643.1 492.4 634.9 502.8C626.7 513.2 611.6 515.1 601.2 506.9L9.196 42.89C-1.236 34.71-3.065 19.63 5.112 9.196C13.29-1.236 28.37-3.065 38.81 5.112L185.7 120.3zM238.1 161.1L353.4 251.7C359.3 225.5 351.7 197.2 331.7 177.2C306.6 152.1 269.1 147 238.1 161.1V161.1zM263 380C233.1 350.1 218.7 309.8 220.9 270L406.6 416.4C357.4 431 301.9 418.9 263 380V380zM116.6 187.9L167.2 227.8L105.5 289.5C73.99 320.1 73.99 372 105.5 403.5C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4C265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2C188.1 505.3 110.2 498.7 60.21 448.8C3.741 392.3 3.741 300.7 60.21 244.3L116.6 187.9z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>420</p>
                </div>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement'
                  title='Has virus'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 0 512 512'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M288 43.55C288 93.44 348.3 118.4 383.6 83.15L391.8 74.98C404.3 62.48 424.5 62.48 437 74.98C449.5 87.48 449.5 107.7 437 120.2L368.7 188.6C352.7 204.3 341.4 224.8 337.6 249.8L168.3 420.1C148.4 448.6 104.5 448.6 84.63 420.1C64.73 391.5 64.73 347.6 84.63 319.1L172.4 231.3C208.7 197 233.6 154.3 233.6 104.4C233.6 54.47 173.3 29.5 138 64.73L130.1 72.9C117.6 85.4 97.41 85.4 84.94 72.9C72.44 60.4 72.44 40.17 84.94 27.67L153.2-41.52C194.8-83.6 295.2-83.6 336.7-41.52C375.5 2.213 377.4 55.78 288 43.55zM121.4 169.3L44.88 245.8C25.35 265.6 25.35 295.7 44.88 315.5L138.4 408.9C147.4 417.1 166.5 421.6 181.5 417.1L296.7 295.7C306.2 272.4 318.5 253.3 333.3 239.8L237.2 142.2C222.4 123.2 204.1 105.3 181.5 105.3C159.1 105.3 141.3 123.2 126.6 142.2L121.4 169.3zM250.7 419.8L299.4 428.2C316.8 433.6 335.5 423.6 336.8 410.8L342.8 236.8C344.1 225 336.8 213.2 325.4 211.4L146.2 160.1C134.7 158.8 120.5 174.7 121.1 185.7L127.8 359.6C128.4 370.9 143.8 382.3 156.1 376.4L250.7 419.8z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>420</p>
                </div>
              </div>
            </div>
            <div
              className='tab-pane tabsMainBottomContent'
              role='tabpanel'
              id='tab-2'
            >
              <div className='IBMSMSMBSSDownloadsElementInsideReactions'>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement IBMSMSMBSSDEIReactionsElementActive'
                  title='Clean'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 0 512 512'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M512 165.4c0 127.9-70.05 235.3-175.3 270.1c-20.04 7.938-41.83 12.46-64.69 12.46c-64.9 0-125.2-36.51-155.7-94.47c-54.13 49.93-68.71 107-68.96 108.1C44.72 472.6 34.87 480 24.02 480c-1.844 0-3.727-.2187-5.602-.6562c-12.89-3.098-20.84-16.08-17.75-28.96c9.598-39.5 90.47-226.4 335.3-226.4C344.8 224 352 216.8 352 208S344.8 192 336 192C228.6 192 151 226.6 96.29 267.6c.1934-10.82 1.242-21.84 3.535-33.05c13.47-65.81 66.04-119 131.4-134.2c28.33-6.562 55.68-6.013 80.93-.0054c56 13.32 118.2-7.412 149.3-61.24c5.664-9.828 20.02-9.516 24.66 .8282C502.7 76.76 512 121.9 512 165.4z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>4,200</p>
                </div>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement'
                  title='Broken link'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 -64 640 640'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M185.7 120.3C242.5 75.82 324.7 79.73 376.1 131.1C420.1 175.1 430.9 239.6 406.7 293.5L438.6 318.4L534.5 222.5C566 191 566 139.1 534.5 108.5C506.7 80.63 462.7 76.1 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58C374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.732 529.8 13.25 579.8 63.24C636.3 119.7 636.3 211.3 579.8 267.7L489.3 358.2L630.8 469.1C641.2 477.3 643.1 492.4 634.9 502.8C626.7 513.2 611.6 515.1 601.2 506.9L9.196 42.89C-1.236 34.71-3.065 19.63 5.112 9.196C13.29-1.236 28.37-3.065 38.81 5.112L185.7 120.3zM238.1 161.1L353.4 251.7C359.3 225.5 351.7 197.2 331.7 177.2C306.6 152.1 269.1 147 238.1 161.1V161.1zM263 380C233.1 350.1 218.7 309.8 220.9 270L406.6 416.4C357.4 431 301.9 418.9 263 380V380zM116.6 187.9L167.2 227.8L105.5 289.5C73.99 320.1 73.99 372 105.5 403.5C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4C265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2C188.1 505.3 110.2 498.7 60.21 448.8C3.741 392.3 3.741 300.7 60.21 244.3L116.6 187.9z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>4,200</p>
                </div>
                <div
                  data-bs-toggle='tooltip'
                  data-bss-tooltip=''
                  className='IBMSMSMBSSDEIReactionsElement'
                  title='Has virus'
                >
                  <div className='IBMSMSMBSSDEIReactionsElementIconWrapper'>
                    <svg
                      xmlns='http://www.w3.org/2000/svg'
                      viewBox='0 0 512 512'
                      width='1em'
                      height='1em'
                      fill='currentColor'
                      className='IBMSMSMBSSDEIReactionsElementIcon'
                    >
                      <path d='M288 43.55C288 93.44 348.3 118.4 383.6 83.15L391.8 74.98C404.3 62.48 424.5 62.48 437 74.98C449.5 87.48 449.5 107.7 437 120.2L368.7 188.6C352.7 204.3 341.4 224.8 337.6 249.8L168.3 420.1C148.4 448.6 104.5 448.6 84.63 420.1C64.73 391.5 64.73 347.6 84.63 319.1L172.4 231.3C208.7 197 233.6 154.3 233.6 104.4C233.6 54.47 173.3 29.5 138 64.73L130.1 72.9C117.6 85.4 97.41 85.4 84.94 72.9C72.44 60.4 72.44 40.17 84.94 27.67L153.2-41.52C194.8-83.6 295.2-83.6 336.7-41.52C375.5 2.213 377.4 55.78 288 43.55zM121.4 169.3L44.88 245.8C25.35 265.6 25.35 295.7 44.88 315.5L138.4 408.9C147.4 417.1 166.5 421.6 181.5 417.1L296.7 295.7C306.2 272.4 318.5 253.3 333.3 239.8L237.2 142.2C222.4 123.2 204.1 105.3 181.5 105.3C159.1 105.3 141.3 123.2 126.6 142.2L121.4 169.3zM250.7 419.8L299.4 428.2C316.8 433.6 335.5 423.6 336.8 410.8L342.8 236.8C344.1 225 336.8 213.2 325.4 211.4L146.2 160.1C134.7 158.8 120.5 174.7 121.1 185.7L127.8 359.6C128.4 370.9 143.8 382.3 156.1 376.4L250.7 419.8z' />
                    </svg>
                  </div>
                  <p className='IBMSMSMBSSDEIReactionsElementText'>4,200</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div className='IBMSMSMBSSDownloadsElementInside IBMSMSMBSSDownloadsElementInsideAlt'>
        <p
          className='IBMSMSMBSSDownloadsElementInsideAltText'
          onClick={() => setShowAuthDetails((prev) => !prev)}
        >
          Authentication Details
        </p>
        {showAuthDetails && (
          <div className='IBMSMSMBSSDownloadsElementInsideAltTable'>
            <div className='IBMSMSMBSSDownloadsElementInsideAltTableRow'>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol IBMSMSMBSSDownloadsElementInsideAltTableRowColFirst'>
                <p>SHA-256 hash</p>
              </div>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol'>
                <p>{hash}</p>
              </div>
            </div>
            <div className='IBMSMSMBSSDownloadsElementInsideAltTableRow'>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol IBMSMSMBSSDownloadsElementInsideAltTableRowColFirst'>
                <p>Signature from</p>
              </div>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol'>
                <p>{signatureKey}</p>
              </div>
            </div>
            <div className='IBMSMSMBSSDownloadsElementInsideAltTableRow'>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol IBMSMSMBSSDownloadsElementInsideAltTableRowColFirst'>
                <p>Scan</p>
              </div>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol'>
                <p>{malwareScanLink}</p>
              </div>
            </div>
            <div className='IBMSMSMBSSDownloadsElementInsideAltTableRow'>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol IBMSMSMBSSDownloadsElementInsideAltTableRowColFirst'>
                <p>Mod Version</p>
              </div>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol'>
                <p>{modVersion}</p>
              </div>
            </div>
            <div className='IBMSMSMBSSDownloadsElementInsideAltTableRow'>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol IBMSMSMBSSDownloadsElementInsideAltTableRowColFirst'>
                <p>Note</p>
              </div>
              <div className='IBMSMSMBSSDownloadsElementInsideAltTableRowCol'>
                <p>{customNote}</p>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

const Comments = () => {
  return (
    <div className='IBMSMSMBSSCommentsWrapper'>
      <h4 className='IBMSMSMBSSTitle'>Comments (WIP)</h4>
      <div id='ArticleComments-1' className='IBMSMSMBSSComments'>
        <div className='IBMSMSMBSSCommentsCreation'>
          <div className='IBMSMSMBSSCC_Top'>
            <textarea
              id='commentBox-1'
              className='IBMSMSMBSSCC_Top_Box'
            ></textarea>
          </div>
          <div className='IBMSMSMBSSCC_Bottom'>
            <a className='IBMSMSMBSSCC_BottomButton'>
              Comment
              <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
                <div className='IBMSMSMBSSCL_CAElementLoad'></div>
              </div>
            </a>
          </div>
        </div>
        <div className='CommentsToggle'>
          <button
            className='btn btnMain CommentsToggleBtn CommentsToggleActive'
            type='button'
          >
            All Comments
          </button>
          <button className='btn btnMain CommentsToggleBtn' type='button'>
            Creator Comments
          </button>
        </div>
        <div className='IBMSMSMBSSCommentsList'>
          <div className='IBMSMSMBSSCL_Comment'>
            <div className='IBMSMSMBSSCL_CommentTop'>
              <div className='IBMSMSMBSSCL_CommentTopPPWrapper'>
                <a
                  className='IBMSMSMBSSCL_CommentTopPP'
                  href='profile.html'
                  style={{
                    background: `url('/assets/img/DEG%20Mods%20Default%20PP.png') center / cover no-repeat`
                  }}
                ></a>
              </div>
              <div className='IBMSMSMBSSCL_CommentTopDetailsWrapper'>
                <div className='IBMSMSMBSSCL_CommentTopDetails'>
                  <a className='IBMSMSMBSSCL_CTD_Name' href='profile.html'>
                    User name
                  </a>
                  <a className='IBMSMSMBSSCL_CTD_Address' href='profile.html'>
                    npub1address
                  </a>
                </div>
                <div className='IBMSMSMBSSCL_CommentActionsDetails'>
                  <a className='IBMSMSMBSSCL_CADTime' href='feed-note.html'>
                    8:45 PM
                  </a>
                  <a className='IBMSMSMBSSCL_CADDate' href='feed-note.html'>
                    02/05/2024
                  </a>
                </div>
              </div>
            </div>
            <div className='IBMSMSMBSSCL_CommentBottom'>
              <p className='IBMSMSMBSSCL_CBText'>Example user comment</p>
            </div>
            <div className='IBMSMSMBSSCL_CommentActions'>
              <div className='IBMSMSMBSSCL_CommentActionsInside'>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAEUp IBMSMSMBSSCL_CAEUpActive'>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='0 0 512 512'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    className='IBMSMSMBSSCL_CAElementIcon'
                  >
                    <path d='M0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84.02L256 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 .0003 232.4 .0003 190.9L0 190.9z'></path>
                  </svg>
                  <p className='IBMSMSMBSSCL_CAElementText'>52</p>
                  <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
                    <div className='IBMSMSMBSSCL_CAElementLoad'></div>
                  </div>
                </div>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAEDown'>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='0 0 512 512'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    className='IBMSMSMBSSCL_CAElementIcon'
                  >
                    <path d='M512 440.1C512 479.9 479.7 512 439.1 512H71.92C32.17 512 0 479.8 0 440c0-35.88 26.19-65.35 60.56-70.85C43.31 356 32 335.4 32 312C32 272.2 64.25 240 104 240h13.99C104.5 228.2 96 211.2 96 192c0-35.38 28.56-64 63.94-64h16C220.1 128 256 92.12 256 48c0-17.38-5.784-33.35-15.16-46.47C245.8 .7754 250.9 0 256 0c53 0 96 43 96 96c0 11.25-2.288 22-5.913 32h5.879C387.3 128 416 156.6 416 192c0 19.25-8.59 36.25-22.09 48H408C447.8 240 480 272.2 480 312c0 23.38-11.38 44.01-28.63 57.14C485.7 374.6 512 404.3 512 440.1z'></path>
                  </svg>
                  <p className='IBMSMSMBSSCL_CAElementText'>4</p>
                  <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
                    <div className='IBMSMSMBSSCL_CAElementLoad'></div>
                  </div>
                </div>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAERepost IBMSMSMBSSCL_CAERepostActive'>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='0 -64 640 640'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    className='IBMSMSMBSSCL_CAElementIcon'
                  >
                    <path d='M614.2 334.8C610.5 325.8 601.7 319.1 592 319.1H544V176C544 131.9 508.1 96 464 96h-128c-17.67 0-32 14.31-32 32s14.33 32 32 32h128C472.8 160 480 167.2 480 176v143.1h-48c-9.703 0-18.45 5.844-22.17 14.82s-1.656 19.29 5.203 26.16l80 80.02C499.7 445.7 505.9 448 512 448s12.28-2.344 16.97-7.031l80-80.02C615.8 354.1 617.9 343.8 614.2 334.8zM304 352h-128C167.2 352 160 344.8 160 336V192h48c9.703 0 18.45-5.844 22.17-14.82s1.656-19.29-5.203-26.16l-80-80.02C140.3 66.34 134.1 64 128 64S115.7 66.34 111 71.03l-80 80.02C24.17 157.9 22.11 168.2 25.83 177.2S38.3 192 48 192H96V336C96 380.1 131.9 416 176 416h128c17.67 0 32-14.31 32-32S321.7 352 304 352z'></path>
                  </svg>
                  <p className='IBMSMSMBSSCL_CAElementText'>6</p>
                  <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
                    <div className='IBMSMSMBSSCL_CAElementLoad'></div>
                  </div>
                </div>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAEBolt IBMSMSMBSSCL_CAEBoltActive'>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='-64 0 512 512'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    className='IBMSMSMBSSCL_CAElementIcon'
                  >
                    <path d='M240.5 224H352C365.3 224 377.3 232.3 381.1 244.7C386.6 257.2 383.1 271.3 373.1 280.1L117.1 504.1C105.8 513.9 89.27 514.7 77.19 505.9C65.1 497.1 60.7 481.1 66.59 467.4L143.5 288H31.1C18.67 288 6.733 279.7 2.044 267.3C-2.645 254.8 .8944 240.7 10.93 231.9L266.9 7.918C278.2-1.92 294.7-2.669 306.8 6.114C318.9 14.9 323.3 30.87 317.4 44.61L240.5 224z'></path>
                  </svg>
                  <p className='IBMSMSMBSSCL_CAElementText'>500K</p>
                  <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
                    <div className='IBMSMSMBSSCL_CAElementLoad'></div>
                  </div>
                </div>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAEReplies'>
                  <svg
                    xmlns='http://www.w3.org/2000/svg'
                    viewBox='0 0 512 512'
                    width='1em'
                    height='1em'
                    fill='currentColor'
                    className='IBMSMSMBSSCL_CAElementIcon'
                  >
                    <path d='M256 32C114.6 32 .0272 125.1 .0272 240c0 49.63 21.35 94.98 56.97 130.7c-12.5 50.37-54.27 95.27-54.77 95.77c-2.25 2.25-2.875 5.734-1.5 8.734C1.979 478.2 4.75 480 8 480c66.25 0 115.1-31.76 140.6-51.39C181.2 440.9 217.6 448 256 448c141.4 0 255.1-93.13 255.1-208S397.4 32 256 32z'></path>
                  </svg>
                  <p className='IBMSMSMBSSCL_CAElementText'>12</p>
                  <p className='IBMSMSMBSSCL_CAElementText'>Replies</p>
                </div>
                <div className='IBMSMSMBSSCL_CAElement IBMSMSMBSSCL_CAEReply'>
                  <p className='IBMSMSMBSSCL_CAElementText'>Reply</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

type ZapProps = {
  modDetails: ModDetails
}

const Zap = ({ modDetails }: ZapProps) => {
  const [isOpen, setIsOpen] = useState(false)
  const [hasZapped, setHasZapped] = useState(false)

  const userState = useAppSelector((state) => state.user)

  const [totalZappedAmount, setTotalZappedAmount] = useState('0')

  useDidMount(() => {
    RelayController.getInstance()
      .getTotalZapAmount(modDetails, userState.user?.pubkey as string)
      .then((res) => {
        setTotalZappedAmount(abbreviateNumber(res.accumulatedZapAmount))
        setHasZapped(res.hasZapped)
      })
      .catch((err) => {
        toast.error(err.message || err)
      })
  })

  return (
    <>
      <div
        id='reactBolt'
        className={`IBMSMSMBSS_Details_Card IBMSMSMBSS_D_CBolt ${
          hasZapped ? 'IBMSMSMBSS_D_CBActive' : ''
        }`}
        onClick={() => setIsOpen(true)}
      >
        <div className='IBMSMSMBSS_Details_CardVisual'>
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='-64 0 512 512'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSS_Details_CardVisualIcon'
          >
            <path d='M240.5 224H352C365.3 224 377.3 232.3 381.1 244.7C386.6 257.2 383.1 271.3 373.1 280.1L117.1 504.1C105.8 513.9 89.27 514.7 77.19 505.9C65.1 497.1 60.7 481.1 66.59 467.4L143.5 288H31.1C18.67 288 6.733 279.7 2.044 267.3C-2.645 254.8 .8944 240.7 10.93 231.9L266.9 7.918C278.2-1.92 294.7-2.669 306.8 6.114C318.9 14.9 323.3 30.87 317.4 44.61L240.5 224z'></path>
          </svg>
        </div>
        <p className='IBMSMSMBSS_Details_CardText'>{totalZappedAmount}</p>
        <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
          <div className='IBMSMSMBSSCL_CAElementLoad'></div>
        </div>
      </div>
      {isOpen && (
        <ZapPopUp
          title='Tip/Zap'
          receiver={modDetails.author}
          eventId={modDetails.id}
          aTag={modDetails.aTag}
          handleClose={() => setIsOpen(false)}
          lastNode={<ZapSite />}
          notCloseAfterZap
        />
      )}
    </>
  )
}

const ZapSite = () => {
  const [isLoading, setIsLoading] = useState(false)
  const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')

  const [amount, setAmount] = useState(0)

  const [paymentRequest, setPaymentRequest] = useState<PaymentRequest>()

  const userState = useAppSelector((state) => state.user)

  const handleAmountChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const unformattedValue = unformatNumber(event.target.value)
    setAmount(unformattedValue)
  }

  const handleClose = useCallback(() => {
    setPaymentRequest(undefined)
    setIsLoading(false)
  }, [])

  const handleQRExpiry = useCallback(() => {
    setPaymentRequest(undefined)
  }, [])

  const generatePaymentRequest =
    useCallback(async (): Promise<PaymentRequest | null> => {
      let userHexKey: string

      setIsLoading(true)
      setLoadingSpinnerDesc('Getting user pubkey')

      if (userState.auth && userState.user?.pubkey) {
        userHexKey = userState.user.pubkey as string
      } else {
        userHexKey = (await window.nostr?.getPublicKey()) as string
      }

      if (!userHexKey) {
        setIsLoading(false)
        toast.error('Could not get pubkey')
        return null
      }

      setLoadingSpinnerDesc('Getting admin metadata')
      const metadataController = await MetadataController.getInstance()

      const adminMetadata = await metadataController.findAdminMetadata()

      if (!adminMetadata?.lud16) {
        setIsLoading(false)
        toast.error('Lighting address (lud16) is missing in admin metadata!')
        return null
      }

      if (!adminMetadata?.pubkey) {
        setIsLoading(false)
        toast.error('pubkey is missing in admin metadata!')
        return null
      }

      const zapController = ZapController.getInstance()

      setLoadingSpinnerDesc('Creating zap request')
      return await zapController
        .getLightningPaymentRequest(
          adminMetadata.lud16,
          amount,
          adminMetadata.pubkey as string,
          userHexKey
        )
        .catch((err) => {
          toast.error(err.message || err)
          return null
        })
        .finally(() => {
          setIsLoading(false)
        })
    }, [amount, userState])

  const handleSend = useCallback(async () => {
    const pr = await generatePaymentRequest()

    if (!pr) return

    setIsLoading(true)
    setLoadingSpinnerDesc('Sending payment!')

    const zapController = ZapController.getInstance()

    if (await zapController.isWeblnProviderExists()) {
      await zapController
        .sendPayment(pr.pr)
        .then(() => {
          toast.success(`Successfully sent ${amount} sats!`)
          handleClose()
        })
        .catch((err) => {
          toast.error(err.message || err)
        })
    } else {
      toast.warn('Webln is not present. Use QR code to send zap.')
      setPaymentRequest(pr)
    }

    setIsLoading(false)
  }, [amount, handleClose, generatePaymentRequest])

  const handleGenerateQRCode = async () => {
    const pr = await generatePaymentRequest()

    if (!pr) return

    setPaymentRequest(pr)
  }

  return (
    <>
      <div className='inputLabelWrapperMain'>
        <label className='form-label labelMain'>
          Tip DEG Mods too (Optional)
        </label>
        <div className='ZapSplitUserBox'>
          <div className='ZapSplitUserBoxUser'>
            <div
              className='ZapSplitUserBoxUserPic'
              style={{
                background: `url('/assets/img/Logo%20with%20circle.png')
          center / cover no-repeat`
              }}
            ></div>
            <div className='ZapSplitUserBoxUserDetails'>
              <p className='ZapSplitUserBoxUserDetailsName'>DEG Mods</p>
              <p className='ZapSplitUserBoxUserDetailsHandle'>
                degmods@degmods.com
              </p>
            </div>
          </div>
          <p className='ZapSplitUserBoxText'>
            Help with the development, maintenance, management, and growth of
            DEG Mods.
          </p>
          <div className='inputLabelWrapperMain'>
            <label className='form-label labelMain'>Amount (Satoshis)</label>
            <input
              type='text'
              className='inputMain'
              inputMode='numeric'
              placeholder='69 or 420? or 69,420?'
              value={amount ? formatNumber(amount) : ''}
              onChange={handleAmountChange}
            />
          </div>
          <div className='pUMCB_ZapsInsideAmountOptions'>
            <ZapPresets setAmount={setAmount} />
          </div>
          <ZapButtons
            disabled={!amount}
            handleGenerateQRCode={handleGenerateQRCode}
            handleSend={handleSend}
          />
          {paymentRequest && (
            <ZapQR
              paymentRequest={paymentRequest}
              handleClose={handleClose}
              handleQRExpiry={handleQRExpiry}
            />
          )}
        </div>
      </div>
      {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
    </>
  )
}

type ReactionsProps = {
  modDetails: ModDetails
}

const Reactions = ({ modDetails }: ReactionsProps) => {
  const [isReactionInProgress, setIsReactionInProgress] = useState(false)
  const [isDataLoaded, setIsDataLoaded] = useState(false)
  const [reactionEvents, setReactionEvents] = useState<Event[]>([])

  const userState = useAppSelector((state) => state.user)

  useDidMount(() => {
    const filter: Filter = {
      kinds: [kinds.Reaction],
      '#a': [modDetails.aTag]
    }

    RelayController.getInstance()
      .fetchEventsFromUserRelays(filter, modDetails.author, UserRelaysType.Read)
      .then((events) => {
        setReactionEvents(events)
      })
      .finally(() => {
        setIsDataLoaded(true)
      })
  })

  const checkHasPositiveReaction = () => {
    return (
      !!userState.auth &&
      reactionEvents.some(
        (event) =>
          event.pubkey === userState.user?.pubkey &&
          (REACTIONS.positive.emojis.includes(event.content) ||
            REACTIONS.positive.shortCodes.includes(event.content))
      )
    )
  }

  const checkHasNegativeReaction = () => {
    return (
      !!userState.auth &&
      reactionEvents.some(
        (event) =>
          event.pubkey === userState.user?.pubkey &&
          (REACTIONS.negative.emojis.includes(event.content) ||
            REACTIONS.negative.shortCodes.includes(event.content))
      )
    )
  }

  const getPubkey = async () => {
    let hexPubkey: string

    if (userState.auth && userState.user?.pubkey) {
      hexPubkey = userState.user.pubkey as string
    } else {
      hexPubkey = (await window.nostr?.getPublicKey()) as string
    }

    if (!hexPubkey) {
      toast.error('Could not get pubkey')
      return null
    }

    return hexPubkey
  }

  const handleReaction = async (isPositive?: boolean) => {
    if (
      !isDataLoaded ||
      checkHasPositiveReaction() ||
      checkHasNegativeReaction()
    )
      return

    // Check if the voting process is already in progress
    if (isReactionInProgress) return

    // Set the flag to indicate that the voting process has started
    setIsReactionInProgress(true)

    try {
      const pubkey = await getPubkey()
      if (!pubkey) return

      const unsignedEvent: UnsignedEvent = {
        kind: kinds.Reaction,
        created_at: now(),
        content: isPositive ? '+' : '-',
        pubkey,
        tags: [
          ['e', modDetails.id],
          ['p', modDetails.author],
          ['a', modDetails.aTag]
        ]
      }

      const signedEvent = await window.nostr
        ?.signEvent(unsignedEvent)
        .then((event) => event as Event)
        .catch((err) => {
          toast.error('Failed to sign the event!')
          log(true, LogType.Error, 'Failed to sign the event!', err)
          return null
        })

      if (!signedEvent) return

      const publishedOnRelays = await RelayController.getInstance().publish(
        signedEvent as Event,
        modDetails.author,
        UserRelaysType.Read
      )

      if (publishedOnRelays.length === 0) {
        toast.error('Failed to publish reaction event on any relay')
        return
      }

      setReactionEvents((prev) => [...prev, signedEvent])
    } finally {
      setIsReactionInProgress(false)
    }
  }

  const { likesCount, disLikesCount } = useMemo(() => {
    let positiveCount = 0
    let negativeCount = 0
    reactionEvents.forEach((event) => {
      if (
        REACTIONS.positive.emojis.includes(event.content) ||
        REACTIONS.positive.shortCodes.includes(event.content)
      ) {
        positiveCount++
      } else if (
        REACTIONS.negative.emojis.includes(event.content) ||
        REACTIONS.negative.shortCodes.includes(event.content)
      ) {
        negativeCount++
      }
    })

    return {
      likesCount: abbreviateNumber(positiveCount),
      disLikesCount: abbreviateNumber(negativeCount)
    }
  }, [reactionEvents])

  const hasReactedPositively = checkHasPositiveReaction()
  const hasReactedNegatively = checkHasNegativeReaction()

  if (!isDataLoaded) return null

  return (
    <>
      <div
        className={`IBMSMSMBSS_Details_Card IBMSMSMBSS_D_CReactUp ${
          hasReactedPositively ? 'IBMSMSMBSS_D_CRUActive' : ''
        }`}
        onClick={() => handleReaction(true)}
      >
        <div className='IBMSMSMBSS_Details_CardVisual'>
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 512 512'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSS_Details_CardVisualIcon'
          >
            <path d='M0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84.02L256 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 .0003 232.4 .0003 190.9L0 190.9z'></path>
          </svg>
        </div>
        <p className='IBMSMSMBSS_Details_CardText'>{likesCount}</p>
        <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
          <div className='IBMSMSMBSSCL_CAElementLoad'></div>
        </div>
      </div>
      <div
        className={`IBMSMSMBSS_Details_Card IBMSMSMBSS_D_CReactDown ${
          hasReactedNegatively ? 'IBMSMSMBSS_D_CRDActive' : ''
        }`}
        onClick={() => handleReaction()}
      >
        <div className='IBMSMSMBSS_Details_CardVisual'>
          <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 512 512'
            width='1em'
            height='1em'
            fill='currentColor'
            className='IBMSMSMBSS_Details_CardVisualIcon'
          >
            <path d='M512 440.1C512 479.9 479.7 512 439.1 512H71.92C32.17 512 0 479.8 0 440c0-35.88 26.19-65.35 60.56-70.85C43.31 356 32 335.4 32 312C32 272.2 64.25 240 104 240h13.99C104.5 228.2 96 211.2 96 192c0-35.38 28.56-64 63.94-64h16C220.1 128 256 92.12 256 48c0-17.38-5.784-33.35-15.16-46.47C245.8 .7754 250.9 0 256 0c53 0 96 43 96 96c0 11.25-2.288 22-5.913 32h5.879C387.3 128 416 156.6 416 192c0 19.25-8.59 36.25-22.09 48H408C447.8 240 480 272.2 480 312c0 23.38-11.38 44.01-28.63 57.14C485.7 374.6 512 404.3 512 440.1z'></path>
          </svg>
        </div>
        <p className='IBMSMSMBSS_Details_CardText'>{disLikesCount}</p>
        <div className='IBMSMSMBSSCL_CAElementLoadWrapper'>
          <div className='IBMSMSMBSSCL_CAElementLoad'></div>
        </div>
      </div>
    </>
  )
}
