import { HeaderEditor } from '@komi-app/creator-ui'
import { Col, Row } from 'antd'
import { Text } from 'components/Typography'
import { useAutoSave } from 'hooks/useAutoSave'
import { useEffect, useMemo, useState } from 'react'
import { Area } from 'react-easy-crop/types'
import {
  selectLocalizationSelected,
  selectTalentProfile,
  selectTalentProfileModules
} from 'redux/User/selector'
import { useTypedSelector } from 'redux/rootReducer'
import { useProfilePhoto } from '../ProfilePhoto/ProfilePhoto'
import { useDispatch } from 'react-redux'
import { setTalentProfileAction } from 'redux/User/actions'
import { loadFileFromURL } from 'utils/file'

const useHeaderImage = () => {
  const { uploadAndUpdateProfileImage, isAutoSaveSuccess } = useProfilePhoto()
  const { onSaveProfile } = useAutoSave()
  const localizationSelected = useTypedSelector(selectLocalizationSelected)
  const talentProfile = useTypedSelector(selectTalentProfile)
  const modules = useTypedSelector(selectTalentProfileModules)
  const dispatch = useDispatch()

  const [fileName, setFileName] = useState<string | undefined>()
  const [headerImage, setHeaderImage] = useState<File | undefined>(undefined)
  const [uploading, setUploading] = useState(false)
  const [uploadFailed, setUploadFailed] = useState(false)

  const resolvedFileName =
    fileName || talentProfile?.avatarFilename || 'header.jpg'

  useEffect(() => {
    const fetchImage = async () => {
      if (talentProfile?.avatar) {
        if (headerImage) {
          setUploading(true)
          setHeaderImage(new File([], resolvedFileName))
        }

        const file = await loadFileFromURL(
          talentProfile.avatar,
          resolvedFileName
        )
        setHeaderImage(file)
        setUploading(false)
      }
    }
    fetchImage()
  }, [talentProfile?.avatar, talentProfile?.avatarFilename])

  const handleImageSelect = (file: File | undefined) => {
    setHeaderImage(file)
    setUploadFailed(false)
    setUploading(false)

    if (file) {
      setFileName(file.name)
    } else {
      // Triggered when an image has been removed from the picker, remove the image from backend
      saveImage(null)
    }
  }

  const handleCropComplete = async (
    croppedArea: Area,
    croppedAreaPixels: Area
  ) => {
    if (!headerImage) {
      return
    }

    const aspectRatio =
      // Round aspect ratio to remove any floating point precision errors
      Math.round((croppedAreaPixels.height / croppedAreaPixels.width) * 100) /
      100

    setUploading(true)

    try {
      const avatarUrl = await uploadAndUpdateProfileImage(
        headerImage,
        croppedAreaPixels
      )

      if (typeof avatarUrl !== 'string') {
        throw new Error('Failed to upload image')
      }

      saveImage(avatarUrl, aspectRatio)
    } catch (e) {
      setUploadFailed(true)
      setUploading(false)
    }
  }

  const saveImage = (avatarUrl: string | null, avatarRatio = 1.25) => {
    dispatch(
      setTalentProfileAction({
        avatar: avatarUrl,
        avatarRatio,
        avatarFilename: fileName
      })
    )

    onSaveProfile({
      newTalent: {
        ...talentProfile,
        avatar: avatarUrl,
        avatarRatio,
        avatarFilename: fileName
      },
      newModules: modules,
      localizationId: localizationSelected?.id,
      callback: () => {
        setUploading(false)
      },
      errorCallback: () => {
        setUploading(false)
      }
    })
  }

  const error = useMemo(() => {
    if (talentProfile && !talentProfile?.avatar && isAutoSaveSuccess) {
      return 'Upload an image'
    }

    if (uploadFailed) {
      return 'Failed to upload image'
    }
  }, [talentProfile, isAutoSaveSuccess])

  return {
    headerImage,
    handleImageSelect,
    handleCropComplete,
    uploading,
    error
  }
}

const ProfilePhotoV2: React.FC = () => {
  const {
    headerImage,
    handleImageSelect,
    handleCropComplete,
    uploading,
    error
  } = useHeaderImage()

  return (
    <div
      id="profile-photo"
      className="profile-photo"
      data-testid="profile-photo__wrapper"
    >
      <Row
        className="m__t--16 m__b--20 m__l--16"
        align="middle"
        justify="space-between"
      >
        <Col>
          <Text preset="semibold18" data-testid="profile-photo__title">
            Image
          </Text>
        </Col>
      </Row>
      <div>
        <Row className="m--16">
          <Col className="full-width">
            <HeaderEditor
              imageFile={headerImage}
              onImageChange={handleImageSelect}
              onCropComplete={handleCropComplete}
              uploading={uploading}
              error={error}
            />
          </Col>
        </Row>
      </div>
    </div>
  )
}

export default ProfilePhotoV2
