import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import ArraySearch from 'arraysearch'
import React, { useEffect, useMemo, useState } from 'react'
import { OverlayTrigger, Popover } from 'react-bootstrap'
import RangeSlider from 'react-bootstrap-range-slider'
import {
  FaChevronCircleDown,
  FaChevronCircleUp,
  FaThumbsDown,
  FaThumbsUp,
  FaTimesCircle,
} from 'react-icons/fa'
import { NotificationManager } from 'react-notifications'

import RefLink from '../../../main/RefLink'
import { AccountService } from '../../services/account.service'

const Finder = ArraySearch.Finder

export function VoteWidget(props: any) {
  const reflink = useMemo(() => {
    return RefLink.parse(props.reflink)
  }, [props.reflink])
  const author = useMemo(() => {
    return reflink.root
  }, [reflink])

  const permlink = useMemo(() => {
    return reflink.permlink
  }, [])

  const [downvoters, setDownvoters] = useState([])
  const [upvoters, setUpvoters] = useState([])
  const [upvotePct, setUpvotePct] = useState(0)
  const [downvotePct, setDownvotePct] = useState(0)
  const [showModal, setShowModal] = useState(false)
  const [showDModal, setShowDModal] = useState(false)

  const setVoters = () => {
    void AccountService.permalinkToPostInfo(props.reflink).then((post) => {
      const votes = post.active_votes.sort((e, i) => {
        return i.rshares - e.rshares
      })

      setDownvoters(votes.filter((vote) => vote.percent < 0))
      setUpvoters(votes.filter((vote) => vote.percent >= 0).reverse())
    })
  }

  useEffect(() => {
    setVoters()
  }, [])

  const handleClose = () => {
    setShowModal(false)
  }

  const handleShow = () => {
    setShowModal(true)
  }

  const handleDClose = () => {
    setShowDModal(false)
  }
  const handleDShow = () => {
    setShowDModal(true)
  }

  const handleVote = async () => {
    const modalState = showModal
    if (modalState === false) {
      handleShow()
    } else {
      const profileID = localStorage.getItem('SNProfileID')

      if (profileID) {
        try {
          const profile = (await AccountService.getAccount(profileID)) as any
          const theWifObj = Finder.one.in(profile.keyring).with({
            privateKeys: {},
          })
          const wif = theWifObj.privateKeys.posting_key // posting key
          const voter = profile.nickname // voting account
          const weight = upvotePct // vote weight in percentage(between 1 - 100)
          const accountType = 'hive'

          const voteOp = {
            wif,
            voter,
            author,
            permlink,
            weight,
            accountType,
            profileID,
          }

          await AccountService.voteHandler(voteOp)
          NotificationManager.success('Vote cast')
          const voterFmt = `@${voter}`
          setUpvoters([...upvoters, voterFmt])
          setShowModal(false)
          upvoters.push()
        } catch (error) {
          NotificationManager.success('There was an error completing this operation')
        }
      } else {
        NotificationManager.success('You need to be logged in to perform this operation')
      }
    }
  }

  const handleDownVote = async () => {
    const modalState = showDModal
    if (modalState === false) {
      handleDShow()
    } else {
      const profileID = localStorage.getItem('SNProfileID')

      if (profileID) {
        try {
          const profile = (await AccountService.getAccount(profileID)) as any
          const theWifObj = Finder.one.in(profile.keyring).with({
            privateKeys: {},
          })
          const wif = theWifObj.privateKeys.posting_key // posting key
          const voter = profile.nickname // voting account
          const weight = downvotePct * -1 // vote weight in percentage(between 1 - 100)
          const accountType = 'hive'

          const voteOp = {
            wif,
            voter,
            author,
            permlink,
            weight,
            accountType,
            profileID,
          }

          await AccountService.voteHandler(voteOp)

          NotificationManager.success('Vote casted, page will reload momentarily')
          setShowDModal(false)
        } catch (error) {
          NotificationManager.success('There was an error completing this operation')
        }
      } else {
        NotificationManager.success('You need to be logged in to perform this operation')
      }
    }
  }

  return (
    <>
      <span className="ml-2 p-0">
        <span style={{ cursor: 'pointer' }}>
          <FaThumbsUp
            className="text-secondary"
            onClick={() => {
              void handleVote()
            }}
          />
        </span>
        {showModal && (
          <span>
            <RangeSlider
              value={upvotePct}
              onChange={(evt) => {
                setUpvotePct(evt.target.value)
              }}
            />
            <FontAwesomeIcon
              size={'lg'}
              icon={(<FaChevronCircleUp style={{ cursor: 'pointer' }} />) as any}
            />
            <FontAwesomeIcon
              size={'lg'}
              icon={
                (<FaTimesCircle style={{ cursor: 'pointer' }} className="text-danger" />) as any
              }
            />
          </span>
        )}
      </span>
      <OverlayTrigger
        rootClose
        trigger="click"
        placement="bottom"
        overlay={
          <Popover id="popover-basic">
            <Popover.Title as="h3">
              Upvotes for @{author}/{permlink}
            </Popover.Title>
            <Popover.Content>
              {upvoters.slice(0, 10).map((e, index) => {
                return (
                  <div key={index}>
                    @{e.voter}: {e.percent / 100}%<br />
                  </div>
                )
              })}
              <a
                onClick={() => {
                  //todo: open modal
                }}
              >
                See more...
              </a>
            </Popover.Content>
          </Popover>
        }
      >
        <b style={{ cursor: 'pointer' }}>{upvoters.length}</b>
      </OverlayTrigger>

      <span className="ml-2 p-0">
        <span style={{ cursor: 'pointer' }}>
          <FaThumbsDown
            className="text-secondary"
            onClick={() => {
              void handleDownVote()
            }}
          />
        </span>
        {showDModal && (
          <span>
            <RangeSlider
              value={downvotePct}
              onChange={(changeEvent) => {
                setDownvotePct(changeEvent.target.value)
              }}
            />
            <FontAwesomeIcon
              size={'lg'}
              icon={(<FaChevronCircleDown style={{ cursor: 'pointer' }} />) as any}
            />
            <FontAwesomeIcon
              size={'lg'}
              icon={
                (<FaTimesCircle style={{ cursor: 'pointer' }} className="text-danger" />) as any
              }
            />
          </span>
        )}
      </span>
      <OverlayTrigger
        rootClose
        trigger="click"
        placement="bottom"
        overlay={
          <Popover id="basic-popover">
            <Popover.Title as="h3">
              Downvotes for @{author}/{permlink}
            </Popover.Title>
            <Popover.Content>
              {downvoters.slice(0, 10).map((item, index) => {
                return (
                  <div key={index}>
                    @{item.voter}: {item.percent / 100}%<br />
                  </div>
                )
              })}
              <a
                onClick={() => {
                  //todo: open modal
                }}
              >
                See more...
              </a>
            </Popover.Content>
          </Popover>
        }
      >
        <b style={{ cursor: 'pointer' }}>{downvoters.length}</b>
      </OverlayTrigger>
    </>
  )
}