import React from 'react';
import { Form, Upload } from 'antd';
import { message } from '@/lib/feedback/message';
import type { UploadProps } from 'antd/es/upload';
import type { FormItemProps } from 'antd/es/form';
import { Upload as UploadIcon } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';

/** Ex.: "image/*", ".pdf,.png", "application/pdf" */
function fileMatchesAccept(file: File, accept?: string): boolean {
    if (!accept || accept === '*') return true;
    const type = file.type?.toLowerCase() ?? '';
    const name = file.name?.toLowerCase() ?? '';
    const parts = accept.split(',').map((s) => s.trim().toLowerCase());
    for (const part of parts) {
        if (part.startsWith('.')) {
            if (name.endsWith(part)) return true;
        } else if (part.endsWith('/*')) {
            const prefix = part.slice(0, -1);
            if (type.startsWith(prefix)) return true;
        } else if (type === part || type.startsWith(part + '/')) {
            return true;
        }
    }
    return false;
}

interface FormUploadProps extends Omit<UploadProps, 'name'>, Omit<FormItemProps, 'name' | 'children'> {
    name: string | (string | number)[];
    label?: string;
    required?: boolean;
    help?: string;
    maxCount?: number;
    /** Ex.: ".pdf,.png", "image/*", "application/pdf" */
    accept?: string;
    /** Tamanho máximo por arquivo em MB. Mensagem de erro exibida se ultrapassar. */
    maxSizeMb?: number;
    listType?: 'text' | 'picture' | 'picture-card';
}

export default function FormUpload({
    name,
    label,
    required = false,
    help,
    maxCount = 1,
    accept,
    maxSizeMb,
    listType = 'text',
    rules,
    beforeUpload: customBeforeUpload,
    ...uploadProps
}: FormUploadProps) {
    const formRules = required
        ? [{ required: true, message: `${label || 'Campo'} é obrigatório` }, ...(rules || [])]
        : rules;

    const beforeUpload: UploadProps['beforeUpload'] = (file, fileList) => {
        if (maxSizeMb != null && file.size > maxSizeMb * 1024 * 1024) {
            message.error(`Tamanho máximo por arquivo: ${maxSizeMb} MB.`);
            return Upload.LIST_IGNORE;
        }
        if (accept && !fileMatchesAccept(file, accept)) {
            message.error(`Formato não aceito. Use: ${accept}`);
            return Upload.LIST_IGNORE;
        }
        if (customBeforeUpload) {
            const result = customBeforeUpload(file, fileList);
            if (result === Upload.LIST_IGNORE) return Upload.LIST_IGNORE;
            if (result === false) return false;
        }
        return false; // manter na lista sem enviar automaticamente
    };

    const helpText = help ?? (maxSizeMb || accept
        ? [maxSizeMb && `Máximo ${maxSizeMb} MB por arquivo`, accept && `Formatos: ${accept}`]
            .filter(Boolean)
            .join(' • ')
        : undefined);

    return (
        <Form.Item
            name={name}
            label={label}
            rules={formRules}
            help={helpText}
            valuePropName="fileList"
            getValueFromEvent={(e) => {
                if (Array.isArray(e)) {
                    return e;
                }
                return e?.fileList;
            }}
        >
            <Upload
                maxCount={maxCount}
                accept={accept}
                listType={listType}
                beforeUpload={beforeUpload}
                {...uploadProps}
            >
                <button type="button" style={{ border: 0, background: 'none' }}>
                    <UploadIcon size={ICON_SIZE_MD} aria-hidden /> Clique para fazer upload
                </button>
            </Upload>
        </Form.Item>
    );
}
