import { Form, Formik, Field } from 'formik';
import React, { useContext, useEffect, useState } from 'react';
import { applyAccessToken, axiosInstance } from '../../../axiosApi';
import { setTokens } from '../../auth/tokenStorage';
import { AuthContext } from '../../contexts/AuthContext';
import { Link, useNavigate } from 'react-router-dom';
import { AccountContext } from '../../contexts/AccountContext';
import { AxiosResponse } from 'axios';
import { Account, AccountType } from '../../data';
import ParticleBackground from '../../components/ParticleBackground/ParticleBackground';
import SsoButtons, { OAuthProviderFlags } from '../../components/SsoButtons/SsoButtons';
import { AnalyticsEvents, identifyAccount, trackEvent } from '../../utils/analytics';
import { checkoutReturnUrls } from '../../utils/finance';
import { isNativePlatform } from '../../platform/nativePlatform';
import { logInRevenueCat, purchasePlan } from '../../utils/revenueCat';
import styled from 'styled-components';
import * as Yup from 'yup';
import hesychiaMark from '../../assets/brand/hesychia-mark.png';

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: 0.5rem;
  color: #fff;
  text-align: center;
`;

const BrandMark = styled.img`
  width: 4rem;
  height: 4rem;
  margin-bottom: 1.25rem;
  border-radius: 50%;
`;

const CardSubtitle = styled.p`
  color: rgba(255, 255, 255, 0.65);
  text-align: center;
  margin-bottom: 2rem;
  font-size: 0.95rem;
`;

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 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%;
`;

const NavLink = styled(Link)`
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.6);
  margin-top: 1.5rem;
  cursor: pointer;
  font-size: 0.9rem;
  transition: color 0.2s ease;
  text-decoration: none;

  &:hover {
    color: #fff;
    text-decoration: underline;
  }
`;

const FieldError = styled.div`
  color: #ff6b6b;
  font-size: 0.8rem;
  margin-top: -1.2rem;
  margin-bottom: 1rem;
`;

export type SignUpValues = {
  email: string;
  password: string;
  confirmPassword: string;
  first_name: string;
  last_name: string;
  company_name: string;
};

const validationSchema = Yup.object().shape({
  email: Yup.string().email('Invalid email').required('Required'),
  password: Yup.string().min(8, 'Password must be at least 8 characters').required('Required'),
  confirmPassword: Yup.string()
    .oneOf([Yup.ref('password')], 'Passwords must match')
    .required('Required'),
  first_name: Yup.string(),
  last_name: Yup.string(),
  company_name: Yup.string(),
});

const SignUp = (): JSX.Element => {
  const navigate = useNavigate();
  const { setAuthentication, setNeedsNewPassword } = useContext(AuthContext);
  const { setAccount } = useContext(AccountContext);
  const [errorMessage, setErrorMessage] = useState<string>('');
  const [registrationEnabled, setRegistrationEnabled] = useState<boolean | null>(null);
  const [oauthProviders, setOauthProviders] = useState<OAuthProviderFlags>({});

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const response = await axiosInstance.get('/public/settings/');
        if (!cancelled) {
          setRegistrationEnabled(Boolean(response.data?.enable_account_registration));
          setOauthProviders({
            google: Boolean(response.data?.oauth?.google),
            microsoft: Boolean(response.data?.oauth?.microsoft),
          });
        }
      } catch {
        if (!cancelled) {
          setRegistrationEnabled(false);
          setOauthProviders({});
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  const loadAccount = async (): Promise<Account> => {
    const get_user_response: AxiosResponse<AccountType> = await axiosInstance.get('/user/get/');
    const account = new Account({
      id: get_user_response.data.id,
      email: get_user_response.data.email,
      first_name: get_user_response.data.first_name,
      last_name: get_user_response.data.last_name,
      is_company_manager: get_user_response.data.is_company_manager,
      has_signed_tos: get_user_response.data.has_signed_tos,
      company: {
        id: get_user_response.data.company?.id,
        name: get_user_response.data.company?.name,
        state: get_user_response.data.company?.state,
        zipcode: get_user_response.data.company?.zipcode,
        address: get_user_response.data.company?.address,
      },
    });
    setAccount(account);
    setAuthentication(true);
    setNeedsNewPassword(get_user_response.data.has_usable_password);
    return account;
  };

  const handleSignUp = async (values: SignUpValues): Promise<void> => {
    setErrorMessage('');
    trackEvent(AnalyticsEvents.SIGNUP_STARTED, { method: 'password' });
    try {
      const registerResponse = await axiosInstance.post('/user/create/', {
        email: values.email,
        password: values.password,
        first_name: values.first_name,
        last_name: values.last_name,
        company_name: values.company_name,
      });

      await setTokens(registerResponse.data.access, registerResponse.data.refresh);
      applyAccessToken(registerResponse.data.access);
      const account = await loadAccount();
      trackEvent(AnalyticsEvents.SIGNUP_SUCCESS, { method: 'password' });
      identifyAccount(account);
      void Promise.resolve(logInRevenueCat(account)).catch((err) =>
        console.warn('RevenueCat logIn', err)
      );

      const needsCheckout = registerResponse.data?.needs_checkout !== false;
      if (!needsCheckout) {
        navigate('/');
        return;
      }

      // Native: store IAP via RevenueCat (BillingSection) — skip Stripe Checkout.
      if (isNativePlatform()) {
        try {
          trackEvent(AnalyticsEvents.CHECKOUT_STARTED, { source: 'signup_native' });
          await purchasePlan();
          navigate('/account/');
          return;
        } catch (purchaseError: unknown) {
          console.warn('RevenueCat purchase after signup', purchaseError);
          navigate('/account/');
          return;
        }
      }

      const { success_url, cancel_url } = checkoutReturnUrls();
      trackEvent(AnalyticsEvents.CHECKOUT_STARTED, { source: 'signup' });
      const checkoutResponse = await axiosInstance.post('/monetization/checkout/', {
        success_url,
        cancel_url,
      });

      const checkoutUrl = checkoutResponse.data?.checkout_url;
      if (!checkoutUrl) {
        setErrorMessage('Account created, but checkout could not be started. Try signing in.');
        return;
      }

      window.location.assign(checkoutUrl);
    } catch (error: unknown) {
      console.log(error);
      trackEvent(AnalyticsEvents.SIGNUP_FAILED, { method: 'password' });
      const axiosError = error as {
        response?: { status?: number; data?: { detail?: string; email?: string[] } };
      };
      if (axiosError.response?.status === 403) {
        setErrorMessage('Account registration is currently disabled.');
      } else if (axiosError.response?.data?.email?.[0]) {
        setErrorMessage(axiosError.response.data.email[0]);
      } else if (axiosError.response?.data?.detail) {
        setErrorMessage(String(axiosError.response.data.detail));
      } else {
        setErrorMessage('Could not create account. Try again.');
      }
    }
  };

  if (registrationEnabled === null) {
    return (
      <PageContainer>
        <ParticleBackground />
        <ContentWrapper>
          <GlassCard>
            <BrandMark src={hesychiaMark} alt="Hesychia" />
            <CardTitle>Sign Up</CardTitle>
            <CardSubtitle>Loading…</CardSubtitle>
          </GlassCard>
        </ContentWrapper>
      </PageContainer>
    );
  }

  if (!registrationEnabled) {
    return (
      <PageContainer>
        <ParticleBackground />
        <ContentWrapper>
          <GlassCard>
            <BrandMark src={hesychiaMark} alt="Hesychia" />
            <CardTitle>Sign Up</CardTitle>
            <ErrorMessage>Self-serve registration is not available right now.</ErrorMessage>
            <NavLink to="/signin/">Already have an account? Sign in</NavLink>
          </GlassCard>
        </ContentWrapper>
      </PageContainer>
    );
  }

  return (
    <PageContainer>
      <ParticleBackground />
      <ContentWrapper>
        <GlassCard>
          <BrandMark src={hesychiaMark} alt="Hesychia" />
          <CardTitle>Sign Up</CardTitle>
          <CardSubtitle>Create an account, then complete payment on Stripe.</CardSubtitle>
          {errorMessage && <ErrorMessage>{errorMessage}</ErrorMessage>}
          <Formik
            initialValues={{
              email: '',
              password: '',
              confirmPassword: '',
              first_name: '',
              last_name: '',
              company_name: '',
            }}
            onSubmit={handleSignUp}
            validationSchema={validationSchema}
          >
            {(formik) => (
              <Form style={{ width: '100%' }}>
                <Field as={StyledInput} name="email" placeholder="Email Address" type="email" />
                {formik.touched.email && formik.errors.email && (
                  <FieldError>{formik.errors.email}</FieldError>
                )}
                <Field as={StyledInput} name="first_name" placeholder="First name (optional)" type="text" />
                <Field as={StyledInput} name="last_name" placeholder="Last name (optional)" type="text" />
                <Field
                  as={StyledInput}
                  name="company_name"
                  placeholder="Company / workspace (optional)"
                  type="text"
                />
                <Field as={StyledInput} name="password" placeholder="Password" type="password" />
                {formik.touched.password && formik.errors.password && (
                  <FieldError>{formik.errors.password}</FieldError>
                )}
                <Field
                  as={StyledInput}
                  name="confirmPassword"
                  placeholder="Confirm password"
                  type="password"
                />
                {formik.touched.confirmPassword && formik.errors.confirmPassword && (
                  <FieldError>{formik.errors.confirmPassword}</FieldError>
                )}
                <StyledButton type="submit" disabled={formik.isSubmitting}>
                  {formik.isSubmitting ? 'Creating account…' : 'Sign Up & Pay'}
                </StyledButton>
                <SsoButtons
                  intent="signup"
                  providers={oauthProviders}
                  disabled={formik.isSubmitting}
                />
              </Form>
            )}
          </Formik>
          <NavLink to="/signin/">Already have an account? Sign in</NavLink>
          <NavLink to="/terms_of_service/" style={{ marginTop: '0.75rem' }}>
            Terms of Service
          </NavLink>
        </GlassCard>
      </ContentWrapper>
    </PageContainer>
  );
};

export default SignUp;
