import { memo, useContext, useCallback, useMemo } from 'react';
import ButtonGroup from '@mui/material/ButtonGroup';
import { JsonFormsDispatch, useJsonForms, withJsonFormsControlProps } from '@jsonforms/react';
import { DataContext } from '../context/Context';
import { inputProps } from '../interface/inputfieldProps';
import ComponentWrapper from '../common/ComponentWrapper';
import { getComponentProps } from '../common/getComponentProps';
import { getFieldName } from '../permissions/getFieldName';
import { Box } from '@mui/material';
import React from 'react';

const ImpaktAppsButtonGroup = memo(function (props: inputProps) {
 const {
  enabled,
  uischema,
  path,
  cells,
  schema,
  renderers,
  rootSchema,
  data,
  handleChange,
 } = props;

 const { pageName, permissions,serviceProvider } = useContext(DataContext);
 const ctx = useJsonForms();
 const dynamicStyle = React.useMemo(() => {
  return serviceProvider(
   ctx,
   {
    onClick: uischema.config?.main?.styleFunction || 'getStyle',
   },
   {
    event: { _reactName: 'onClick' },
    path,
   },
  );
 }, [data, path]);
 const componentStyle = { ...uischema.config?.style, ...dynamicStyle };
 const uischemaData = uischema?.config?.main;
 const fieldName = getFieldName(path);

 const activeStyle = componentStyle.activeButtonStyle ?? {};
 const inactiveStyle = componentStyle.inactiveButtonStyle ?? {};

 const isMultiSelect = uischemaData?.multiSelect ?? false;

 const handleButtonClick = useCallback(
  (buttonValue: string) => {
   if (isMultiSelect) {
    const current: string[] = Array.isArray(data) ? [...data] : [];
    const updated = current.includes(buttonValue)
     ? current.filter((v) => v !== buttonValue)
     : [...current, buttonValue];
    handleChange(path, updated);
   } else {
    handleChange(path, data === buttonValue ? undefined : buttonValue);
   }
  },
  [data, path, isMultiSelect, handleChange],
 );

 const getScopeValue = (scope: string): string => {
  return scope?.split('/').pop() ?? scope;
 };

 const activeMap = useMemo<Record<string, boolean>>(() => {
  if (!data) return {};
  if (isMultiSelect) {
   return (Array.isArray(data) ? data : []).reduce(
    (acc: Record<string, boolean>, val: string) => {
     acc[val] = true;
     return acc;
    },
    {},
   );
  }
  return { [data]: true };
 }, [data, isMultiSelect]);

 return (
  <ComponentWrapper
   {...getComponentProps(
    `${pageName}:${fieldName}`,
    permissions,
    schema,
    rootSchema,
   )}
  >
   <ButtonGroup
    orientation={uischemaData?.orientation || 'horizontal'}
    variant={uischemaData?.variant || 'contained'}
    size={uischemaData?.size || 'medium'}
    color={uischemaData?.color}
    sx={{
     boxShadow: 'none',
     width: '100%',
     ...componentStyle,
    }}
   >
    {uischema?.elements?.map((element: any, i: number) => {
     const buttonValue: string = element?.scope
      ? getScopeValue(element.scope)
      : `${path}-${i}`;
     const isActive = activeMap[buttonValue] ?? false;
     const mergedElement = {
      ...element,
      config: {
       ...element.config,
       main: {
        ...element.config?.main,
       },
       style: {
        ...element.config?.style,
        ...(isActive ? activeStyle : inactiveStyle),
       },
      },
     };
     return (
      <Box
       key={`button-group-item-${i}`}
       onClick={() => handleButtonClick(buttonValue)}
       sx={{ display: 'contents' }}
      >
       <JsonFormsDispatch
        schema={schema}
        uischema={mergedElement}
        path={path}
        enabled={enabled}
        renderers={renderers}
        cells={cells}
       />
      </Box>
     );
    })}
   </ButtonGroup>
  </ComponentWrapper>
 );
});

export default withJsonFormsControlProps(ImpaktAppsButtonGroup);
