import { Divider, Tooltip } from '@mui/material'
import {
  formatTimestamp,
  fromUnixTimestamp,
  hexToNpub,
  npubToHex,
  SigitStatus,
  SignStatus
} from '../../utils'
import { useSigitMeta } from '../../hooks/useSigitMeta'
import { UserAvatarGroup } from '../UserAvatarGroup'

import styles from './style.module.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
  faCalendar,
  faCalendarCheck,
  faCalendarPlus,
  faCheck,
  faClock,
  faEye,
  faServer,
  faFile,
  faFileCircleExclamation
} from '@fortawesome/free-solid-svg-icons'
import { getExtensionIconLabel } from '../getExtensionIconLabel'
import { useAppSelector } from '../../hooks/store'
import { DisplaySigner } from '../DisplaySigner'
import { Meta, OpenTimestamp } from '../../types'
import { extractFileExtensions } from '../../utils/file'
import { UserAvatar } from '../UserAvatar'

interface UsersDetailsProps {
  meta: Meta
}

export const UsersDetails = ({ meta }: UsersDetailsProps) => {
  const {
    submittedBy,
    exportedBy,
    signers,
    viewers,
    fileHashes,
    zipUrls,
    signersStatus,
    createdAt,
    completedAt,
    parsedSignatureEvents,
    signedStatus,
    isValid,
    id,
    timestamps
  } = useSigitMeta(meta)
  const { usersPubkey } = useAppSelector((state) => state.auth)
  const userCanSign =
    typeof usersPubkey !== 'undefined' &&
    signers.includes(hexToNpub(usersPubkey))

  const { extensions, isSame } = extractFileExtensions(Object.keys(fileHashes))

  const isTimestampVerified = (
    timestamps: OpenTimestamp[],
    nostrId: string
  ): boolean => {
    const matched = timestamps.find((t) => t.nostrId === nostrId)
    return !!(matched && matched.verification)
  }

  const getOpenTimestampsInfo = (
    timestamps: OpenTimestamp[],
    nostrId: string
  ) => {
    if (isTimestampVerified(timestamps, nostrId)) {
      return <FontAwesomeIcon className={styles.ticket} icon={faCheck} />
    } else {
      return <FontAwesomeIcon className={styles.ticket} icon={faClock} />
    }
  }

  const getCompletedOpenTimestampsInfo = (timestamp: OpenTimestamp) => {
    if (timestamp.verification) {
      return <FontAwesomeIcon className={styles.ticket} icon={faCheck} />
    } else {
      return <FontAwesomeIcon className={styles.ticket} icon={faClock} />
    }
  }

  const getTimestampTooltipTitle = (label: string, isVerified: boolean) => {
    return `${label} / Open Timestamp ${isVerified ? 'Verified' : 'Pending'}`
  }

  const isUserSignatureTimestampVerified = () => {
    if (
      userCanSign &&
      hexToNpub(usersPubkey) in parsedSignatureEvents &&
      timestamps &&
      timestamps.length > 0
    ) {
      const nostrId = parsedSignatureEvents[hexToNpub(usersPubkey)].id
      return isTimestampVerified(timestamps, nostrId)
    }
    return false
  }

  /**
   * Used to parse the base URL from Blossom server full path
   */
  const getBaseUrl = (url: string): string => {
    try {
      const parsedUrl = new URL(url)
      return `${parsedUrl.protocol}//${parsedUrl.host}`
    } catch (error) {
      return 'Invalid URL'
    }
  }

  return submittedBy ? (
    <div className={styles.container}>
      <div className={styles.section}>
        <p>Signers</p>
        <div className={styles.users}>
          {submittedBy && (
            <DisplaySigner
              status={isValid ? SignStatus.Signed : SignStatus.Invalid}
              pubkey={submittedBy}
            />
          )}

          {submittedBy && signers.length ? (
            <Divider orientation="vertical" flexItem />
          ) : null}

          <UserAvatarGroup max={20}>
            {signers.map((signer) => {
              const pubkey = npubToHex(signer)!
              return (
                <DisplaySigner
                  key={pubkey}
                  status={signersStatus[signer]}
                  pubkey={pubkey}
                />
              )
            })}
          </UserAvatarGroup>
        </div>

        {viewers.length > 0 && (
          <>
            <p>Viewers</p>
            <div className={styles.users}>
              <UserAvatarGroup max={20}>
                {viewers.map((signer) => {
                  const pubkey = npubToHex(signer)!

                  return (
                    <DisplaySigner
                      key={pubkey}
                      status={SignStatus.Viewer}
                      pubkey={pubkey}
                    />
                  )
                })}
              </UserAvatarGroup>
            </div>
          </>
        )}

        {exportedBy && (
          <>
            <p>Exported By</p>
            <div className={styles.users}>
              <UserAvatar pubkey={exportedBy} />
            </div>
          </>
        )}
      </div>
      <div className={styles.section}>
        <p>Details</p>

        <Tooltip
          title={getTimestampTooltipTitle(
            'Publication date',
            !!(timestamps && id && isTimestampVerified(timestamps, id))
          )}
          placement="top"
          arrow
          disableInteractive
        >
          <span className={styles.detailsItem}>
            <FontAwesomeIcon icon={faCalendarPlus} />{' '}
            {createdAt ? formatTimestamp(createdAt) : <>&mdash;</>}{' '}
            {timestamps &&
              timestamps.length > 0 &&
              id &&
              getOpenTimestampsInfo(timestamps, id)}
          </span>
        </Tooltip>

        <Tooltip
          title={getTimestampTooltipTitle(
            'Completion date',
            !!(
              signedStatus === SigitStatus.Complete &&
              completedAt &&
              timestamps &&
              timestamps.length > 0 &&
              timestamps[timestamps.length - 1].verification
            )
          )}
          placement="top"
          arrow
          disableInteractive
        >
          <span className={styles.detailsItem}>
            <FontAwesomeIcon icon={faCalendarCheck} />{' '}
            {completedAt ? formatTimestamp(completedAt) : <>&mdash;</>}
            {signedStatus === SigitStatus.Complete &&
              completedAt &&
              timestamps &&
              timestamps.length > 0 && (
                <span className={styles.ticket}>
                  {getCompletedOpenTimestampsInfo(
                    timestamps[timestamps.length - 1]
                  )}
                </span>
              )}
          </span>
        </Tooltip>

        {/* User signed date */}
        {userCanSign ? (
          <Tooltip
            title={getTimestampTooltipTitle(
              'Your signature date',
              isUserSignatureTimestampVerified()
            )}
            placement="top"
            arrow
            disableInteractive
          >
            <span className={styles.detailsItem}>
              <FontAwesomeIcon icon={faCalendar} />{' '}
              {hexToNpub(usersPubkey) in parsedSignatureEvents ? (
                parsedSignatureEvents[hexToNpub(usersPubkey)].created_at ? (
                  formatTimestamp(
                    fromUnixTimestamp(
                      parsedSignatureEvents[hexToNpub(usersPubkey)].created_at
                    )
                  )
                ) : (
                  <>&mdash;</>
                )
              ) : (
                <>&mdash;</>
              )}
              {hexToNpub(usersPubkey) in parsedSignatureEvents &&
                timestamps &&
                timestamps.length > 0 && (
                  <span className={styles.ticket}>
                    {getOpenTimestampsInfo(
                      timestamps,
                      parsedSignatureEvents[hexToNpub(usersPubkey)].id
                    )}
                  </span>
                )}
            </span>
          </Tooltip>
        ) : null}
        <span className={styles.detailsItem}>
          <FontAwesomeIcon icon={faEye} /> {signedStatus}
        </span>
        {extensions.length > 0 ? (
          <span className={styles.detailsItem}>
            {!isSame ? (
              <>
                <FontAwesomeIcon icon={faFile} /> Multiple File Types
              </>
            ) : (
              getExtensionIconLabel(extensions[0])
            )}
          </span>
        ) : (
          <>
            <FontAwesomeIcon icon={faFileCircleExclamation} /> &mdash;
          </>
        )}
        <span className={styles.detailsItem}>
          <FontAwesomeIcon icon={faEye} /> {signedStatus}
        </span>
      </div>

      <div className={styles.section}>
        <p>File Servers</p>

        {zipUrls.map((url) => (
          <span className={styles.detailsItem} key={url}>
            <FontAwesomeIcon icon={faServer} /> {getBaseUrl(url)}
          </span>
        ))}
      </div>
    </div>
  ) : undefined
}