import React, { useEffect, useState, forwardRef, useImperativeHandle } from 'react';
import {
  Box,
  Typography,
  TextField,
  Autocomplete,
  Chip,
  FormHelperText
} from '@mui/material';
import useValidation, { defaultRules } from '../../../hooks/useValidation';
import { CmdbItem } from '../../../store/cmdbSlice/thunks';
import { CMDB_ITEM_TYPES } from '../../../store/constants';
import { getAutocompleteClasses } from '../../../store/cmdbSlice/thunks';
import { useAutocompleteField } from '../../../hooks/useAutocompleteField';
import { useFormStyles } from '../styles';

interface ClassFormProps {
  identifier: string;
  setCmdbItem: (item: CmdbItem) => void;
  item?: CmdbItem;
}

interface ClassFormRef {
  validate: () => Promise<boolean>;
}

const ClassForm = forwardRef<ClassFormRef, ClassFormProps>(({ identifier, setCmdbItem, item }, ref) => {
  const { classes } = useFormStyles();
  const [name, setName] = useState<string>(item?.name || '');
  const [description, setDescription] = useState<string>(item?.description || '');
  const [tags, setTags] = useState<string[]>(item?.tags || []);

  const { options: classOptions, loading: loadingClasses } = useAutocompleteField({
    query: name,
    fetchThunk: getAutocompleteClasses
  });

  // Custom validation rules for editing vs creating
  const customRules = item !== undefined
    ? { ...defaultRules, name: { ...defaultRules.name, checkExists: false } }
    : defaultRules;

  const { errors, validate } = useValidation({ customRules });


  const validateForm = async (): Promise<boolean> => {
    const formItem: CmdbItem = {
      type: CMDB_ITEM_TYPES.CLASS,
      name,
      description,
      tags,
      entries: [{
        item_name: name,
        item_value: null,
        item_type: CMDB_ITEM_TYPES.CLASS,
        entry_id: item?.id
      }]
    };

    return await validate({ item: formItem, identifier });
  };

  // Expose the validate function to the parent via the ref
  useImperativeHandle(ref, () => ({
    validate: validateForm,
  }), [validate, name, description, tags, item?.id, identifier]);

  useEffect(() => {
    const formItem: CmdbItem = {
      type: CMDB_ITEM_TYPES.CLASS,
      name,
      description,
      tags,
      entries: [{
        item_name: name,
        item_value: null,
        item_type: CMDB_ITEM_TYPES.CLASS
      }]
    };

    setCmdbItem(formItem);
  }, [name, description, tags, setCmdbItem]);

  return (
    <>
      <Box className={classes.formRow}>
        <Typography variant="body1" className={classes.label}>
          Name:
        </Typography>
        <Box className={classes.fieldContainer}>
          <Autocomplete
            freeSolo
            options={classOptions}
            value={name}
            loading={loadingClasses}
            onInputChange={(_, newValue) => setName(newValue)}
            renderInput={(params) => (
              <TextField
                {...params}
                fullWidth
                variant="outlined"
                size="small"
                placeholder="Class name"
                error={!!errors.item_name}
                helperText={errors.item_name}
              />
            )}
          />
        </Box>
      </Box>

      <Box className={classes.formRow}>
        <Typography variant="body1" className={classes.label}>
          Tags:
        </Typography>
        <Box className={classes.fieldContainer}>
          <Autocomplete
            multiple
            freeSolo
            options={[]}
            value={tags}
            onChange={(event, newValue) => setTags(newValue)}
            renderTags={(value, getTagProps) =>
              value.map((option, index) => {
                const { key, ...chipProps } = getTagProps({ index });
                return (
                  <Chip
                    key={key}
                    variant="outlined"
                    label={option}
                    {...chipProps}
                  />
                );
              })
            }
            renderInput={(params) => (
              <TextField
                {...params}
                variant="outlined"
                placeholder="Tags"
                error={!!errors.tags}
                helperText={errors.tags}
              />
            )}
          />
          <FormHelperText>Press enter to add new tags</FormHelperText>
        </Box>
      </Box>
      <Box className={classes.descriptionRow}>
        <Typography variant="body1" className={classes.label}>
          Description:
        </Typography>
        <Box className={classes.fieldContainer}>
          <TextField
            variant="outlined"
            multiline
            fullWidth
            rows={3}
            placeholder="Class description"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            error={!!errors.description}
            helperText={errors.description}
          />
        </Box>
      </Box>
    </>
  );
});

export default ClassForm;
