import { useEffect, useRef, useState } from 'react'

import { AvatarCropModal } from '../AvatarCropModal/AvatarCropModal'
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { Camera, ImagePlus, RotateCcw } from 'lucide-react'
import { AvatarCameraModal } from '../AvatarCameraModal/AvatarCameraModal'
import {
  MODAL_EXIT_DURATION_MS,
  useDeferredModalPayload,
} from '../../../../shared/lib/lazyMount'

import './AvatarUpload.scss'

type AvatarUploadProps = {
  avatarUrl?: string
  allowCamera?: boolean
  initials: string
  disabled?: boolean
  hasSelectedFile?: boolean
  title?: string
  description?: string
  chooseText?: string
  replaceText?: string
  alt?: string
  onChange: (file: File, previewUrl: string) => void
  onReset: () => void
}

export function AvatarUpload({
  avatarUrl = '',
  allowCamera = true,
  initials,
  disabled = false,
  hasSelectedFile = false,
  chooseText = 'Выбрать фото',
  replaceText = 'Заменить фото',
  alt = 'Изображение',
  onChange,
  onReset,
}: AvatarUploadProps) {
  const inputRef = useRef<HTMLInputElement | null>(null)
  const cropImageSrcRef = useRef('')

  const [cropImageSrc, setCropImageSrc] = useState('')
  const renderCropImageSrc = useDeferredModalPayload(cropImageSrc || null)
  const [isCameraOpen, setIsCameraOpen] =
    useState(false)

  const [isMenuOpen, setIsMenuOpen] =
    useState(false)

  useEffect(() => {
    cropImageSrcRef.current = cropImageSrc
  }, [cropImageSrc])

  useEffect(() => {
    return () => {
      if (cropImageSrcRef.current) {
        URL.revokeObjectURL(cropImageSrcRef.current)
      }
    }
  }, [])

  function revokeCropImageLater(src: string) {
    window.setTimeout(() => {
      URL.revokeObjectURL(src)
    }, MODAL_EXIT_DURATION_MS)
  }

  function handleCameraCapture(file: File) {
    handleFileChange(file)
    setIsCameraOpen(false)
  }

  function handleFileChange(file?: File) {
    if (!file || disabled) return

    if (cropImageSrc) {
      URL.revokeObjectURL(cropImageSrc)
    }

    setCropImageSrc(URL.createObjectURL(file))
  }

  function handleCancelCrop() {
    if (cropImageSrc) {
      revokeCropImageLater(cropImageSrc)
    }

    setCropImageSrc('')
  }

  function handleConfirmCrop(file: File, previewUrl: string) {
    if (cropImageSrc) {
      revokeCropImageLater(cropImageSrc)
    }

    setCropImageSrc('')
    onChange(file, previewUrl)
  }

  return (
    <div className="avatar-upload">
      <div className={`avatar-upload__preview ${avatarUrl ? 'transparent-backdrop' : ''}`}>
        {avatarUrl ? (
          <img src={avatarUrl} alt={alt} />
        ) : (
          <span>{initials}</span>
        )}

        <DropdownMenu.Root
          open={isMenuOpen}
          onOpenChange={setIsMenuOpen}
        >
          <DropdownMenu.Trigger asChild>
            <button
              className="avatar-upload__camera"
              type="button"
              disabled={disabled}
              aria-label="Выбрать фото"
            >
              <Camera size={18} />
            </button>
          </DropdownMenu.Trigger>

          <DropdownMenu.Portal>
            <DropdownMenu.Content
              className="avatar-upload__menu"
              side="right"
              align="start"
              sideOffset={8}
            >
              <DropdownMenu.Item
                className="avatar-upload__menu-item"
                onSelect={(event) => {
                  event.preventDefault()

                  setIsMenuOpen(false)

                  setTimeout(() => {
                    inputRef.current?.click()
                  }, 0)
                }}
              >
                <ImagePlus size={16} />
                <span>Выбрать изображение</span>
              </DropdownMenu.Item>

              {allowCamera && (
                <DropdownMenu.Item
                  className="avatar-upload__menu-item"
                  onSelect={(event) => {
                    event.preventDefault()

                    setIsMenuOpen(false)

                    setTimeout(() => {
                      setIsCameraOpen(true)
                    }, 0)
                  }}
                >
                  <Camera size={16} />
                  <span>Сделать фото</span>
                </DropdownMenu.Item>
              )}
            </DropdownMenu.Content>
          </DropdownMenu.Portal>
        </DropdownMenu.Root>
      </div>

      <input
        ref={inputRef}
        type="file"
        accept="image/png,image/jpeg,image/gif"
        hidden
        disabled={disabled}
        onChange={(event) => {
          handleFileChange(event.target.files?.[0])
          event.target.value = ''
        }}
      />

      {/* <div className="avatar-upload__text">
        <span>PNG, JPG или GIF</span>
      </div> */}

      <div className="avatar-upload__actions">
        <button
          className="avatar-upload__choose"
          type="button"
          disabled={disabled}
          onClick={() => inputRef.current?.click()}
        >
          {avatarUrl ? replaceText : chooseText}
        </button>

        {hasSelectedFile && (
          <button
            className="avatar-upload__reset"
            type="button"
            disabled={disabled}
            onClick={onReset}
            aria-label="Сбросить выбранное фото"
          >
            <RotateCcw size={16} />
          </button>
        )}
      </div>

      {/* {hasSelectedFile && (
        <p className="avatar-upload__hint">
          Новое фото будет загружено после сохранения.
        </p>
      )} */}

      <AvatarCropModal
        open={Boolean(cropImageSrc)}
        imageSrc={cropImageSrc || renderCropImageSrc || ''}
        onCancel={handleCancelCrop}
        onConfirm={handleConfirmCrop}
      />
      <AvatarCameraModal
        open={isCameraOpen}
        onClose={() => setIsCameraOpen(false)}
        onCapture={handleCameraCapture}
      />
    </div>
  )
}
