import { type FC, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { isEqual } from 'lodash-es';
import { IconPlus } from '@material-hu/icons/tabler';
import Stack from '@material-hu/mui/Stack';

import Button from '@material-hu/components/design-system/Buttons/Button';
import CardContainer from '@material-hu/components/design-system/CardContainer';
import Drawer from '@material-hu/components/design-system/Drawer';
import FormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import Title from '@material-hu/components/design-system/Title';
import { useDialogLayer } from '@material-hu/components/layers/Dialogs';

import {
  type FilterFormValues,
  type ViewForm,
} from 'src/pages/dashboard/serviceManagement/types';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { validateRequired } from 'src/utils/validation';

import useViews from '../../hooks/useViews';
import { FILTERS_DEFAULT_VALUES } from '../constants';

import CountFilterItem from './CountFilterItem';
import FiltersDrawer from './FiltersDrawer';

type Props = {
  open: boolean;
  onClose: () => void;
  viewId?: string;
};

const serviceFilterItems = [
  {
    tLabel: 'states',
    value: 'statesIn',
  },
  {
    tLabel: 'service_items',
    value: 'serviceItemsIn',
  },
  {
    tLabel: 'initiators',
    value: 'initiatorsIn',
  },
  {
    tLabel: 'collaborator_types',
    value: 'initiatorCollaboratorTypesIn',
  },
  {
    tLabel: 'agents',
    value: 'agentsIn',
  },
];
const VIEW_NAME_MAX_LENGTH = 140;

const CreateViewDrawer: FC<Props> = ({ open, onClose, viewId }) => {
  const { t } = useLokaliseTranslation('service_management');

  const [appliedFilters, setAppliedFilters] = useState<FilterFormValues | null>(
    null,
  );

  const [filterDrawerOpen, setFilterDrawerOpen] = useState(false);

  const form = useForm<ViewForm>({
    defaultValues: {
      name: '',
      ...FILTERS_DEFAULT_VALUES,
    },
    mode: 'onChange',
  });

  const {
    formState: { isValid },
  } = form;

  const { createViewMutation } = useViews(viewId);

  const { openDialog, closeDialog } = useDialogLayer();

  const formValues = form.watch();

  const hasEmptyFilters = useMemo(() => {
    const { name, ...filterValues } = formValues;
    return Object.values(filterValues).every(value => {
      if (Array.isArray(value)) {
        return value.length === 0;
      }
      return value == null;
    });
  }, [formValues]);

  const createButtonDisabled = hasEmptyFilters || !isValid;

  const handleCreate = () => {
    if (!isValid || createViewMutation.isLoading) {
      form.trigger();
      return;
    }

    createViewMutation.mutate(formValues, {
      onSuccess: () => {
        onClose();
        form.reset();
      },
    });
  };

  const handleOpenFilterDrawer = () => setFilterDrawerOpen(true);

  const handleCloseWithoutSaving = () => {
    closeDialog();
    onClose();
    form.reset();
  };

  const openConfirmExitWithoutSavingDialog = () => {
    openDialog({
      title: t('view_not_saved_yet_title'),
      textBody: t('view_not_saved_yet_description'),
      onClose: () => closeDialog(),
      primaryButtonProps: {
        variant: 'primary',
        children: t('create'),
        onClick: () => {
          closeDialog();
          handleCreate();
        },
        disabled: createButtonDisabled,
      },
      secondaryButtonProps: {
        variant: 'text',
        children: t('exit'),
        onClick: handleCloseWithoutSaving,
      },
      dialogProps: { fullWidth: true },
    });
  };

  const handleApplyFilters = () => {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    const { name: ___, ...filters } = formValues;
    setAppliedFilters(filters);
    setFilterDrawerOpen(false);
  };

  const openFilterNotAppliedDialog = () => {
    openDialog({
      title: t('filters_not_applied_title'),
      textBody: t('filters_not_applied_description'),
      onClose: () => closeDialog(),
      primaryButtonProps: {
        variant: 'primary',
        children: t('apply'),
        onClick: () => {
          closeDialog();
          handleApplyFilters();
        },
      },
      secondaryButtonProps: {
        variant: 'text',
        children: t('exit'),
        onClick: () => {
          closeDialog();
          setFilterDrawerOpen(false);
        },
      },
      dialogProps: { fullWidth: true },
    });
  };

  const handleCloseMainDrawer = () => {
    if (hasEmptyFilters && !formValues.name) {
      onClose();
    } else {
      openConfirmExitWithoutSavingDialog();
    }
  };

  const handleCloseFilterDrawer = () => {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    const { name: __, ...currentFilters } = formValues;
    if (!hasEmptyFilters && !isEqual(appliedFilters, currentFilters)) {
      openFilterNotAppliedDialog();
    } else {
      setFilterDrawerOpen(false);
    }
  };

  const handleResetFilters = () => {
    form.reset({ name: formValues.name, ...FILTERS_DEFAULT_VALUES });
    setAppliedFilters(null);
    handleCloseFilterDrawer();
  };

  const dateFiltersContent = useMemo(() => {
    let count = 0;
    if (formValues.creationDateFrom) count++;
    if (formValues.creationDateTo) count++;
    return count;
  }, [formValues.creationDateFrom, formValues.creationDateTo]);

  return (
    <FormProvider {...form}>
      <Drawer
        title={t('create_new_view')}
        open={open}
        onClose={handleCloseMainDrawer}
        primaryButtonProps={{
          children: t('create_view'),
          fullWidth: true,
          onClick: handleCreate,
          loading: createViewMutation.isLoading,
        }}
        secondaryButtonProps={{
          children: t('cancel'),
          fullWidth: true,
          disabled: createViewMutation.isLoading,
          onClick: handleCloseMainDrawer,
        }}
      >
        <FiltersDrawer
          open={filterDrawerOpen}
          onClose={handleCloseFilterDrawer}
          onReset={handleResetFilters}
          onApply={handleApplyFilters}
          showBackButton
          onBack={handleCloseFilterDrawer}
        />
        <Stack
          sx={{
            gap: 2,
          }}
        >
          <CardContainer
            fullWidth
            sx={{
              backgroundColor: ({ palette }) =>
                palette.new.background.layout.default,
              border: 'none',
            }}
          >
            <FormInputClassic
              name="name"
              rules={validateRequired(t('view_name_required'))}
              inputProps={{
                label: `${t('view_name')} *`,
                placeholder: t('view_name'),
                maxLength: VIEW_NAME_MAX_LENGTH,
                hasCounter: false,
              }}
            />
          </CardContainer>
          <CardContainer
            fullWidth
            sx={{
              backgroundColor: ({ palette }) =>
                palette.new.background.layout.default,
              border: 'none',
            }}
          >
            <Stack sx={{ gap: 1 }}>
              <Title
                variant="S"
                title={t('filters')}
                description={hasEmptyFilters ? t('no_filters_yet') : undefined}
              />
              {!hasEmptyFilters && (
                <>
                  {dateFiltersContent > 0 && (
                    <CountFilterItem
                      title={t('creation_date')}
                      value={null}
                      badgeContent={dateFiltersContent}
                    />
                  )}
                  {serviceFilterItems.map(filter => (
                    <CountFilterItem
                      key={filter.value}
                      title={t(filter.tLabel)}
                      value={formValues[filter.value as keyof FilterFormValues]}
                    />
                  ))}
                </>
              )}
              <Button
                variant="primary"
                onClick={handleOpenFilterDrawer}
                startIcon={<IconPlus />}
                fullWidth
              >
                {t('add_filters')}
              </Button>
            </Stack>
          </CardContainer>
        </Stack>
      </Drawer>
    </FormProvider>
  );
};

export default CreateViewDrawer;
