import { useForm } from 'react-hook-form';

import { type SegmentationType } from 'src/types/user';

import {
  type KnowledgeBaseAudienceForm,
  type KnowledgeBaseAudienceSegmentation,
  KnowledgeBaseAudienceType,
  type SegmentationTag,
} from '../types';
import { buildSegmentationTags } from '../utils';

import { useEditKnowledgeBaseAudience } from './useEditKnowledgeBaseAudience';

type Params = {
  items: string[];
  defaultAudience?: SegmentationTag[];
  groups: SegmentationType[] | undefined;
};

type SubmitArgs = {
  values: KnowledgeBaseAudienceForm;
  onSuccess?: () => void;
};

const EMPTY_VALUES: KnowledgeBaseAudienceForm = {
  audienceType: null,
  segmentation: {},
};

export const useEditAudienceForm = ({
  items,
  defaultAudience,
  groups,
}: Params) => {
  const { mutate, isLoading } = useEditKnowledgeBaseAudience();

  const getInitialAudienceType = (): KnowledgeBaseAudienceType | null => {
    if (defaultAudience === undefined) return EMPTY_VALUES.audienceType;
    return defaultAudience.length === 0
      ? KnowledgeBaseAudienceType.ALL
      : KnowledgeBaseAudienceType.SEGMENTED;
  };

  const initialAudienceType = getInitialAudienceType();

  const initialSegmentation: KnowledgeBaseAudienceSegmentation = defaultAudience
    ? defaultAudience.reduce<KnowledgeBaseAudienceSegmentation>((acc, tag) => {
        acc[tag.groupId] = acc[tag.groupId] ?? new Set();
        acc[tag.groupId].add(tag.itemId);
        return acc;
      }, {})
    : EMPTY_VALUES.segmentation;

  const form = useForm<KnowledgeBaseAudienceForm>({
    defaultValues: {
      audienceType: initialAudienceType,
      segmentation: initialSegmentation,
    },
  });

  const submit = ({ values, onSuccess }: SubmitArgs) => {
    if (!values.audienceType) return;

    const tags: SegmentationTag[] =
      values.audienceType === KnowledgeBaseAudienceType.SEGMENTED
        ? buildSegmentationTags(values.segmentation, groups ?? [])
        : [];

    return mutate({ documents: items, tags, userIds: [] }, { onSuccess });
  };

  const cleanForm = () => {
    form.reset(EMPTY_VALUES);
  };

  return {
    form,
    submit,
    isLoading,
    cleanForm,
  };
};
