import { useState, useRef, useCallback } from 'react';
import { Camera, Upload, X, Check, AlertCircle, Loader2, Image as ImageIcon } from 'lucide-react';
import { uploadPhoto, UploadedPhoto } from '../../lib/uploadApi';
import { formatFileSize, isValidImageType } from '../../lib/photoCompression';

interface PhotoUploadProps {
    onUpload: (photo: UploadedPhoto) => void;
    onError?: (error: string) => void;
    maxSizeMB?: number;
    showPreview?: boolean;
    label?: string;
    className?: string;
}

export default function PhotoUpload({
    onUpload,
    onError,
    maxSizeMB = 10,
    showPreview = true,
    label = 'Upload Photo',
    className = ''
}: PhotoUploadProps) {
    const [isUploading, setIsUploading] = useState(false);
    const [progress, setProgress] = useState(0);
    const [preview, setPreview] = useState<string | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [uploadedPhoto, setUploadedPhoto] = useState<UploadedPhoto | null>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const cameraInputRef = useRef<HTMLInputElement>(null);

    const handleFileSelect = useCallback(async (file: File) => {
        setError(null);

        // Validate file type
        if (!isValidImageType(file)) {
            const msg = 'Invalid file type. Please use JPEG, PNG, WebP, or HEIC.';
            setError(msg);
            onError?.(msg);
            return;
        }

        // Validate file size
        if (file.size > maxSizeMB * 1024 * 1024) {
            const msg = `File too large. Maximum size is ${maxSizeMB}MB.`;
            setError(msg);
            onError?.(msg);
            return;
        }

        // Show preview immediately
        if (showPreview) {
            const reader = new FileReader();
            reader.onloadend = () => setPreview(reader.result as string);
            reader.readAsDataURL(file);
        }

        // Upload
        setIsUploading(true);
        setProgress(0);

        try {
            const result = await uploadPhoto(file, (p) => setProgress(p));
            setUploadedPhoto(result);
            onUpload(result);
        } catch (err: any) {
            const msg = err.response?.data?.error || 'Upload failed. Please try again.';
            setError(msg);
            onError?.(msg);
            setPreview(null);
        } finally {
            setIsUploading(false);
            setProgress(0);
        }
    }, [maxSizeMB, showPreview, onUpload, onError]);

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const file = e.target.files?.[0];
        if (file) {
            handleFileSelect(file);
        }
    };

    const handleDrop = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        const file = e.dataTransfer.files[0];
        if (file) {
            handleFileSelect(file);
        }
    }, [handleFileSelect]);

    const handleDragOver = (e: React.DragEvent) => {
        e.preventDefault();
    };

    const clearPhoto = () => {
        setPreview(null);
        setUploadedPhoto(null);
        setError(null);
        if (fileInputRef.current) fileInputRef.current.value = '';
        if (cameraInputRef.current) cameraInputRef.current.value = '';
    };

    return (
        <div className={`space-y-2 ${className}`}>
            {/* Hidden file inputs */}
            <input
                ref={fileInputRef}
                type="file"
                accept="image/jpeg,image/png,image/webp,image/heic,image/heif"
                onChange={handleInputChange}
                className="hidden"
            />
            <input
                ref={cameraInputRef}
                type="file"
                accept="image/*"
                capture="environment"
                onChange={handleInputChange}
                className="hidden"
            />

            {/* Upload area */}
            {!preview && !uploadedPhoto && (
                <div
                    onDrop={handleDrop}
                    onDragOver={handleDragOver}
                    className="border-2 border-dashed border-slate-300 dark:border-slate-600 rounded-xl p-6 text-center hover:border-emerald-500 dark:hover:border-emerald-500 transition-colors cursor-pointer"
                    onClick={() => fileInputRef.current?.click()}
                >
                    <ImageIcon className="mx-auto h-12 w-12 text-[var(--color-text-tertiary)] mb-3" />
                    <p className="text-sm text-slate-600 dark:text-[var(--color-text-tertiary)] mb-3">
                        {label}
                    </p>
                    <div className="flex justify-center gap-2">
                        <button
                            type="button"
                            onClick={(e) => {
                                e.stopPropagation();
                                fileInputRef.current?.click();
                            }}
                            className="flex items-center gap-1 px-3 py-2 bg-[var(--color-bg-tertiary)] rounded-lg text-sm hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors"
                        >
                            <Upload size={16} />
                            Browse
                        </button>
                        <button
                            type="button"
                            onClick={(e) => {
                                e.stopPropagation();
                                cameraInputRef.current?.click();
                            }}
                            className="flex items-center gap-1 px-3 py-2 bg-[var(--color-primary)] text-white rounded-lg text-sm hover:bg-[var(--color-primary)] transition-colors"
                        >
                            <Camera size={16} />
                            Camera
                        </button>
                    </div>
                    <p className="text-xs text-[var(--color-text-tertiary)] mt-2">
                        Max {maxSizeMB}MB • JPEG, PNG, WebP, HEIC
                    </p>
                </div>
            )}

            {/* Preview / Uploaded state */}
            {(preview || uploadedPhoto) && (
                <div className="relative rounded-xl overflow-hidden bg-slate-100 dark:bg-slate-800">
                    <img
                        src={uploadedPhoto?.urls.medium ? `/api/upload/photo${uploadedPhoto.urls.medium.replace('/photos', '')}` : preview || ''}
                        alt="Uploaded"
                        className="w-full h-48 object-cover"
                    />

                    {/* Loading overlay */}
                    {isUploading && (
                        <div className="absolute inset-0 bg-black/50 flex flex-col items-center justify-center">
                            <Loader2 className="animate-spin text-white mb-2" size={32} />
                            <div className="w-32 h-2 bg-white/20 rounded-full overflow-hidden">
                                <div
                                    className="h-full bg-[var(--color-primary)] transition-all duration-300"
                                    style={{ width: `${progress}%` }}
                                />
                            </div>
                            <p className="text-white text-sm mt-1">{progress}%</p>
                        </div>
                    )}

                    {/* Success indicator */}
                    {uploadedPhoto && !isUploading && (
                        <div className="absolute top-2 left-2 bg-[var(--color-primary)] text-white px-2 py-1 rounded-full text-xs flex items-center gap-1">
                            <Check size={12} />
                            Uploaded
                        </div>
                    )}

                    {/* Clear button */}
                    <button
                        type="button"
                        onClick={clearPhoto}
                        className="absolute top-2 right-2 bg-red-500 text-white p-1.5 rounded-full hover:bg-red-600 transition-colors"
                    >
                        <X size={16} />
                    </button>

                    {/* Metadata */}
                    {uploadedPhoto?.metadata && (
                        <div className="p-2 bg-[var(--color-bg-tertiary)] text-xs text-[var(--color-text-tertiary)] flex justify-between">
                            <span>
                                Original: {formatFileSize(uploadedPhoto.metadata.originalSize)}
                            </span>
                            <span className="text-[var(--color-primary)]">
                                Saved {uploadedPhoto.metadata.savingsPercent}%
                            </span>
                        </div>
                    )}
                </div>
            )}

            {/* Error state */}
            {error && (
                <div className="flex items-center gap-2 text-red-500 text-sm">
                    <AlertCircle size={16} />
                    {error}
                </div>
            )}
        </div>
    );
}
