import { Form, Formik, Field } from 'formik';
import React, { useEffect, useState } from 'react';
import { cleanAxiosInstance } from '../../../axiosApi';
import { useNavigate, useSearchParams } from 'react-router-dom';
import ParticleBackground from '../ParticleBackground/ParticleBackground';
import styled from 'styled-components';
import * as Yup from 'yup';

const PageContainer = styled.div`
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  color: #fff;
  font-family: 'Inter', sans-serif;
`;

const ContentWrapper = styled.div`
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 5;
  padding: 2rem;
`;

const GlassCard = styled.div`
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 1rem;
  padding: 3rem;
  width: 100%;
  max-width: 450px;
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
  display: flex;
  flex-direction: column;
  align-items: center;
`;

const CardTitle = styled.h2`
  font-size: 2rem;
  margin-bottom: 2rem;
  color: #fff;
  text-align: center;
`;

const StyledInput = styled.input`
  width: 100%;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0.5rem;
  padding: 1rem;
  color: #fff;
  font-size: 1rem;
  outline: none;
  transition: all 0.3s ease;
  margin-bottom: 1.5rem;

  &:focus {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(100, 149, 237, 0.5);
    box-shadow: 0 0 10px rgba(100, 149, 237, 0.2);
  }

  &::placeholder {
    color: rgba(255, 255, 255, 0.5);
  }
`;

const StyledButton = styled.button`
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  border-radius: 0.5rem;
  color: #fff;
  padding: 1rem;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.2s ease;
  width: 100%;
  margin-top: 1rem;

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(118, 75, 162, 0.4);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
  }
`;

const HintList = styled.ul`
  list-style: none;
  padding: 0;
  margin: 0 0 0.5rem;
  width: 100%;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.7);
`;

const HintItem = styled.li<{ $ok: boolean }>`
  margin-bottom: 0.35rem;
  color: ${(props) => (props.$ok ? '#7dcea0' : 'rgba(255, 255, 255, 0.55)')};
`;

const ErrorMessage = styled.div`
  color: #ff6b6b;
  margin-bottom: 1rem;
  text-align: center;
  background: rgba(255, 107, 107, 0.1);
  padding: 0.5rem;
  border-radius: 0.5rem;
  width: 100%;
`;

export type PasswordResetValues = {
  password1: string;
  password2: string;
};

const validationSchema = Yup.object().shape({
  password1: Yup.string()
    .min(8, 'Passwords must be at least 8 characters')
    .matches(/[0-9]/, 'Must include a number')
    .matches(/[^A-Za-z0-9]/, 'Must include a special character')
    .required('Required'),
  password2: Yup.string()
    .oneOf([Yup.ref('password1')], 'Passwords must match')
    .required('Required'),
});

const SetPassword = (): JSX.Element => {
  const navigate = useNavigate();
  const [queryParameters] = useSearchParams();
  const slug = queryParameters.get('slug');
  const [linkValid, setLinkValid] = useState(false);
  const [checking, setChecking] = useState(true);
  const [errorMessage, setErrorMessage] = useState('');

  useEffect(() => {
    let cancelled = false;

    (async () => {
      if (!slug) {
        navigate('/signin/');
        return;
      }
      try {
        await cleanAxiosInstance.get(`user/set_password/${slug}/`);
        if (!cancelled) {
          setLinkValid(true);
        }
      } catch {
        if (!cancelled) {
          navigate('/signin/');
        }
      } finally {
        if (!cancelled) {
          setChecking(false);
        }
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [slug, navigate]);

  const handleSetPassword = async ({
    password1,
  }: PasswordResetValues): Promise<void> => {
    setErrorMessage('');
    try {
      await cleanAxiosInstance.post(`user/set_password/${slug}/`, {
        password: password1,
      });
      navigate('/signin/');
    } catch {
      setErrorMessage('Unable to set password. Please try again.');
    }
  };

  if (checking || !linkValid) {
    return (
      <PageContainer>
        <ParticleBackground />
        <ContentWrapper>
          <GlassCard>
            <CardTitle>Loading…</CardTitle>
          </GlassCard>
        </ContentWrapper>
      </PageContainer>
    );
  }

  return (
    <PageContainer>
      <ParticleBackground />
      <ContentWrapper>
        <GlassCard>
          <CardTitle>Set Your Password</CardTitle>
          {errorMessage && <ErrorMessage>{errorMessage}</ErrorMessage>}
          <Formik
            initialValues={{ password1: '', password2: '' }}
            onSubmit={handleSetPassword}
            validationSchema={validationSchema}
            validateOnMount
          >
            {(formik) => (
              <Form style={{ width: '100%' }}>
                <Field
                  as={StyledInput}
                  name="password1"
                  placeholder="New Password"
                  type="password"
                />
                <Field
                  as={StyledInput}
                  name="password2"
                  placeholder="Confirm Password"
                  type="password"
                />
                <HintList>
                  <HintItem $ok={formik.values.password1.length >= 8}>
                    At least 8 characters
                  </HintItem>
                  <HintItem $ok={/[0-9]/.test(formik.values.password1)}>
                    At least one number
                  </HintItem>
                  <HintItem $ok={/[^A-Za-z0-9]/.test(formik.values.password1)}>
                    At least one special character
                  </HintItem>
                  <HintItem
                    $ok={
                      formik.values.password1.length > 0 &&
                      formik.values.password1 === formik.values.password2
                    }
                  >
                    Passwords match
                  </HintItem>
                </HintList>
                <StyledButton
                  type="submit"
                  disabled={!formik.isValid || formik.isSubmitting}
                >
                  Set Password
                </StyledButton>
              </Form>
            )}
          </Formik>
        </GlassCard>
      </ContentWrapper>
    </PageContainer>
  );
};

export default SetPassword;
