import { Box, Container, Flex, Heading } from '@radix-ui/themes';
import { useMutation } from '@tanstack/react-query';
import { useLocation, useNavigate } from 'react-router';
import { toast } from 'react-toastify/unstyled';
import * as v from 'valibot';
import { useResponseErrorHandler } from '../../hooks/ResponseHelper';
import { useApi } from '../../providers/ApiProvider';
import { formHook } from '../../providers/FormProvider';
import type { Route } from './+types/login';
import { SearchParamKeys } from '../../lib/constants';
import { AxiosError } from 'axios';
import { useQueryMessage } from '../../hooks/useQueryMessage';

const loginFormSchema = v.object({
  username: v.pipe(v.string(), v.trim(), v.minLength(1, 'Username is required')),
  password: v.pipe(v.string(), v.minLength(1, 'Password is required')),
});

// eslint-disable-next-line no-empty-pattern
export function meta({}: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: 'Login | YANPM' }];
}

// TODO: remember me
export default function LoginRoute() {
  const navigate = useNavigate();
  const location = useLocation();
  const { tanstackApiClient } = useApi();
  const { defaultResponseErrorHandler } = useResponseErrorHandler();
  useQueryMessage();

  const { mutateAsync: login, isPending } = useMutation({
    ...tanstackApiClient.mutation('post', '/api/auth/login').mutationOptions,
    onSuccess: async () => {
      const searchParams = new URLSearchParams(location.search);
      const redirectTo = searchParams.get(SearchParamKeys.Redirect);
      if (redirectTo) {
        navigate(redirectTo);
        return;
      }
      navigate('/');
    },
    onError: (error) => {
      if (defaultResponseErrorHandler(error, { disableUnauthorizedHandling: true })) return;
      if (error instanceof AxiosError && error.status === 401) {
        toast.error('Invalid username or password.', {
          position: 'top-center',
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: false,
          progress: undefined,
          theme: 'colored',
        });
        return;
      }
      console.error('Login failed:', error);
    },
  });

  const form = formHook.useAppForm({
    defaultValues: {
      username: '',
      password: '',
    },
    validators: {
      onBlur: loginFormSchema,
      onSubmit: loginFormSchema,
    },

    onSubmit: async ({ value }) => {
      toast.dismiss();
      return await login({ body: { password: value.password, username: value.username } }).catch(() => {});
    },
  });

  return (
    <>
      <Flex align="center" justify="center" style={{ minHeight: 'calc(100vh - 64px)' }}>
        <Container size="3" p="0">
          <Box
            style={{
              display: 'flex',
              flexDirection: 'column',
              maxWidth: 420,
              margin: '40px auto',
              backgroundColor: 'white',
              padding: 24,
              borderRadius: 8,
              boxShadow: '0 6px 18px rgba(15,23,42,0.2)',
            }}
          >
            <Heading size="6" style={{ marginBottom: 16, alignSelf: 'center' }}>
              Sign In
            </Heading>
            <form
              onSubmit={(e) => {
                e.preventDefault();
                form.handleSubmit();
              }}
            >
              <form.AppField
                name="username"
                children={(field) => (
                  <>
                    <field.TextField
                      label={'Username'}
                      value={field.state.value}
                      autoComplete="username"
                      spellCheck={false}
                      required
                      onChange={(e) => field.handleChange(e.target.value)}
                    />
                    <field.TextFieldErrorMessage {...field.state.meta} />
                  </>
                )}
              />

              <form.AppField
                name="password"
                children={(field) => (
                  <>
                    <field.TextField
                      label={'Password'}
                      value={field.state.value}
                      type="password"
                      required
                      autoComplete="current-password"
                      onChange={(e) => field.handleChange(e.target.value)}
                      showPasswordToggle
                    />
                    <field.TextFieldErrorMessage {...field.state.meta} />
                  </>
                )}
              />

              <div style={{ marginTop: 18, display: 'flex', gap: 8, justifySelf: 'center' }}>
                <form.SubmitButton
                  loading={isPending}
                  label={{
                    default: 'Sign In',
                    loading: 'Signing In…',
                  }}
                />
              </div>
            </form>
          </Box>
        </Container>
      </Flex>
    </>
  );
}
