import React from 'react';
import type { ReactElement } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import Head from 'next/head';
import BaseButton from '../components/BaseButton';
import CardBox from '../components/CardBox';
import SectionFullScreen from '../components/SectionFullScreen';
import LayoutGuest from '../layouts/Guest';
import { Field, Form, Formik } from 'formik';
import FormField from '../components/FormField';
import BaseDivider from '../components/BaseDivider';
import BaseButtons from '../components/BaseButtons';
import { useRouter } from 'next/router';
import { getPageTitle } from '../config';
import Select from 'react-select';
import axios from 'axios';

type OrganizationOption = {
  value: string;
  label: string;
};

type OrganizationResponse = {
  id: string;
  name: string;
};

export default function Register() {
  const [loading, setLoading] = React.useState(false);
  const [organizations, setOrganizations] = React.useState<OrganizationResponse[]>([]);
  const [selectedOrganization, setSelectedOrganization] = React.useState<OrganizationOption | null>(null);
  const [tenantError, setTenantError] = React.useState('');
  const router = useRouter();
  const notify = (type, msg) => toast(msg, { type, position: 'bottom-center' });

  React.useEffect(() => {
    let isMounted = true;

    const fetchOrganizations = async () => {
      try {
        const response = await axios.get('/org-for-auth');
        const fetchedOrganizations = Array.isArray(response.data) ? response.data : [];

        if (!isMounted) {
          return;
        }

        setOrganizations(fetchedOrganizations);
        setTenantError('');

        if (fetchedOrganizations[0]) {
          setSelectedOrganization({
            value: fetchedOrganizations[0].id,
            label: fetchedOrganizations[0].name,
          });
        }
      } catch (error) {
        console.error(error?.response || error);

        if (!isMounted) {
          return;
        }

        const message =
          typeof error?.response?.data === 'string'
            ? error.response.data
            : 'Registration is only available from a valid tenant subdomain.';

        setOrganizations([]);
        setSelectedOrganization(null);
        setTenantError(message);
      }
    };

    fetchOrganizations();

    return () => {
      isMounted = false;
    };
  }, []);

  const options = organizations.map((org) => ({
    value: org.id,
    label: org.name,
  }));

  const handleSubmit = async (value) => {
    if (!selectedOrganization?.value) {
      notify('error', tenantError || 'No tenant organization is available for registration.');
      return;
    }

    setLoading(true);

    try {
      const formData = {
        ...value,
        organizationsId: selectedOrganization.value,
      };

      await axios.post('/auth/signup', formData);
      notify('success', 'Please check your email for verification link');
      await router.push('/login');
    } catch (error) {
      console.error('register error:', error?.response || error);
      const message =
        typeof error?.response?.data === 'string'
          ? error.response.data
          : 'Something went wrong. Try again.';
      notify('error', message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Login')}</title>
      </Head>

      <SectionFullScreen bg='violet'>
        <CardBox className='w-11/12 md:w-7/12 lg:w-6/12 xl:w-4/12'>
          <Formik
            initialValues={{
              email: '',
              password: '',
              confirm: '',
            }}
            onSubmit={(values) => handleSubmit(values)}
          >
            <Form>
              <label className='block font-bold mb-2'>Organization</label>

              <Select
                classNames={{
                  control: () => 'px-1 mb-4 py-2',
                }}
                value={selectedOrganization}
                onChange={(option) => setSelectedOrganization(option as OrganizationOption | null)}
                options={options}
                placeholder='Tenant organization'
                isDisabled={loading || options.length <= 1}
              />

              {tenantError && <p className='text-sm text-red-600 mb-4'>{tenantError}</p>}

              <FormField label='Email' help='Please enter your email'>
                <Field type='email' name='email' />
              </FormField>
              <FormField label='Password' help='Please enter your password'>
                <Field type='password' name='password' />
              </FormField>
              <FormField label='Confirm Password' help='Please confirm your password'>
                <Field type='password' name='confirm' />
              </FormField>

              <BaseDivider />

              <BaseButtons>
                <BaseButton
                  type='submit'
                  label={loading ? 'Loading...' : 'Register'}
                  color='info'
                  disabled={loading || !selectedOrganization?.value}
                />
                <BaseButton href='/login' label='Login' color='info' />
              </BaseButtons>
            </Form>
          </Formik>
        </CardBox>
      </SectionFullScreen>
      <ToastContainer />
    </>
  );
}

Register.getLayout = function getLayout(page: ReactElement) {
  return <LayoutGuest>{page}</LayoutGuest>;
};
