import React, { useCallback, useMemo, useState, useRef } from 'react';
import {
  Box,
  Typography,
  Select,
  MenuItem,
  OutlinedInput,
  Button,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  FormHelperText,
  type SelectChangeEvent
} from '@mui/material';
import { isDarkMode } from '@northern.tech/store/utils';
import { blue, darkBlue } from '../../../themes/common';
import { useDispatch, useSelector } from 'react-redux';
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
import { makeStyles } from 'tss-react/mui';

import { createItem, getItems, CmdbItem, getPolicyConfigurationsIds } from '../store/cmdbSlice/thunks';
import { ITEM_TYPES } from '../store/constants';
import { selectPagination } from '../store/cmdbSlice/selectors';

interface CmdbCreateProps {
  onCancel: () => void;
  identifier: string;
}
interface FormRef {
  validate: () => Promise<boolean>;
}

export const useStyles = makeStyles()((theme) => ({
  root: {
    '& .MuiSelect-root.MuiOutlinedInput-root': {
      width: 172,
      height: 32
    },
    '& .MuiSelect-icon': {
      right: 8
    },
    '& .MuiAutocomplete-inputRoot.MuiOutlinedInput-root': {
      '& .MuiAutocomplete-tag': {
        fontWeight: 500,
        border: 'none',
        background: (isDarkMode(theme.palette.mode) ? theme.palette.darkBackground[900] : '#E3E4E5'),
        height: 24,
        '& .MuiChip-deleteIcon': {
          color: '#8C8D8E'
        }
      }
    },
    '& .MuiAutocomplete-root .MuiAutocomplete-input': {
      background: 'none'
    },
    '& .MuiAutocomplete-root .MuiOutlinedInput-notchedOutline': {
      border: `1px solid ${isDarkMode(theme.palette.mode) ? 'rgba(255, 255, 255, 0.23)' : 'rgba(0, 0, 0, 0.23)'}`
    },
    '& .MuiAutocomplete-root:hover .MuiOutlinedInput-notchedOutline': {
      borderColor: isDarkMode(theme.palette.mode) ? 'rgba(255, 255, 255, 0.87)' : 'rgba(0, 0, 0, 0.87)'
    },
    ['.MuiAutocomplete-root .Mui-focused .MuiOutlinedInput-notchedOutline']: {
      border: `${isDarkMode(theme.palette.mode) ? `2px solid ${darkBlue[200]}` : `2px solid ${blue[500]}`} !important`
    },
    '& .Mui-focused.Mui-error .MuiOutlinedInput-notchedOutline': {
      borderColor: `${theme.palette.error.main} !important`
    },
  },
  accordion: {
    border: `1px solid ${theme.palette.primary.border}`,
    borderRadius: '4px',
    boxShadow: 'none',
    '&::before': {
      display: 'none',
    },
    '&:not(:last-of-type)': {
      marginBottom: theme.spacing(1),
    },
  },
  summary: {
    backgroundColor: theme.palette.background.default,
    '&.Mui-expanded': {
      minHeight: '48px',
      backgroundColor: theme.palette.background.summary,
    },
    '& .MuiAccordionSummary-content': {
      display: 'flex',
      alignItems: 'center',
      margin: `${theme.spacing(1.5)} 0`,
      '&.Mui-expanded': {
        margin: `${theme.spacing(1.5)} 0`,
      }
    },
  },
  formRow: {
    display: 'flex',
    alignItems: 'baseline',
    '&:not(:last-of-type)': {
      marginBottom: theme.spacing(2.5),
    }
  },
  descriptionRow: {
    display: 'flex',
    alignItems: 'baseline',
  },
  label: {
    width: 142,
    flexShrink: 0,
    marginRight: theme.spacing(3),
    color: theme.palette.text.primary,
    fontWeight: 500,
  },
  itemLabel: {
    fontWeight: 500,
    width: 200
  },
  details: {
    backgroundColor: theme.palette.background.default,
    padding: theme.spacing(2),
    borderTop: `1px solid ${theme.palette.divider}`,
  },
  buttonContainer: {
    display: 'flex',
    gap: theme.spacing(1),
  }
}));


const CmdbCreate: React.FC<CmdbCreateProps> = ({ onCancel, identifier }) => {
  const { classes } = useStyles();
  const [type, setType] = useState<string>('');
  const [error, setError] = useState<string>('');
  const [cmdbItem, setCmdbItem] = useState<CmdbItem | undefined>();
  const dispatch = useDispatch();
  const formRef = useRef<FormRef | null>(null);
  const pagination = useSelector(selectPagination);

  const selectedType = useMemo(() => {
    return ITEM_TYPES.find(item => item.value === type);
  }, [type]);

  const FormComponent = useMemo(() => {
    if (!selectedType) return null;
    
    return selectedType.component({ identifier, setCmdbItem, formRef });
  }, [selectedType, identifier, setCmdbItem]);

  React.useEffect(() => {
    if (selectedType) {
      setError('');
    }
  }, [selectedType]);


  const handleTypeChange = (event: SelectChangeEvent<string>) => {
    setType(event.target.value);
  };

  const onSave = useCallback(async () => {
    if (!formRef.current) {
      setError('Data type is required');
      return;
    }
    const isValid = await formRef.current.validate();
    if (isValid) {
      await dispatch(createItem({ identifier, entry: cmdbItem })).unwrap();
      dispatch(getItems({ identifier, page: pagination.page || 1 }));
      dispatch(getPolicyConfigurationsIds({ identifier }));
      onCancel();
    }
  }, [cmdbItem, identifier, pagination.page, dispatch, onCancel]);



  return (
    <Box className={classes.root}>
      <Accordion expanded={true} className={classes.accordion}>
        <AccordionSummary expandIcon={<ExpandMoreIcon />} className={classes.summary}>
          <Typography variant="body2" className={classes.itemLabel}>
            New host specific data
          </Typography>
        </AccordionSummary>
        <AccordionDetails className={classes.details}>
          <Box>
            <Box className={classes.formRow}>
              <Typography variant="body1" className={classes.label}>
                Type:
              </Typography>
              <Box>
                <Select
                  displayEmpty
                  value={type}
                  fullWidth
                  onChange={handleTypeChange}
                  IconComponent={ExpandMoreIcon}
                  input={<OutlinedInput />}
                  error={!!error}
                >
                  <MenuItem disabled value="">
                    Select a type
                  </MenuItem>
                  {ITEM_TYPES.map((option) => (
                    <MenuItem key={option.value} value={option.value}>
                      {option.label}
                    </MenuItem>
                  ))}
                </Select>
                {error && <FormHelperText error>{error}</FormHelperText>}
              </Box>
            </Box>
            {FormComponent}
          </Box>
        </AccordionDetails>
      </Accordion>
      <Box sx={{ mb: 3, mt: 1 }}>
        <Button 
          onClick={onCancel} 
          variant="outlined" 
          sx={{ mr: 1 }} 
          size="small"
        >
          Cancel
        </Button>
        <Button 
          onClick={onSave} 
          variant="contained" 
          color="secondary" 
          size="small"
        >
          Save
        </Button>
      </Box>
    </Box>
  );
};

export default React.memo(CmdbCreate);
