import { useRef, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useMutation } from 'react-query';

import i18next from 'i18next';
import { useDrawerV2 } from '@material-hu/hooks/useDrawerV2';
import Stack from '@material-hu/mui/Stack';

import { type AutocompleteOption } from '@material-hu/components/design-system/Inputs/Autocomplete/types';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { isDarkModeEnabled } from 'src/constants/env';
import { type Language } from 'src/constants/languages';
import { useAuth } from 'src/contexts/JWTContext';
import useCommunityFeature from 'src/hooks/useCommunityFeature';
import useGeneralError from 'src/hooks/useGeneralError';
import useThemeMode from 'src/hooks/useThemeMode';
import { refetchAllTranslations } from 'src/pages/dashboard/feed/queries';
import { invalidateAllTranslations } from 'src/pages/dashboard/groups/queries';
import { changeLanguageUser, patchUserLanguage } from 'src/services/users';
import { CommunityFeature } from 'src/types/communityFeatures';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { setDocumentLanguage } from 'src/utils/languages';

import { useTranslation } from '../i18n';

import AppearanceSection from './components/AppearanceSection';
import PlatformLanguageSection from './components/PlatformLanguageSection';
import { SettingsChangeLanguageForm } from './SettingsChangeLanguageForm';

type SettingsFormValues = {
  postTranslationLanguage: AutocompleteOption | null;
};

const toLanguageOption = (
  code: string,
  translate: (key: string) => string,
): AutocompleteOption => ({
  value: code,
  label: translate(`language_${code.toLowerCase().replace('-', '_')}`),
});

export const useSettingsDrawer = () => {
  const {
    user,
    changePostTranslationLanguage,
    changeLanguage: changeUserLanguage,
  } = useAuth();
  const { t } = useTranslation();
  const { t: tSettings } = useLokaliseTranslation('settings');
  const { t: tDashboard } = useLokaliseTranslation('dashboard');
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();
  const canTranslate = useCommunityFeature(CommunityFeature.TRANSLATE_POSTS);
  const { commitThemeMode, resetThemeMode } = useThemeMode();

  const { id: userId, postTranslationLanguage } = user!;

  // --- Platform language draft (applied only on "Guardar") ---
  const initialLanguageRef = useRef<Language>(user?.language as Language);
  const [draftLanguage, setDraftLanguage] = useState<Language>(
    user?.language as Language,
  );

  const { mutate: commitPlatformLanguage } = useMutation({
    mutationFn: (language: Language) => changeLanguageUser(userId, language),
    onSuccess: (_, language) => {
      // Apply the language change only once the save succeeds.
      changeUserLanguage?.(language);
      setDocumentLanguage(language);
      i18next.changeLanguage(language);
      initialLanguageRef.current = language;
    },
    onError: err => {
      showGeneralError(err, t('CHANGE_LANGUAGE_ERROR'));
    },
  });

  // --- Colleague posts translation language ---
  const defaultOption = postTranslationLanguage
    ? toLanguageOption(postTranslationLanguage, tDashboard)
    : null;

  const form = useForm<SettingsFormValues>({
    defaultValues: { postTranslationLanguage: defaultOption },
  });

  const { mutate: changeLanguageMutate } = useMutation({
    mutationFn: (language: string) => patchUserLanguage(language, userId),
    onSuccess: response => {
      invalidateAllTranslations();
      refetchAllTranslations();
      changePostTranslationLanguage?.(response.data);
      enqueueSnackbar({
        title: tSettings('LANGUAGE_CHANGED_SUCCESSFULLY'),
        variant: 'success',
      });
    },
  });

  const handleSave = () => {
    // Theme: persist the previewed mode.
    commitThemeMode();

    // Platform language: apply only on save, and only if it changed.
    if (draftLanguage !== initialLanguageRef.current) {
      commitPlatformLanguage(draftLanguage);
    }

    // Colleague posts language.
    const postOption = form.getValues().postTranslationLanguage;
    if (canTranslate && postOption) {
      changeLanguageMutate(String(postOption.value));
    }

    closeDrawer();
  };

  const handleClose = () => {
    // Discard the unsaved theme preview and language draft.
    resetThemeMode();
    setDraftLanguage(initialLanguageRef.current);
    form.reset();
    closeDrawer();
  };

  const {
    drawer,
    showDrawer: openDrawer,
    closeDrawer,
  } = useDrawerV2(() => ({
    title: isDarkModeEnabled ? tSettings('preferences') : t('SETTINGS'),
    children: (
      <Stack gap={2}>
        {isDarkModeEnabled && (
          <PlatformLanguageSection
            value={draftLanguage}
            onChange={setDraftLanguage}
          />
        )}
        {canTranslate && (
          <FormProvider {...form}>
            <SettingsChangeLanguageForm />
          </FormProvider>
        )}
        {isDarkModeEnabled && <AppearanceSection />}
      </Stack>
    ),
    onClose: handleClose,
    primaryButtonProps:
      isDarkModeEnabled || canTranslate
        ? {
            children: tSettings('save'),
            fullWidth: true,
            onClick: handleSave,
          }
        : undefined,
  }));

  const showDrawer = () => {
    // Snapshot the current language as the revert baseline for this session.
    initialLanguageRef.current = user?.language as Language;
    setDraftLanguage(user?.language as Language);
    openDrawer({});
  };

  return { drawer, showDrawer };
};
