import React, { useCallback, useMemo, useState } from 'react';
import { intersectionWith } from 'lodash';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { Flex, Padded, Text, Checkbox } from '@buffetjs/core';
import { useIntl } from 'react-intl';
import { usePermissionsContext } from '../../../../../../hooks';
import ConditionsModal from '../../../../ConditionsModal';
import ConditionsButton from '../../../../ConditionsButton';
import CheckboxWrapper from '../CheckboxWrapper';
import BaselineAlignment from '../BaselineAlignment';
import SubCategoryWrapper from './SubCategoryWrapper';
import ConditionsButtonWrapper from './ConditionsButtonWrapper';

const Border = styled.div`
  flex: 1;
  align-self: center;
  border-top: 1px solid #f6f6f6;
  padding: 0px 10px;
`;

const SubCategory = ({ categoryName, subCategory }) => {
  const { formatMessage } = useIntl();
  const [modal, setModal] = useState({ isOpen: false, isMounted: false });
  const { pluginsAndSettingsPermissions, dispatch } = usePermissionsContext();

  const checkPermission = useCallback(
    action => {
      return (
        pluginsAndSettingsPermissions.findIndex(permission => permission.action === action) !== -1
      );
    },
    [pluginsAndSettingsPermissions]
  );

  const handlePermission = action => {
    dispatch({
      type: 'ON_PLUGIN_SETTING_ACTION',
      action,
    });
  };

  const currentPermissions = useMemo(() => {
    return intersectionWith(
      pluginsAndSettingsPermissions,
      subCategory.actions,
      (x, y) => x.action === y.action
    );
  }, [pluginsAndSettingsPermissions, subCategory.actions]);

  const hasAllCategoryActions = useMemo(() => {
    return currentPermissions.length === subCategory.actions.length;
  }, [currentPermissions, subCategory.actions]);

  const hasSomeCategoryActions = useMemo(() => {
    return currentPermissions.length > 0 && currentPermissions.length < subCategory.actions.length;
  }, [currentPermissions, subCategory.actions]);

  const categoryConditions = useMemo(() => {
    return currentPermissions.reduce((acc, current) => {
      return {
        ...acc,
        [current.action]: current.conditions,
      };
    }, {});
  }, [currentPermissions]);

  const hasCategoryConditions = useMemo(() => {
    return Object.values(categoryConditions).flat().length > 0;
  }, [categoryConditions]);

  const handleSubCategoryPermissions = () => {
    dispatch({
      type: 'ON_PLUGIN_SETTING_SUB_CATEGORY_ACTIONS',
      actions: subCategory.actions,
      shouldEnable: !hasAllCategoryActions,
    });
  };

  const handleModalOpen = () => {
    setModal({
      isMounted: true,
      isOpen: true,
    });
  };

  const handleToggleModal = () => {
    setModal(prev => ({
      ...prev,
      isOpen: !prev.isOpen,
    }));
  };

  const handleClosed = () => {
    setModal(prev => ({ ...prev, isMounted: false }));
  };

  const actionsForConditions = useMemo(() => {
    return currentPermissions.map(permission => ({
      id: permission.action,
      displayName: subCategory.actions.find(perm => perm.action === permission.action).displayName,
    }));
  }, [currentPermissions, subCategory.actions]);

  const checkCategory = useCallback(
    action => {
      return categoryConditions[action] ? categoryConditions[action].length > 0 : false;
    },
    [categoryConditions]
  );

  const handleConditionsSubmit = conditions => {
    dispatch({
      type: 'ON_PLUGIN_SETTING_CONDITIONS_SELECT',
      conditions,
    });
  };

  return (
    <>
      <SubCategoryWrapper disabled>
        <Flex justifyContent="space-between" alignItems="center">
          <Padded right size="sm">
            <Text
              lineHeight="18px"
              color="#919bae"
              fontWeight="bold"
              fontSize="xs"
              textTransform="uppercase"
            >
              {subCategory.subCategory}
            </Text>
          </Padded>
          <Border />
          <Padded left size="sm">
            <BaselineAlignment />
            <Checkbox
              name={`select-all-${subCategory.subCategory}`}
              message={formatMessage({ id: 'app.utils.select-all' })}
              disabled
              onChange={handleSubCategoryPermissions}
              someChecked={hasSomeCategoryActions}
              value={hasAllCategoryActions}
            />
          </Padded>
        </Flex>
        <BaselineAlignment />
        <Padded top size="xs">
          <Flex flexWrap="wrap">
            {subCategory.actions.map(sc => (
              <CheckboxWrapper disabled hasConditions={checkCategory(sc.action)} key={sc.action}>
                <Checkbox
                  value={checkPermission(sc.action)}
                  name={sc.action}
                  disabled
                  message={sc.displayName}
                  onChange={() => handlePermission(sc.action)}
                />
              </CheckboxWrapper>
            ))}
          </Flex>
          <ConditionsButtonWrapper disabled hasConditions={hasCategoryConditions}>
            <ConditionsButton hasConditions={hasCategoryConditions} onClick={handleModalOpen} />
          </ConditionsButtonWrapper>
        </Padded>
      </SubCategoryWrapper>
      {modal.isMounted && (
        <ConditionsModal
          actions={actionsForConditions}
          initialConditions={categoryConditions}
          onSubmit={handleConditionsSubmit}
          onToggle={handleToggleModal}
          isOpen={modal.isOpen}
          onClosed={handleClosed}
          headerBreadCrumbs={[categoryName, subCategory.subCategory]}
        />
      )}
    </>
  );
};

SubCategory.propTypes = {
  categoryName: PropTypes.string.isRequired,
  subCategory: PropTypes.object.isRequired,
};

export default SubCategory;
