'use client';

import { signIn } from 'next-auth/react';
import { usePathname, useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { ROUTES } from '@theme/routes';
import { LoginFormType, FormType, PzSignInOptions } from '@theme/types';
import { Button, Input, Link } from '@theme/components';
import { SubmitHandler, useForm } from 'react-hook-form';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import clsx from 'clsx';
import { useGetBasketQuery } from '@akinon/next/data/client/basket';
import { useCaptcha, useLocalization } from '@akinon/next/hooks';
import { AuthError } from '@akinon/next/types';
import { Image } from '@akinon/next/components/image';
import PluginModule, { Component } from '@akinon/next/components/plugin-module';
import { twMerge } from 'tailwind-merge';

const oauthProviders: Array<{
  key: string;
  label?: string;
  image?: string;
  localeKey?: string;
}> = [
  {
    key: 'google',
    label: 'Google'
  },
  {
    key: 'facebook',
    label: 'Facebook'
  },
  {
    key: 'apple',
    label: 'Apple'
  }
];

const loginFormSchema = (t) =>
  yup.object().shape({
    email: yup
      .string()
      .email(t('auth.login.form.error.email_valid'))
      .required(t('auth.login.form.error.required')),
    password: yup.string().required(t('auth.login.form.error.required'))
  });

export const Login = ({
  setActiveTab
}: {
  setActiveTab?: (tab: string) => void;
}) => {
  const { t, locale } = useLocalization();

  const { refetch: refetchBasketData } = useGetBasketQuery();

  const {
    register,
    handleSubmit,
    formState: { errors },
    setError
  } = useForm<LoginFormType>({
    resolver: yupResolver(loginFormSchema(t))
  });

  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [formError, setFormError] = useState(null);
  const [isCheckout, setIsCheckout] = useState<boolean>(false);

  const {
    CaptchaView,
    validated: captchaValidated,
    isVisible: isCaptchaVisible,
    validate: validateCaptcha
  } = useCaptcha();

  const onSubmit: SubmitHandler<LoginFormType> = async (data) => {
    setFormError(null);

    const loginResponse = await signIn('default', {
      redirect: false,
      callbackUrl: searchParams.get('callbackUrl') ?? '/',
      captchaValidated,
      ...data,
      formType: FormType.login
    } as PzSignInOptions & { redirect: false });

    if (loginResponse.error) {
      const errors: AuthError[] = JSON.parse(loginResponse.code);

      if (errors.find((error) => error.type === 'captcha')) {
        if (await validateCaptcha()) {
          onSubmit(data);
        }

        return;
      }

      const fieldErrors = errors.find((error) => error.type === 'field_errors')
        ?.data as {
        name: string;
        value: string[];
      }[];
      const nonFieldErrors = errors.find(
        (error) => error.type === 'non_field_errors'
      )?.data as string[];

      fieldErrors?.forEach((item) => {
        let parsedValue: Record<string, string[]> | string[] = [];

        if (typeof item.value === 'string') {
          try {
            parsedValue = JSON.parse(item.value);
          } catch {
            parsedValue = [item.value];
          }
        } else {
          parsedValue = item.value;
        }

        if (Array.isArray(parsedValue)) {
          setError(item.name as keyof LoginFormType, {
            type: 'custom',
            message: parsedValue.join(', ')
          });
        } else {
          Object.keys(parsedValue).forEach((key) => {
            const fieldName = key as keyof LoginFormType;
            const errorMessages = parsedValue[key] as string[];

            setError(fieldName, {
              type: 'custom',
              message: errorMessages.join(', ')
            });
          });
        }
      });

      if (nonFieldErrors?.length) {
        setFormError(nonFieldErrors.join(', '));
      }

      return;
    }

    if (loginResponse.url) {
      window.location.href = loginResponse.url;
      refetchBasketData();
    }
  };

  useEffect(() => {
    if (pathname.includes('/orders/checkout')) {
      setIsCheckout(true);
    }
  }, [pathname]);

  return (
    <section className="w-full mt-6 lg:mt-8">
      <form
        action="/api/auth/signin/credentials"
        method="post"
        onSubmit={handleSubmit(onSubmit)}
      >
        <input type="hidden" value={FormType.login} {...register('formType')} />
        <input type="hidden" value={locale} {...register('locale')} />

        <div>
          <Input
            labelStyle="floating"
            label={t('auth.login.form.email.placeholder')}
            className="h-12"
            {...register('email')}
            error={errors.email}
            data-testid="login-email"
            required
          />
        </div>

        <div className="mt-4">
          <Input
            labelStyle="floating"
            label={t('auth.login.form.password.placeholder')}
            className="h-12"
            type="password"
            {...register('password')}
            error={errors.password}
            data-testid="login-password"
            required
          />
        </div>

        <Link
          href={ROUTES.FORGOT_PASSWORD}
          className="block text-black-750/75 text-sm underline mt-4"
          data-testid="login-forgot-password"
        >
          {t('auth.login.form.forgot_password')}
        </Link>

        {formError && (
          <p
            className="text-error text-xs my-2"
            data-testid="login-error-field"
          >
            {formError}
          </p>
        )}

        <div className="flex justify-center">
          <CaptchaView className="mt-8" data-testid="login-captcha" />
        </div>

        <Button
          className="w-full h-12 text-sm font-normal mt-6 lg:mt-8"
          type="submit"
          disabled={isCaptchaVisible && !captchaValidated}
          data-testid="login-submit"
        >
          {t('auth.login.form.submit')}
        </Button>

        <p
          className={clsx(
            twMerge(
              'relative block text-center mt-3 lg:mt-8 text-black-750 text-sm',
              'before:absolute before:left-0 before:top-1/2 before:w-full before:h-px before:bg-[#d2d2d2] before:-z-10'
            )
          )}
        >
          <span className="bg-white px-4">{t('auth.login.form.or')}</span>
        </p>
      </form>

      <div className="grid gap-4 mt-2">
        {oauthProviders.map((provider) => (
          <Button
            key={provider.key}
            className="text-base text-black-750 h-auto py-4 border border-gray-650 leading-[0.94]"
            type="submit"
            appearance="outlined"
            disabled={isCaptchaVisible && !captchaValidated}
            onClick={() => {
              location.href = `/${provider.key}/login/`;
            }}
          >
            {t('auth.login.form.continue_with_provider').replace(
              '{provider}',
              provider.localeKey ? t(provider.localeKey) : provider.label
            )}
          </Button>
        ))}
        {isCheckout && (
          <Button
            className="text-base text-black-750 h-auto py-4 border border-gray-650 leading-[0.94]"
            type="submit"
            appearance="outlined"
            onClick={() => {
              setActiveTab?.('guest');
            }}
          >
            {t('checkout.auth.continue_as_guest_checkout')}
          </Button>
        )}
        <PluginModule
          component={Component.AkifastQuickLoginButton}
          props={{
            isCaptchaVisible,
            captchaValidated
          }}
        />
      </div>
    </section>
  );
};
