import { Label } from "@/components/ui/label";
import LabelStyle from "@/shared/components/dashboard/label-style";
import { useState, useEffect, InputHTMLAttributes, MouseEvent, DragEvent } from "react";
import { Controller, useFormContext } from "react-hook-form";
import ValidationError from "../../validation-error";
import { cn } from "@/lib/utils";

type FileInputFieldProps = {
	label?: string;
	name: string;
	required?: boolean;
	placeholder?: string;
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange'>;

const FileInputField = ({
	label,
	name,
	required = false,
	placeholder = "Upload file",
	className = "col-span-4 flex flex-col gap-3",
  ...props
}: FileInputFieldProps) => {
	const { control, formState: { errors }, watch } = useFormContext();
	const [isDragOver, setIsDragOver] = useState(false);
	const [selectedFiles, setSelectedFiles] = useState<File[]>([]);

	// Watch the form field value to sync with selectedFiles
	const fieldValue = watch(name);

	// Sync selectedFiles with form data
	useEffect(() => {
		if (fieldValue) {
			if (Array.isArray(fieldValue)) {
				setSelectedFiles(fieldValue);
			} else if (fieldValue instanceof File) {
				setSelectedFiles([fieldValue]);
			} else {
				setSelectedFiles([]);
			}
		} else {
			setSelectedFiles([]);
		}
	}, [fieldValue]);

	// Get nested error by path (e.g., "document_uploads.id_document_scan")
	const getNestedError = (obj: any, path: string) => {
		return path.split('.').reduce((current, key) => current?.[key], obj);
	};

	const fieldError = getNestedError(errors, name);

	const handleFileSelect = (files: FileList | null, onChange: (value: any) => void) => {
		if (!files) return;

		const fileArray = Array.from(files);
		setSelectedFiles(fileArray);

		if (props.multiple) {
			onChange(fileArray);
		} else {
			onChange(fileArray[0] || null);
		}
	};

	const handleDeleteFile = (index: number, onChange: (value: any) => void) => {
		const updatedFiles = selectedFiles.filter((_, i) => i !== index);
		setSelectedFiles(updatedFiles);

		if (props.multiple) {
			onChange(updatedFiles);
		} else {
			onChange(null);
		}
	};

	const handleUploadAreaClick = (e: MouseEvent) => {
		if (!props.disabled) {
			const fileInput = document.getElementById(`file-input-${name}`) as HTMLInputElement;
			if (fileInput) {
				fileInput.click();
			}
		}
	};

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

	const handleDragLeave = (e: DragEvent) => {
		e.preventDefault();
		setIsDragOver(false);
	};

	const handleDrop = (e: DragEvent, onChange: (value: any) => void) => {
		e.preventDefault();
		setIsDragOver(false);
		handleFileSelect(e.dataTransfer.files, onChange);
	};

	return (
		<div className={className}>
			{label && <Label>
				<LabelStyle>
					{label} {required && "*"}
				</LabelStyle>
			</Label>}
			<Controller
				control={control}
				name={name}
				rules={required ? { required: `${label} is required` } : undefined}
				render={({ field }) => (
					<div className="flex flex-col gap-2">
						<div
							className={cn(`relative w-full min-h-32 border-2 border-dashed rounded-lg transition-all duration-200 cursor-pointer ${
								isDragOver
									? 'border-blue-400 bg-blue-50'
									: fieldError
									? 'border-red-400 bg-red-50'
									: 'border-gray-300 bg-gray-50 hover:border-gray-400 hover:bg-gray-100'
							}`, {
                'opacity-50 cursor-not-allowed': props.disabled
              })}
							onDragOver={handleDragOver}
							onDragLeave={handleDragLeave}
							onDrop={(e) => handleDrop(e, field.onChange)}
							onClick={handleUploadAreaClick}
						>
							<input
								id={`file-input-${name}`}
								type="file"
								className="sr-only"
								onChange={(e) => handleFileSelect(e.target.files, field.onChange)}
								{...props}
							/>

							<div className="flex flex-col items-center justify-center h-full p-6">
								{/* Upload Icon */}
								<div className="mb-4">
									<svg
										className="w-12 h-12 text-gray-400"
										fill="none"
										stroke="currentColor"
										viewBox="0 0 24 24"
									>
										<path
											strokeLinecap="round"
											strokeLinejoin="round"
											strokeWidth={1.5}
											d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
										/>
									</svg>
								</div>

								{/* Upload Text */}
								<div className="text-center">
									<p className="text-lg font-medium text-gray-700 mb-1">
										{placeholder}
									</p>
									<p className="text-sm text-gray-500">
										Click to browse or drag and drop files here
									</p>
									{props.accept && (
										<p className="text-xs text-gray-400 mt-1">
											Supported formats: {props.accept.replace(/[/*]/g, '').toUpperCase()}
										</p>
									)}
								</div>
							</div>
						</div>

						{/* Selected Files Display */}
						{selectedFiles.length > 0 && (
							<div className="mt-2 space-y-1">
								{selectedFiles.map((file, index) => (
									<div key={index} className="flex items-center justify-between p-3 bg-gray-100 rounded-lg text-sm border">
										<div className="flex items-center gap-3 flex-1 min-w-0">
											{/* File Icon */}
											<div className="flex-shrink-0">
												{file.type.startsWith('image/') ? (
													<svg className="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
														<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
													</svg>
												) : (
													<svg className="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
														<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
													</svg>
												)}
											</div>

											{/* File Info */}
											<div className="flex-1 min-w-0">
												<p className="font-medium text-gray-900 truncate">{file.name}</p>
												<p className="text-xs text-gray-500">
													{(file.size / 1024 / 1024).toFixed(2)} MB
												</p>
											</div>
										</div>

										{/* Delete Button */}
										{!props.disabled && <button
											type="button"
											onClick={(e) => {
												e.stopPropagation();
												handleDeleteFile(index, field.onChange);
											}}
											className="flex-shrink-0 p-1 text-red-500 hover:text-red-700 hover:bg-red-50 rounded transition-colors"
											aria-label="Delete file"
										>
											<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
												<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
											</svg>
										</button>}
									</div>
								))}
							</div>
						)}

						{fieldError && (
							<ValidationError error={fieldError.message || `${label} is required`} />
						)}
					</div>
				)}
			/>
		</div>
	);
};

export default FileInputField;