"use client"

import { useCallback, useRef, useState, useEffect } from 'react'
import styles from './ImgInputForm.module.css'

const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB

const ImgInputForm = () => {
    const fileRef = useRef<HTMLInputElement | null>(null)
    const [fileName, setFileName] = useState('')
    const [preview, setPreview] = useState<string | null>(null)
    const [isDragging, setIsDragging] = useState(false)
    const [loading, setLoading] = useState(false)
    const [error, setError] = useState<string | null>(null)
    const [success, setSuccess] = useState<string | null>(null)

    const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:9001'

    useEffect(() => {
        const checkAuth = async () => {
            try {
                const res = await fetch(`${API_BASE}/auth/check-token`, {
                    method: 'GET',
                    credentials: 'include',
                })
                if (!res.ok) throw new Error('인증 실패')
                console.log('사용자 인증 성공')
            } catch (err) {
                console.error('사용자 인증 실패:', (err as Error).message)
                setError('로그인이 필요합니다.')
            }
        }

        checkAuth()
    }, [])

    const handleFile = useCallback((file: File) => {
        setError(null)
        setSuccess(null)
        if (!file.type.startsWith('image/')) {
            setError('이미지 파일만 업로드할 수 있습니다.')
            return
        }
        if (file.size > MAX_FILE_SIZE) {
            setError('파일 크기는 5MB 이하만 업로드 가능합니다.')
            return
        }

        setFileName(file.name)
        setPreview(URL.createObjectURL(file))
        // keep the selected file in the hidden input
        if (fileRef.current) {
            const dataTransfer = new DataTransfer()
            dataTransfer.items.add(file)
            fileRef.current.files = dataTransfer.files
        }
    }, [])

    const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
        const file = e.target.files?.[0]
        if (file) handleFile(file)
    }

    const onClickPick = () => fileRef.current?.click()

    const onDrop: React.DragEventHandler<HTMLDivElement> = (e) => {
        e.preventDefault()
        setIsDragging(false)
        const file = e.dataTransfer.files?.[0]
        if (file) handleFile(file)
    }

    const onDragOver: React.DragEventHandler<HTMLDivElement> = (e) => {
        e.preventDefault()
        setIsDragging(true)
    }

    const onDragLeave: React.DragEventHandler<HTMLDivElement> = () => {
        setIsDragging(false)
    }

    const upload = async () => {
        setError(null)
        setSuccess(null)
        const files = fileRef.current?.files
        if (!files || files.length === 0) {
            setError('업로드할 파일을 선택해주세요.')
            return
        }
        const file = files[0]
        if (!file.type.startsWith('image/')) {
            setError('이미지 파일만 업로드할 수 있습니다.')
            return
        }
        setLoading(true)
        try {
            const fd = new FormData()
            fd.append('image', file)
            const res = await fetch(`${API_BASE}/img/get-img`, {
                method: 'POST',
                body: fd,
                credentials: 'include'
            })
            if (!res.ok) throw new Error('업로드 실패')
            setSuccess('업로드 성공')
        } catch (err) {
            setError((err as Error).message || '업로드 중 오류가 발생했습니다')
        } finally {
            setLoading(false)
        }
    }

    return (
        <div className={styles.wrapper}>
            <div
                className={`${styles.dropzone} ${isDragging ? styles.dragging : styles.normal}`}
                onDrop={onDrop}
                onDragOver={onDragOver}
                onDragLeave={onDragLeave}
            >
                <input
                    ref={fileRef}
                    type="file"
                    accept="image/*"
                    className={styles.fileInput}
                    onChange={onChange}
                />

                <div className={styles.previewBox}>
                    {preview ? (
                        // preview kept modest in size
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={preview} alt="preview" className={styles.previewImg} onClick={onClickPick} />
                    ) : (
                        <div className={styles.placeholder}>
                            이미지를 끌어다 놓거나<br />
                            클릭해 선택하세요
                        </div>
                    )}
                </div>

                <div className={styles.row}>
                    <input
                        type="text"
                        readOnly
                        value={fileName}
                        onClick={onClickPick}
                        placeholder="선택된 파일 없음"
                        className={styles.textInput}
                    />
                    <button
                        onClick={upload}
                        disabled={loading}
                        className={`${styles.btn} ${loading ? styles.btnLoading : styles.btnPrimary}`}
                    >
                        {loading ? '업로드 중...' : '업로드'}
                    </button>
                </div>

                {error && <p className={styles.errorMsg}>{error}</p>}
                {success && <p className={styles.successMsg}>{success}</p>}
            </div>
        </div>
    )
}

export default ImgInputForm
