import { useEffect, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { toast } from 'react-toastify'

import ContentCopyIcon from '@mui/icons-material/ContentCopy'
import EditIcon from '@mui/icons-material/Edit'
import { Box, IconButton, SxProps, Theme, Typography } from '@mui/material'

import { nip19 } from 'nostr-tools'

import { Container } from '../../components/Container'
import { Footer } from '../../components/Footer/Footer'
import { LoadingSpinner } from '../../components/LoadingSpinner'
import { useAppSelector } from '../../hooks/store'

import { getProfileSettingsRoute } from '../../routes'

import {
  getProfileUsername,
  getRoboHashPicture,
  hexToNpub,
  shorten
} from '../../utils'

import { NDKUserProfile } from '@nostr-dev-kit/ndk'
import { useNDKContext } from '../../hooks'
import styles from './style.module.scss'

export const ProfilePage = () => {
  const navigate = useNavigate()

  const { npub } = useParams()
  const { ndk, findMetadata } = useNDKContext()

  const [pubkey, setPubkey] = useState<string>()
  const [userProfile, setUserProfile] = useState<NDKUserProfile | null>(null)

  const userRobotImage = useAppSelector((state) => state.user.robotImage)
  const currentUserProfile = useAppSelector((state) => state.user.profile)
  const { usersPubkey } = useAppSelector((state) => state.auth)

  const [isUsersOwnProfile, setIsUsersOwnProfile] = useState(false)

  const [isLoading, setIsLoading] = useState(true)
  const [loadingSpinnerDesc] = useState('Fetching metadata')

  useEffect(() => {
    if (npub) {
      try {
        const hexPubkey = nip19.decode(npub).data as string
        setPubkey(hexPubkey)

        if (hexPubkey === usersPubkey) setIsUsersOwnProfile(true)
      } catch (error) {
        toast.error('Error occurred in decoding npub' + error)
      }
    }
  }, [npub, usersPubkey])

  useEffect(() => {
    if (isUsersOwnProfile && currentUserProfile) {
      setUserProfile(currentUserProfile)
      setIsLoading(false)

      return
    }

    if (pubkey) {
      findMetadata(pubkey)
        .then((profile) => {
          setUserProfile(profile)
        })
        .catch((err) => {
          toast.error(err)
        })
        .finally(() => {
          setIsLoading(false)
        })
    }
  }, [ndk, isUsersOwnProfile, currentUserProfile, pubkey, findMetadata])

  /**
   * Rendering text with button which copies the provided text
   * @param text to be visible
   * @param sx props (MUI) to customize style
   * @returns HTML rendered text
   */
  const textElementWithCopyIcon = (
    text: string,
    sx?: SxProps<Theme>,
    shortenOffset?: number
  ) => {
    const onClick = () => {
      navigator.clipboard.writeText(text)

      toast.success('Copied to clipboard', {
        autoClose: 1000,
        hideProgressBar: true
      })
    }

    return (
      <Typography variant="caption" sx={sx} className={styles.npubNipItem}>
        <span onClick={onClick}>{shorten(text, shortenOffset)}</span>
        <ContentCopyIcon onClick={onClick} className={styles.copyIcon} />
      </Typography>
    )
  }

  /**
   * Handles the logic for Image URL.
   * If no picture in kind 0 found - use robohash avatar
   *
   * @returns robohash image url
   */
  const getProfileImage = (profile: NDKUserProfile | null) => {
    if (!profile) return getRoboHashPicture(npub)

    if (!isUsersOwnProfile) {
      return profile.image || getRoboHashPicture(npub!)
    }

    // userRobotImage is used only when visiting own profile
    // while kind 0 picture is not set
    return profile.image || userRobotImage || getRoboHashPicture(npub!)
  }

  const profileName =
    pubkey && getProfileUsername(pubkey, userProfile || undefined)

  return (
    <>
      {isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
      {pubkey && (
        <Container className={styles.container}>
          <Box
            className={`${styles.banner} ${!userProfile || !userProfile.banner ? styles.noImage : ''}`}
          >
            {userProfile && userProfile.banner ? (
              <img
                src={userProfile.banner}
                alt={`banner image for ${profileName}`}
              />
            ) : (
              ''
            )}
          </Box>

          <Box className={styles.belowBanner}>
            <Box className={styles.upper}>
              <Box className={styles.left}>
                <div
                  style={{
                    borderWidth: '2px',
                    borderStyle: pubkey ? 'solid' : 'none',
                    borderColor: `#${pubkey?.substring(0, 6)}`
                  }}
                  className={styles.imageWrapper}
                >
                  <img
                    className={styles['image-placeholder']}
                    src={getProfileImage(userProfile)}
                    alt={profileName}
                  />
                </div>
              </Box>

              <Box className={styles.right}>
                {isUsersOwnProfile && (
                  <IconButton
                    onClick={() => navigate(getProfileSettingsRoute(pubkey))}
                  >
                    <EditIcon />
                  </IconButton>
                )}
              </Box>
            </Box>
            <Box className={styles.head}>
              <Box sx={{ lineHeight: 1 }} className={styles.npubNip}>
                <Box
                  sx={{
                    display: 'flex'
                  }}
                >
                  <Typography
                    sx={{ margin: '5px 0 5px 0' }}
                    variant="h6"
                    className={styles.bold}
                  >
                    {profileName}
                  </Typography>
                </Box>
                <Box>
                  {textElementWithCopyIcon(
                    hexToNpub(pubkey) || '',
                    undefined,
                    15
                  )}
                </Box>
                <Box>
                  {userProfile?.nip05 &&
                    textElementWithCopyIcon(userProfile.nip05, undefined, 15)}
                </Box>
                <Box>
                  {userProfile?.lud16 &&
                    textElementWithCopyIcon(userProfile.lud16, undefined, 15)}
                </Box>
              </Box>

              <Box>
                {userProfile?.website && (
                  <Typography
                    sx={{ marginTop: '10px' }}
                    variant="caption"
                    component={Link}
                    to={userProfile.website}
                    target="_blank"
                    className={`${styles.website} ${styles.link} ${styles.captionWrapper}`}
                  >
                    {userProfile.website}
                  </Typography>
                )}
              </Box>
            </Box>
            <Box>
              {userProfile?.about && (
                <Typography mt={1} className={styles.about}>
                  {userProfile.about}
                </Typography>
              )}
            </Box>
          </Box>
        </Container>
      )}
      <Footer />
    </>
  )
}
