import { useEffect, useRef, useState } from 'react'
import { Button } from '@shared/ui'
import { useMe, useUploadAvatar } from '@features/auth'
import { AvatarCropModal } from './AvatarCropModal'
import styles from './ProfileAvatar.module.css'

function blobToBase64(blob: Blob): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => {
      const result = reader.result as string
      const comma = result.indexOf(',')
      resolve(comma >= 0 ? result.slice(comma + 1) : result)
    }
    reader.onerror = () => reject(reader.error)
    reader.readAsDataURL(blob)
  })
}

export function ProfileAvatar() {
  const { data } = useMe()
  const { mutateAsync: upload, isPending } = useUploadAvatar()
  const inputRef = useRef<HTMLInputElement>(null)
  const [error, setError] = useState<string | null>(null)
  const [imgFailed, setImgFailed] = useState(false)
  const [pendingPreview, setPendingPreview] = useState<string | null>(null)

  const avatarLink = data?.avatar_link ?? null
  const showImg = avatarLink && !imgFailed

  useEffect(() => {
    setImgFailed(false)
  }, [avatarLink])

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

  const openPicker = () => {
    if (isPending) return
    inputRef.current?.click()
  }

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    e.target.value = ''
    if (!file) return

    setError(null)
    setPendingPreview(URL.createObjectURL(file))
  }

  const closeModal = () => {
    if (pendingPreview) URL.revokeObjectURL(pendingPreview)
    setPendingPreview(null)
  }

  const handleConfirm = async (blob: Blob) => {
    try {
      const photo_base64 = await blobToBase64(blob)
      await upload({ photo_base64, decoded_bytes: String(blob.size) })
      closeModal()
    } catch {
      setError('Не удалось загрузить фото')
      closeModal()
    }
  }

  return (
    <div className={styles.col}>
      <div className={styles.avatar} onClick={openPicker}>
        {showImg ? (
          <img
            src={avatarLink}
            alt="avatar"
            className={styles.avatarImg}
            referrerPolicy="no-referrer"
            onError={() => {
              console.warn('[avatar] failed to load', avatarLink)
              setImgFailed(true)
            }}
          />
        ) : (
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
            <circle cx="12" cy="8" r="4" />
            <path d="M4 20c0-4 4-7 8-7s8 3 8 7" />
          </svg>
        )}
        <div className={styles.overlay}>
          <svg viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
            <path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z" />
            <circle cx="12" cy="13" r="4" />
          </svg>
        </div>
      </div>
      <input
        ref={inputRef}
        type="file"
        accept="image/*"
        onChange={handleFileChange}
        hidden
      />
      <div className={styles.addPhoto}>
        <Button variant="ghost" onClick={openPicker} disabled={isPending}>
          {isPending ? 'ЗАГРУЗКА...' : 'ДОБАВИТЬ ФОТО'}
        </Button>
      </div>
      {error && <span className={styles.error}>{error}</span>}

      {pendingPreview && (
        <AvatarCropModal
          imageSrc={pendingPreview}
          isSaving={isPending}
          onCancel={closeModal}
          onConfirm={handleConfirm}
        />
      )}
    </div>
  )
}
