import { Icon, Copy, Link } from '@linagora/twake-icons'
import PropTypes from 'prop-types'
import React, { useReducer, useState } from 'react'

import { useClient } from 'cozy-client'
import Button from 'cozy-ui/transpiled/react/Buttons'
import { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
import { useI18n } from 'twake-i18n'

import { ShareRestrictionModal } from './ShareRestrictionModal/ShareRestrictionModal'
import {
  copyToClipboard,
  createSharingLink
} from './ShareRestrictionModal/helpers'
import { useSharingContext } from '../hooks/useSharingContext'

const ShareByLink = ({
  link,
  document,
  documentType,
  showGenerateLinkButton = false,
  autoOpenShareRestriction = false
}) => {
  const { t } = useI18n()
  const { isMobile } = useBreakpoints()
  const { showAlert } = useAlert()
  const client = useClient()
  const { shareByLink, getOwner, getSharingById } = useSharingContext()
  const [isGenerating, setIsGenerating] = useState(false)

  const canShare = typeof navigator?.share === 'function'
  const showGenerateButton = showGenerateLinkButton && !link
  const showCopyAndSendButtons = !showGenerateButton && isMobile && canShare
  const showOnlyCopyButton = !showGenerateButton && (!isMobile || !canShare)

  const [isEditDialogOpen, toggleEditDialogOpen] = useReducer(
    state => !state,
    false
  )

  const showGenericError = () => {
    showAlert({
      message: t(`${documentType}.share.error.generic`),
      severity: 'error',
      variant: 'filled'
    })
  }

  const handleGenerateLink = async () => {
    setIsGenerating(true)
    try {
      return await createSharingLink({
        client,
        file: document,
        documentType,
        shareByLink,
        getOwner,
        getSharingById,
        t,
        showAlert,
        password: '',
        ttl: undefined,
        editingRights: 'readOnly'
      })
    } catch (_error) {
      return null
    } finally {
      setIsGenerating(false)
    }
  }

  const generateLinkAndCopyLinkToClipboard = async () => {
    if (link) {
      await copyToClipboard(link, { t, showAlert })
      return
    }
    // Safari: the clipboard API must be invoked synchronously within the
    // click handler, so we pass the pending link to `copyToClipboard`.
    // The resolved URL is captured here so we can branch on success after
    // the copy has completed, without re-awaiting the promise.
    let generatedLink = null
    await copyToClipboard(
      handleGenerateLink().then(generated => {
        generatedLink = generated
        if (!generated) throw new Error('link-generation-failed')
        return generated
      }),
      { t, showAlert }
    )
    if (!generatedLink) {
      showGenericError()
      return
    }
    if (autoOpenShareRestriction) {
      toggleEditDialogOpen()
    }
  }

  const generateLinkSilently = async () => {
    const generated = await handleGenerateLink()
    if (!generated) {
      showGenericError()
      return
    }
    if (autoOpenShareRestriction) {
      toggleEditDialogOpen()
    }
  }

  const shareLink = async () => {
    let linkToShare = link
    if (!linkToShare) {
      linkToShare = await handleGenerateLink()
    }
    if (!linkToShare) {
      showGenericError()
      return
    }

    try {
      const shareData = {
        text: t(`${documentType}.share.shareByLink.shareDescription`, {
          name: document.name || ''
        }),
        url: linkToShare
      }
      await navigator.share(shareData)
    } catch (error) {
      // Don't show error when user cancels the share dialog
      if (error.name !== 'AbortError') {
        showGenericError()
      }
    }
  }

  return (
    <div className="u-w-100">
      {showCopyAndSendButtons && (
        <>
          <Button
            label={t(`${documentType}.share.shareByLink.send`)}
            variant="secondary"
            size="medium"
            startIcon={<Icon icon={Link} />}
            onClick={shareLink}
            busy={isGenerating}
          />
          <Button
            label={<Icon icon={Copy} />}
            variant="secondary"
            size="medium"
            onClick={generateLinkAndCopyLinkToClipboard}
            disabled={isGenerating}
          />
        </>
      )}
      {showOnlyCopyButton && (
        <Button
          label={t(`${documentType}.share.shareByLink.copy`)}
          variant="secondary"
          size="medium"
          startIcon={<Icon icon={Link} />}
          onClick={generateLinkAndCopyLinkToClipboard}
          busy={isGenerating}
        />
      )}
      {showGenerateButton && (
        <Button
          label={t(`${documentType}.share.shareByLink.create`)}
          variant="secondary"
          size="medium"
          startIcon={<Icon icon={Link} />}
          onClick={generateLinkSilently}
          busy={isGenerating}
        />
      )}
      {isEditDialogOpen && (
        <ShareRestrictionModal file={document} onClose={toggleEditDialogOpen} />
      )}
    </div>
  )
}

ShareByLink.propTypes = {
  link: PropTypes.string,
  document: PropTypes.object.isRequired,
  documentType: PropTypes.string.isRequired,
  showGenerateLinkButton: PropTypes.bool,
  autoOpenShareRestriction: PropTypes.bool
}

export default ShareByLink
