import { useEffect } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { type UseInfiniteQueryResult } from 'react-query';

import { IconPlus, IconX } from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack, { type StackProps } 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 Tooltip from '@material-hu/components/design-system/Tooltip';

import { type CustomField } from 'src/types/instance';
import { type SegmentationType } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  defaultConditionValues,
  getRequestFields,
  JoinOperator,
} from 'src/components/Condition/components/constants';
import {
  categorizedFields,
  getConditionOperators,
} from 'src/components/Condition/components/utils';

import MenuSelect from '../MenuSelect';
import FieldSelect from '../MenuSelect/FieldSelect';

import JoinSelector from './JoinSelector';
import ValueSelector from './ValueSelector';

export type ConditionData = {
  users: Array<{ id: number; label: string; avatar?: string | null }>;
  agents: Array<{ id: number; label: string; avatar?: string | null }>;
  categories: Array<{ id: string; label: string; avatar?: string | null }>;
  departments: Array<{ id: number | string; label: string }>;
  jobs: Array<{ id: string; label: string }>;
  states: Array<{ id: string; label: string }>;
  isLoadingStates: boolean;
  usersInfiniteQuery: UseInfiniteQueryResult<any>;
  agentsInfiniteQuery: UseInfiniteQueryResult<any>;
  categoriesInfiniteQuery: UseInfiniteQueryResult<any>;
  departmentsInfiniteQuery: UseInfiniteQueryResult<any>;
  jobsInfiniteQuery: UseInfiniteQueryResult<any>;
  search: string;
  setSearch: (search: string) => void;
};

export type ConditionProps = {
  name: string;
  profileFields: CustomField[];
  conditionData: ConditionData;
  segmentationGroups?: SegmentationType[];
  sx?: StackProps['sx'];
};

const Condition = ({
  name,
  profileFields,
  conditionData,
  segmentationGroups,
  sx,
}: ConditionProps) => {
  const { getValues, control, watch, setValue } = useFormContext();
  const { t } = useLokaliseTranslation([
    'backoffice_only',
    'workflows',
    'general',
    'users',
  ]);

  const { fields, append, remove, replace } = useFieldArray({
    control,
    name,
  });

  const clearFirstConditionFields = () => {
    setValue(`${name}[0].field`, null, { shouldValidate: true });
    setValue(`${name}[0].equalityOperator`, null);
    setValue(`${name}[0].value`, null);
    setValue(`${name}[0].joinOperator`, JoinOperator.AND);
  };

  const conditions = watch(name) || [];

  // biome-ignore lint/correctness/useExhaustiveDependencies: We need to replace the conditions when the name changes
  useEffect(() => {
    replace(conditions);
  }, [name]);

  const {
    users,
    agents,
    categories,
    departments,
    jobs,
    states,
    isLoadingStates,
    usersInfiniteQuery,
    agentsInfiniteQuery,
    categoriesInfiniteQuery,
    departmentsInfiniteQuery,
    jobsInfiniteQuery,
    search,
    setSearch,
  } = conditionData;

  return (
    <Stack sx={{ gap: 2, ...sx }}>
      <CardContainer fullWidth>
        <Stack sx={{ gap: 2 }}>
          {fields.map((line, index) => (
            <Stack
              key={line.id}
              sx={{
                flexDirection: 'row',
                alignItems: 'center',
                gap: 1,
                width: '100%',
              }}
            >
              <JoinSelector
                index={index}
                name={name}
              />
              <FieldSelect
                title={t('backoffice_only:condition.fields')}
                items={getRequestFields(t)}
                categorizedItems={categorizedFields(profileFields, t)}
                segmentationGroups={segmentationGroups}
                name={`${name}[${index}].field`}
                onChange={() => {
                  setValue(`${name}[${index}].equalityOperator`, null);
                  setValue(`${name}[${index}].value`, null);
                }}
              />
              <MenuSelect
                title={t('backoffice_only:condition.condition')}
                items={getConditionOperators(
                  watch(`${name}[${index}].field`),
                  profileFields || [],
                  t,
                )}
                name={`${name}[${index}].equalityOperator`}
                maxSelection={1}
                singleObject
                isDisabled={!watch(`${name}[${index}].field`)}
                onChange={() => {
                  setValue(`${name}[${index}].value`, null);
                }}
              />
              <ValueSelector
                index={index}
                name={name}
                users={users}
                states={states || []}
                categories={categories}
                departments={departments}
                jobs={jobs}
                usersInfiniteQuery={usersInfiniteQuery}
                categoriesInfiniteQuery={categoriesInfiniteQuery}
                departmentsInfiniteQuery={departmentsInfiniteQuery}
                jobsInfiniteQuery={jobsInfiniteQuery}
                dynamicFields={profileFields}
                isLoadingStates={isLoadingStates}
                agents={agents}
                agentsInfiniteQuery={agentsInfiniteQuery}
                search={search}
                setSearch={setSearch}
                segmentationGroups={segmentationGroups}
              />
              <IconButton
                sx={{ flex: 0 }}
                aria-label={t('general:remove')}
                onClick={() => {
                  if (fields.length === 1) clearFirstConditionFields();
                  else remove(index);
                }}
              >
                <IconX size={16} />
              </IconButton>
            </Stack>
          ))}
        </Stack>
        <Tooltip
          title={t('workflows:conditions_limit')}
          description={t('workflows:conditions_limit_description')}
          disableTooltip={fields.length < 6}
        >
          <span>
            <Button
              variant="tertiary"
              size="medium"
              sx={{ mt: 2 }}
              fullWidth
              startIcon={<IconPlus size={16} />}
              onClick={() => {
                append({
                  ...defaultConditionValues,
                  joinOperator:
                    getValues(name)?.[1]?.joinOperator || JoinOperator.AND,
                });
              }}
              disabled={fields.length >= 6}
            >
              {t('backoffice_only:condition.new_condition')}
            </Button>
          </span>
        </Tooltip>
      </CardContainer>
    </Stack>
  );
};

export default Condition;
