import React from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import { Field, Form, Formik } from 'formik';
import { ToastContainer, toast } from 'react-toastify';
import Select from 'react-select';
import axios from 'axios';

import BaseButton from '../components/BaseButton';
import BaseButtons from '../components/BaseButtons';
import BaseDivider from '../components/BaseDivider';
import CardBox from '../components/CardBox';
import FormField from '../components/FormField';
import SectionFullScreen from '../components/SectionFullScreen';
import LayoutGuest from '../layouts/Guest';
import { getPageTitle } from '../config';
import { useAppSelector } from '../stores/hooks';
import { useRouter } from 'next/router';

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;
};

type RegisterValues = {
  email: string;
  password: string;
  confirm: string;
};

const TITLE = 'Gracey Corporate Stay Portal';
const REGISTER_CHIPS = ['Customer self-signup', 'Organization-linked access', 'Internal admin provisioning'];

const AUTH_INPUT_CLASS = '!bg-white !text-stone-900 placeholder:!text-stone-400 dark:!bg-white dark:!text-stone-900 dark:placeholder:!text-stone-400';

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 textColor = useAppSelector((state) => state.style.linkColor);
  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: RegisterValues) => {
    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'>
        <div className='min-h-screen w-full bg-gradient-to-br from-[#fbf6ee] via-[#f3eadb] to-[#dfc8a5] px-3 py-4 text-stone-900 sm:px-5 sm:py-6 lg:px-8 lg:py-8'>
          <div className='mx-auto flex min-h-[calc(100vh-2rem)] w-full max-w-7xl flex-col overflow-hidden rounded-[2rem] border border-stone-200/90 bg-white/75 shadow-[0_30px_80px_rgba(68,44,23,0.12)] backdrop-blur md:grid md:grid-cols-[1.04fr_0.96fr]'>
            <div className='relative overflow-hidden border-b border-stone-200/80 bg-[linear-gradient(180deg,rgba(255,250,243,0.98),rgba(243,233,216,0.98))] px-5 py-6 sm:px-8 sm:py-8 lg:px-12 lg:py-10 md:border-b-0 md:border-r'>
              <div className='absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(199,152,87,0.18),transparent_28%),radial-gradient(circle_at_bottom_left,rgba(255,255,255,0.85),transparent_34%)]' />

              <div className='relative z-10 flex h-full flex-col justify-between gap-6'>
                <div className='space-y-6 sm:space-y-8'>
                  <div className='space-y-4'>
                    <p className='text-[11px] font-semibold uppercase tracking-[0.34em] text-stone-500'>
                      Customer enrollment
                    </p>
                    <div className='space-y-3'>
                      <h1 className='max-w-2xl text-3xl font-semibold leading-tight text-stone-950 sm:text-[2.55rem]'>
                        Create portal access with the right organization attached.
                      </h1>
                      <p className='max-w-2xl text-sm leading-7 text-stone-700 sm:text-base'>
                        Register a customer account for Gracey and connect it to the correct organization before the
                        first stay request is submitted.
                      </p>
                    </div>
                    <div className='flex flex-wrap gap-2'>
                      {REGISTER_CHIPS.map((chip) => (
                        <span
                          key={chip}
                          className='inline-flex items-center rounded-full border border-stone-200 bg-white/80 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-stone-600'
                        >
                          {chip}
                        </span>
                      ))}
                    </div>
                  </div>

                  <div className='grid gap-3 rounded-[1.75rem] border border-amber-200/70 bg-white/60 p-4 sm:grid-cols-3 sm:p-5'>
                    <div>
                      <p className='text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-800'>
                        Audience
                      </p>
                      <p className='mt-2 text-sm text-stone-700'>Customer-side account setup</p>
                    </div>
                    <div>
                      <p className='text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-800'>
                        Organization scope
                      </p>
                      <p className='mt-2 text-sm text-stone-700'>Attach access to the right company</p>
                    </div>
                    <div>
                      <p className='text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-800'>
                        Admin note
                      </p>
                      <p className='mt-2 text-sm text-stone-700'>Admin roles stay internally provisioned</p>
                    </div>
                  </div>

                  <div className='rounded-[1.75rem] border border-stone-200/90 bg-white/55 p-5'>
                    <div className='flex items-center gap-3'>
                      <span className='h-px w-10 bg-amber-400/80' />
                      <p className='text-xs font-semibold uppercase tracking-[0.28em] text-stone-600'>Enrollment notes</p>
                    </div>

                    <div className='mt-4 space-y-4 text-sm leading-7 text-stone-700'>
                      <p>
                        Select the organization that should own the account. This keeps customer access tied to the
                        right operating context from the start.
                      </p>
                      <p>
                        Linked tenants, if available, become visible after account creation so the login experience
                        stays consistent with the workspace structure.
                      </p>
                      <p className='text-stone-600'>
                        Need admin or concierge access instead? Those roles should be created internally rather than
                        through public signup.
                      </p>
                    </div>
                  </div>
                </div>

                <div className='rounded-[1.5rem] border border-stone-200/90 bg-white/55 p-4 text-sm leading-6 text-stone-600'>
                  Gracey keeps public account creation narrow on purpose: clear audience, clear tenant context, and a
                  quieter path into the authenticated workspace.
                </div>
              </div>
            </div>

            <div className='flex items-center justify-center bg-[linear-gradient(180deg,rgba(255,255,255,0.74),rgba(255,250,242,0.96))] px-4 py-6 sm:px-8 sm:py-8 lg:px-10 lg:py-10'>
              <div className='w-full max-w-xl space-y-5 sm:space-y-6'>
                <CardBox className='border border-stone-200/90 bg-white/95 text-stone-950 shadow-[0_22px_55px_rgba(60,38,20,0.08)] dark:!border-stone-200 dark:!bg-white dark:!text-stone-950'>
                  <div className='space-y-5 sm:space-y-6'>
                    <div className='space-y-3'>
                      <p className='text-xs font-semibold uppercase tracking-[0.28em] text-stone-500'>Customer access</p>
                      <h2 className='text-3xl font-semibold text-stone-950'>Create your account</h2>
                      <p className='text-sm leading-6 text-stone-600'>
                        Set your portal credentials and attach them to the right organization before your first stay
                        request begins.
                      </p>
                      <div className='flex flex-wrap gap-2 pt-1'>
                        {REGISTER_CHIPS.map((chip) => (
                          <span
                            key={chip}
                            className='inline-flex items-center rounded-full border border-stone-200 bg-stone-50 px-3 py-1 text-[11px] font-medium text-stone-600'
                          >
                            {chip}
                          </span>
                        ))}
                      </div>
                    </div>

                    {selectedOrganizationRecord ? (
                      <div className='rounded-[1.25rem] border border-amber-200/80 bg-amber-50/80 p-4 text-sm text-stone-700'>
                        <p className='text-[11px] font-semibold uppercase tracking-[0.22em] text-amber-800'>
                          Account context
                        </p>
                        <p className='mt-2 leading-6'>
                          This signup creates a <span className='font-semibold'>Customer</span> account inside{' '}
                          <span className='font-semibold'>{selectedOrganizationRecord.name}</span>.
                        </p>
                      </div>
                    ) : null}

                    <Formik
                      initialValues={{
                        email: '',
                        password: '',
                        confirm: '',
                      }}
                      onSubmit={(values) => handleSubmit(values)}
                    >
                      <Form>
                        <div className='mb-4'>
                          <label className='mb-2 block text-sm font-semibold text-stone-700'>Organization</label>
                          <Select<OrganizationSelectOption, false>
                            classNames={{
                              control: ({ isFocused }) =>
                                `min-h-[42px] rounded-lg border bg-white px-2 py-1 text-sm shadow-none ${
                                  isFocused
                                    ? 'border-stone-900 ring-1 ring-stone-900'
                                    : 'border-stone-300 hover:border-stone-400'
                                }`,
                              menu: () => 'overflow-hidden rounded-xl border border-stone-200 bg-white shadow-xl',
                              menuList: () => 'p-2',
                              option: ({ isFocused, isSelected }) =>
                                `cursor-pointer rounded-lg px-3 py-2 text-sm ${
                                  isSelected
                                    ? 'bg-stone-900 text-white'
                                    : isFocused
                                      ? 'bg-amber-50 text-stone-900'
                                      : 'text-stone-700'
                                }`,
                              placeholder: () => 'text-stone-400',
                              singleValue: () => 'text-stone-900',
                              indicatorSeparator: () => 'hidden',
                              dropdownIndicator: () => 'text-stone-500',
                            }}
                            value={selectedOrganization}
                            onChange={(option) => setSelectedOrganization(option)}
                            options={options}
                            placeholder='Select organization...'
                          />
                        </div>

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

                        <BaseDivider />

                        <BaseButtons className='w-full' type='justify-center' classAddon='mb-3' mb='mb-0'>
                          <BaseButton
                            className='w-full justify-center border-[#4d3929] bg-[#4d3929] text-white hover:bg-[#3d2d21] focus:ring-amber-300'
                            type='submit'
                            label={loading ? 'Loading...' : 'Register'}
                            color='white'
                            disabled={loading}
                          />
                        </BaseButtons>

                        <div className='flex flex-col items-center gap-3 text-center sm:flex-row sm:justify-between sm:text-left'>
                          <p className='text-sm text-stone-600'>Already have credentials?</p>
                          <Link className={`${textColor} text-sm font-medium`} href='/login'>
                            Return to Login
                          </Link>
                        </div>
                      </Form>
                    </Formik>
                  </div>
                </CardBox>

                <div className='flex flex-col items-center justify-center gap-3 border-t border-stone-200 pt-1 text-center text-sm text-stone-600 sm:flex-row'>
                  <p>© 2026 {TITLE}. © All rights reserved</p>
                  <div className='flex flex-wrap items-center justify-center gap-4'>
                    <Link className={`${textColor} text-sm`} href='/privacy-policy/'>
                      Privacy Policy
                    </Link>
                    <Link className={`${textColor} text-sm`} href='/terms-of-use/'>
                      Terms of Use
                    </Link>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </SectionFullScreen>

      <ToastContainer />
    </>
  );
}

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