'use client';

import { useMemo, useState } from 'react';

import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';

import { useRevalidatePersonalAccountDataQuery } from '@kit/accounts/hooks/use-personal-account-data';
import { useUpdateAccountData } from '@kit/accounts/hooks/use-update-account';
import { Database } from '@kit/supabase/database';
import { useUser } from '@kit/supabase/hooks/use-user';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@kit/ui/select';
import { Trans } from '@kit/ui/trans';

export function LanguageSelector({
  onChange,
}: {
  onChange?: (locale: string) => unknown;
}) {
  const { i18n } = useTranslation();
  const { language: currentLanguage, options } = i18n;
  const [value, setValue] = useState(i18n.language);

  const { data: user } = useUser();

  const locales = (options.supportedLngs as string[]).filter(
    (locale) => locale.toLowerCase() !== 'cimode',
  );

  const languageNames = useMemo(() => {
    return new Intl.DisplayNames([currentLanguage], {
      type: 'language',
    });
  }, [currentLanguage]);

  const userId = user?.id;
  const updateAccountMutation = useUpdateAccountData(userId);
  const revalidateUserDataQuery = useRevalidatePersonalAccountDataQuery();

  const updateLanguagePreference = async (
    locale: Database['medreport']['Enums']['locale'],
  ) => {
    setValue(locale);

    if (onChange) {
      onChange(locale);
    }

    if (!userId) {
      localStorage.setItem('lang', locale);
      return i18n.changeLanguage(locale);
    }

    const promise = updateAccountMutation
      .mutateAsync({
        preferred_locale: locale,
      })
      .then(() => {
        revalidateUserDataQuery(userId!);
      });
    await i18n.changeLanguage(locale);

    return toast.promise(() => promise, {
      success: <Trans i18nKey={'account:updatePreferredLocaleSuccess'} />,
      error: <Trans i18nKey={'account:updatePreferredLocaleError'} />,
      loading: <Trans i18nKey={'account:updatePreferredLocaleLoading'} />,
    });
  };

  return (
    <Select value={value} onValueChange={updateLanguagePreference}>
      <SelectTrigger>
        <SelectValue />
      </SelectTrigger>

      <SelectContent>
        {locales.map((locale) => {
          const label = capitalize(languageNames.of(locale) ?? locale);

          const option = {
            value: locale,
            label,
          };

          return (
            <SelectItem value={option.value} key={option.value}>
              {option.label}
            </SelectItem>
          );
        })}
      </SelectContent>
    </Select>
  );
}

function capitalize(lang: string) {
  return lang.slice(0, 1).toUpperCase() + lang.slice(1);
}
