import React from 'react';
import { Input, Form } from 'antd';
import type { InputProps } from 'antd/es/input';
import type { FormItemProps } from 'antd/es/form';
import { maskCPF, maskCNPJ, maskPhone, maskCEP } from '@/lib/utils/masks';

interface FormInputProps extends Omit<InputProps, 'name'> {
    name: string | (string | number)[];
    label?: string;
    required?: boolean;
    help?: string;
    /** Texto de apoio abaixo do campo (Form.Item `extra`). */
    extra?: React.ReactNode;
    prefixIcon?: React.ReactNode;
    suffixIcon?: React.ReactNode;
    mask?: 'cpf' | 'cnpj' | 'phone' | 'cep';
    rules?: FormItemProps['rules'];
    dependencies?: FormItemProps['dependencies'];
    validateTrigger?: FormItemProps['validateTrigger'];
}

function applyMask(
    mask: NonNullable<FormInputProps['mask']>,
    raw: string
): string {
    switch (mask) {
        case 'cpf':
            return maskCPF(raw);
        case 'cnpj':
            return maskCNPJ(raw);
        case 'phone':
            return maskPhone(raw);
        case 'cep':
            return maskCEP(raw);
        default:
            return raw;
    }
}

/** Garante valor exibido/armazenado já mascarado (ex.: API envia só dígitos). */
function normalizeMaskedValue(mask: NonNullable<FormInputProps['mask']>, value: unknown): string {
    if (value == null || value === '') return '';
    return applyMask(mask, String(value));
}

export default function FormInput({
    name,
    label,
    required = false,
    help,
    extra,
    prefixIcon,
    suffixIcon,
    rules,
    mask,
    onChange,
    dependencies,
    validateTrigger,
    inputMode,
    ...inputProps
}: FormInputProps) {
    const formRules = required
        ? [{ required: true, message: `${label || 'Campo'} é obrigatório` }, ...(rules || [])]
        : rules;

    const mergedInputMode =
        inputMode ??
        (mask === 'cpf' || mask === 'cep'
            ? 'numeric'
            : mask === 'cnpj'
              ? 'text'
              : mask === 'phone'
                ? 'tel'
                : undefined);

    const itemProps: Partial<FormItemProps> = mask
        ? {
              getValueFromEvent: (e: React.ChangeEvent<HTMLInputElement>) =>
                  applyMask(mask, e?.target?.value ?? ''),
              normalize: (value: unknown) => normalizeMaskedValue(mask, value),
          }
        : {};

    const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        onChange?.(e);
    };

    return (
        <Form.Item
            name={name}
            label={label}
            rules={formRules}
            help={help}
            extra={extra}
            dependencies={dependencies}
            validateTrigger={validateTrigger}
            {...itemProps}
        >
            <Input
                prefix={prefixIcon}
                suffix={suffixIcon}
                onChange={handleChange}
                inputMode={mergedInputMode}
                autoComplete={mask === 'cpf' ? 'off' : inputProps.autoComplete}
                {...inputProps}
            />
        </Form.Item>
    );
}
