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';
import ConnectedEntityNotice from '../components/ConnectedEntityNotice';

type PublicTenantOption = {
  id: string;
  name?: string;
  slug?: string;
  primary_domain?: string;
  timezone?: string;
  default_currency?: string;
  is_active?: boolean;
};

type PublicOrganizationOption = {
  id: string;
  name: string;
  linkedTenants?: PublicTenantOption[];
  linkedTenantNames?: string[];
  primaryTenant?: PublicTenantOption | null;
};

type OrganizationSelectOption = {
  value: string;
  label: string;
  organization: PublicOrganizationOption;
};

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

  React.useEffect(() => {
    const fetchOrganizations = async () => {
      try {
        const response = await axios.get('/org-for-auth');
        setOrganizations(Array.isArray(response.data) ? response.data : []);
      } catch (error) {
        console.error('Failed to load organizations for signup:', error);
      }
    };

    fetchOrganizations();
  }, []);

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

  const selectedOrganizationRecord = selectedOrganization?.organization || null;
  const selectedTenants = selectedOrganizationRecord?.linkedTenants || [];

  const handleSubmit = async (value) => {
    if (!selectedOrganization) {
      notify('error', 'Please select your organization before creating the account.');
      return;
    }

    if (value.password !== value.confirm) {
      notify('error', 'Password and confirmation must match.');
      return;
    }

    setLoading(true);

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

      await axios.post('/auth/signup', formData);

      const tenantNames = selectedTenants
        .map((tenant) => tenant?.name)
        .filter(Boolean)
        .join(' | ');

      await router.push({
        pathname: '/login',
        query: {
          registeredOrg: selectedOrganizationRecord?.name || selectedOrganization.label,
          registeredRole: 'customer',
          ...(tenantNames ? { registeredTenants: tenantNames } : {}),
        },
      });
    } catch (error) {
      console.error('Signup failed:', error);
      notify('error', 'Something was wrong. Try again.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Register')}</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="mb-2 block font-bold">Organization</label>

              <Select<OrganizationSelectOption, false>
                classNames={{
                  control: () => 'px-1 mb-4 py-2',
                }}
                value={selectedOrganization}
                onChange={(option) => setSelectedOrganization(option)}
                options={options}
                placeholder="Select organization..."
              />

              {selectedOrganizationRecord ? (
                <ConnectedEntityNotice
                  title="Account context"
                  description={
                    <div className="space-y-3">
                      <p>
                        Self-signup creates a <span className="font-semibold">Customer</span> account inside{' '}
                        <span className="font-semibold">{selectedOrganizationRecord.name}</span>.
                      </p>
                      <div>
                        <p className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-blue-800 dark:text-blue-200">
                          Linked tenant preview
                        </p>
                        {selectedTenants.length ? (
                          <div className="flex flex-wrap gap-2">
                            {selectedTenants.map((tenant) => (
                              <span
                                key={tenant.id}
                                className="inline-flex items-center rounded-full border border-blue-200 bg-white/80 px-3 py-1 text-xs font-medium text-blue-900 dark:border-blue-800 dark:bg-blue-900/40 dark:text-blue-100"
                              >
                                {tenant.name || 'Unnamed tenant'}
                              </span>
                            ))}
                          </div>
                        ) : (
                          <p className="text-sm text-blue-800 dark:text-blue-100">
                            No linked tenant is visible for this organization yet.
                          </p>
                        )}
                      </div>
                      <p className="text-xs text-blue-800 dark:text-blue-100">
                        Admin and Super Admin accounts are created internally by an existing privileged user.
                      </p>
                    </div>
                  }
                />
              ) : null}

              <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" />
                <BaseButton href={'/login'} label={'Login'} color="info" />
              </BaseButtons>
            </Form>
          </Formik>
        </CardBox>
      </SectionFullScreen>
      <ToastContainer />
    </>
  );
}

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