import { ChangeEvent, DragEvent, useEffect, useRef, useState } from "react";
import { Button, Card } from "react-bootstrap";
import { MdClose, MdOutlineFileUpload, MdInsertDriveFile, MdDescription } from "react-icons/md";
import Doctype from "./doctype";

interface UploadDocumentProps {
    id?: string;
    selectedFile?: File | null;
    onFileChange: (file: File | null) => void;
    accept?: string;
    maxSize?: number; // in MB
    className?: string;
    placeholder?: string;
    multiple?: boolean;
}

export default function UploadDocument({
    id = "document-upload",
    selectedFile,
    onFileChange,
    accept = "*/*",
    maxSize = 10, // 10MB default
    className = "",
    placeholder = "Click to upload or drag and drop",
    multiple = false
}: UploadDocumentProps) {
    const inputRef = useRef<HTMLInputElement>(null);
    const [isDragging, setIsDragging] = useState(false);
    const [error, setError] = useState<string>("");

    const formatFileSize = (bytes: number): string => {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    };

    const validateFile = (file: File): boolean => {
        setError("");

        // Check file size
        if (file.size > maxSize * 1024 * 1024) {
            setError(`File size exceeds ${maxSize}MB limit`);
            return false;
        }

        // Check file type if accept is specified and not wildcard
        if (accept !== "*/*") {
            const acceptedTypes = accept.split(',').map(type => type.trim());
            const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
            const mimeType = file.type;

            const isAccepted = acceptedTypes.some(type => {
                if (type.startsWith('.')) {
                    return fileExtension === type.toLowerCase();
                } else if (type.includes('/*')) {
                    const category = type.split('/')[0];
                    return mimeType.startsWith(category + '/');
                } else {
                    return mimeType === type;
                }
            });

            if (!isAccepted) {
                setError(`File type not accepted. Allowed types: ${accept}`);
                return false;
            }
        }

        return true;
    };

    const handleFile = (file: File) => {
        if (validateFile(file)) {
            onFileChange(file);
        }
    };

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

    const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
        e.preventDefault();
        setIsDragging(true);
    };

    const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
        e.preventDefault();
        setIsDragging(false);
    };

    const handleDrop = (e: DragEvent<HTMLDivElement>) => {
        e.preventDefault();
        setIsDragging(false);
        const file = e.dataTransfer.files[0];
        if (file) handleFile(file);
    };

    const handleRemoveFile = () => {
        if (inputRef.current) {
            inputRef.current.value = '';
        }
        onFileChange(null);
        setError("");
    };

    const triggerFileInput = () => {
        inputRef.current?.click();
    };

    const getFileExtension = (filename: string): string => {
        return filename.split('.').pop()?.toLowerCase() || '';
    };

    return (
        <div className={`upload-document ${className}`}>
            <input
                id={id}
                name={id}
                type="file"
                accept={accept}
                multiple={multiple}
                className="d-none"
                ref={inputRef}
                onChange={handleFileChange}
            />

            {!selectedFile ? (
                <Card
                    className={`upload-zone bg-light-subtle cursor-pointer border-dashed ${isDragging ? 'border-primary bg-primary-subtle' : 'border-secondary'
                        } ${error ? 'border-danger' : ''}`}
                    style={{ minHeight: '120px' }}
                    onClick={triggerFileInput}
                    onDragOver={handleDragOver}
                    onDragLeave={handleDragLeave}
                    onDrop={handleDrop}
                >
                    <Card.Body className="d-flex flex-column justify-content-center align-items-center text-center py-4">
                        {isDragging ? (
                            <>
                                <MdOutlineFileUpload className="fs-1 text-primary mb-2" />
                                <p className="mb-0 text-primary fw-medium">Drop file here</p>
                            </>
                        ) : (
                            <>
                                <MdOutlineFileUpload className="fs-1 text-muted mb-2" />
                                <p className="mb-1 fw-medium">{placeholder}</p>
                                <small className="text-muted">
                                    Maximum file size: {maxSize}MB
                                    {accept !== "*/*" && (
                                        <><br />Accepted types: {accept}</>
                                    )}
                                </small>
                            </>
                        )}
                    </Card.Body>
                </Card>
            ) : (
                <Card className="selected-file">
                    <Card.Body className="py-3">
                        <div>
                            <div className="mb-4">
                                <Doctype
                                    fileName={selectedFile.name}
                                    iconSize={40}
                                />
                            </div>

                            <div className="d-flex">
                                <div className="flex-grow-1">
                                    <h6 className="mb-1 fw-medium text-break" title={selectedFile.name}>
                                        {selectedFile.name}
                                    </h6>
                                    <div className="d-flex align-items-start gap-2">
                                        <small className="text-muted text-nowrap">
                                            {formatFileSize(selectedFile.size)}
                                        </small>
                                        <span className="text-muted">•</span>
                                        <small className="text-muted">
                                            {selectedFile.type || 'Unknown type'}
                                        </small>
                                    </div>
                                </div>

                                <div className="flex-shrink-0">
                                    <Button
                                        type="button"
                                        variant="danger-subtle"
                                        size="sm"
                                        className="btn-icon"
                                        onClick={handleRemoveFile}
                                        title="Remove file"
                                    >
                                        <MdClose />
                                    </Button>
                                </div>
                            </div>

                        </div>
                    </Card.Body>
                </Card>
            )}

            {error && (
                <div className="mt-2">
                    <small className="text-danger">{error}</small>
                </div>
            )}

            {!selectedFile && (
                <div className="mt-2">
                    <Button
                        type="button"
                        variant="secondary-subtle"
                        size="sm"
                        className="btn-icon-label"
                        onClick={triggerFileInput}
                    >
                        <MdDescription />
                        <span>Browse Files</span>
                    </Button>
                </div>
            )}
        </div>
    );
}
