'use client';

import { Suspense, useEffect, useMemo, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Link, useRouter } from '@/i18n/navigation';
import { useSearchParams } from 'next/navigation';
import { useForm, type FieldErrors, type UseFormRegister, type UseFormSetValue } from 'react-hook-form';
import type { OrganizationDetailsFormValues } from '@/components/ui/auth/OrganizationDetailsFields';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { Lock, Mail, User } from 'lucide-react';
import { AuthPageShell } from '@/components/ui/auth/AuthPageShell';
import { BrandLockup } from '@/components/ui/shared/BrandLockup';
import { Button } from '@/components/ui/shared/Button';
import { Input } from '@/components/ui/shared/Input';
import { OrganizationDetailsFields } from '@/components/ui/auth/OrganizationDetailsFields';
import { RegistrationProgressSteps } from '@/components/ui/auth/RegistrationProgressSteps';
import { getUserFacingError } from '@/components/shared/formatApiError';
import { organizationApi } from '@/lib/api/organization';
import { useAuth } from '@/lib/hooks/useAuth';
import { navigateIntoAppIfOrgSelected } from '@/lib/auth/postAuthRedirect';

type AcceptOrganizationInviteForm = {
  ownerName: string;
  password: string;
  confirmPassword: string;
  organizationName: string;
  organizationEmail: string;
  organizationType: 'CLINIC' | 'LAB';
};

function AcceptOrganizationInviteContent() {
  const t = useTranslations('auth');
  const tErrors = useTranslations('errors');
  const tCommon = useTranslations('common');
  const tValidation = useTranslations('validation');
  const params = useSearchParams();
  const router = useRouter();
  const { login } = useAuth();
  const token = useMemo(() => params.get('token') || '', [params]);

  const acceptOrganizationInviteSchema = useMemo(
    () =>
      z
        .object({
          ownerName: z.string().min(2, tValidation('nameMinLength')),
          password: z
            .string()
            .min(8, tValidation('passwordMinLength'))
            .regex(/[A-Z]/, tValidation('passwordUppercase'))
            .regex(/[0-9]/, tValidation('passwordNumber')),
          confirmPassword: z.string(),
          organizationName: z.string().min(2, tValidation('organizationNameMinLength')),
          organizationEmail: z.string().email(tValidation('organizationEmailInvalid')),
          organizationType: z.enum(['CLINIC', 'LAB'], {
            message: tValidation('organizationTypeRequired'),
          }),
        })
        .refine((data) => data.password === data.confirmPassword, {
          message: tValidation('passwordsDoNotMatch'),
          path: ['confirmPassword'],
        }),
    [tValidation],
  );

  const [step, setStep] = useState(1);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [inviteInfo, setInviteInfo] = useState<{
    ownerEmail: string;
    organizationName: string;
    organizationType: 'CLINIC' | 'LAB';
    organizationEmail?: string;
    inviterOrganizationName: string;
    expiresAt: string;
    status: 'PENDING' | 'ACCEPTED';
  } | null>(null);

  const {
    register,
    handleSubmit,
    watch,
    trigger,
    setValue,
    reset,
    formState: { errors },
  } = useForm<AcceptOrganizationInviteForm>({
    resolver: zodResolver(acceptOrganizationInviteSchema),
    mode: 'onChange',
    defaultValues: {
      organizationType: undefined,
    },
  });

  const organizationType = watch('organizationType');

  useEffect(() => {
    if (!token) {
      setLoading(false);
      setError(t('invalidInvitationLink'));
      return;
    }

    void (async () => {
      setLoading(true);
      setError('');
      try {
        const res = await organizationApi.previewInvite(token);
        setInviteInfo(res.data);
        reset({
          ownerName: '',
          password: '',
          confirmPassword: '',
          organizationName: res.data.organizationName || '',
          organizationEmail: res.data.organizationEmail || '',
          organizationType: res.data.organizationType,
        });
        if (res.data.status === 'ACCEPTED') {
          setSuccess(t('invitationAlreadyAccepted'));
        }
      } catch (e: unknown) {
        setError(getUserFacingError(e, tErrors, t('errorLoadInvitation')));
      } finally {
        setLoading(false);
      }
    })();
  }, [token, reset, t]);

  const handleNext = async () => {
    const isValid = await trigger(['ownerName', 'password', 'confirmPassword']);
    if (isValid) {
      setStep(2);
      setError('');
    }
  };

  const onSubmit = async (data: AcceptOrganizationInviteForm) => {
    if (!token) return;
    setError('');
    setSuccess('');
    setSubmitting(true);
    let accepted = false;
    try {
      await organizationApi.acceptInvite({
        token,
        ownerName: data.ownerName.trim(),
        password: data.password,
        organizationName: data.organizationName.trim(),
        organizationEmail: data.organizationEmail.trim(),
        organizationType: data.organizationType,
      });
      accepted = true;
      const email = inviteInfo?.ownerEmail?.trim();
      if (!email) {
        throw new Error('missing-invite-email');
      }
      const { organizations } = await login(email, data.password);
      navigateIntoAppIfOrgSelected((href) => router.replace(href), organizations.length);
    } catch (e: unknown) {
      if (accepted) {
        setSuccess(t('invitationAcceptedSignInFailed'));
        setTimeout(() => router.replace('/login'), 1500);
      } else {
        setError(getUserFacingError(e, tErrors, t('errorAcceptInvitation')));
      }
    } finally {
      setSubmitting(false);
    }
  };

  const passwordToggleLabels = {
    show: t('showPassword'),
    hide: t('hidePassword'),
  };

  return (
    <AuthPageShell
      header={
        <>
          <Link href="/" className="flex justify-center">
            <BrandLockup className="text-2xl sm:text-3xl text-text-primary" />
          </Link>
          <h2 className="mt-4 sm:mt-6 text-center text-2xl sm:text-3xl font-semibold text-text-primary">
            {t('acceptOrganizationTitle')}
          </h2>
          <p className="mt-2 text-center text-sm text-text-secondary">
            {t('alreadyHaveAccount')}{' '}
            <Link href="/login" className="font-medium text-primary hover:opacity-90">
              {t('signInLink')}
            </Link>
          </p>
        </>
      }
    >
      <div className="surface-card py-6 sm:py-8 px-4 sm:px-10">
        {loading ? (
          <p className="text-sm text-text-secondary">{t('loadingInvitation')}</p>
        ) : (
          <>
            {inviteInfo && (
              <div className="mb-5 sm:mb-6 rounded-[var(--radius-md)] border border-border/70 bg-background-secondary/70 px-3 py-2 text-sm text-text-secondary space-y-1">
                <p>
                  {t('invitedBy')}{' '}
                  <span className="text-text-primary">{inviteInfo.inviterOrganizationName}</span>
                </p>
              </div>
            )}

            {inviteInfo?.status !== 'ACCEPTED' && <RegistrationProgressSteps step={step} />}

            {error && (
              <div className="mb-4 p-3 bg-red-950/30 border border-red-600/40 rounded-[var(--radius-md)]">
                <p className="text-sm text-red-400">{error}</p>
              </div>
            )}
            {success && (
              <div className="mb-4 rounded-[var(--radius-md)] border border-primary/30 bg-primary-soft/40 px-3 py-2 text-sm text-text-primary">
                {success}
              </div>
            )}

            {inviteInfo?.status !== 'ACCEPTED' && (
              <form onSubmit={handleSubmit(onSubmit)} className="space-y-5 sm:space-y-6">
                {step === 1 && (
                  <>
                    <Input
                      label={t('ownerEmail')}
                      value={inviteInfo?.ownerEmail ?? ''}
                      readOnly
                      disabled
                      icon={<Mail className="h-5 w-5 icon-flat" />}
                    />
                    <Input
                      label={t('fullName')}
                      {...register('ownerName')}
                      placeholder={t('namePlaceholder')}
                      error={errors.ownerName?.message}
                      icon={<User className="h-5 w-5 icon-flat" />}
                    />
                    <Input
                      label={t('password')}
                      {...register('password')}
                      type="password"
                      placeholder={t('passwordPlaceholder')}
                      error={errors.password?.message}
                      icon={<Lock className="h-5 w-5 icon-flat" />}
                      passwordToggleLabels={passwordToggleLabels}
                    />
                    <Input
                      label={t('confirmPassword')}
                      {...register('confirmPassword')}
                      type="password"
                      placeholder={t('passwordPlaceholder')}
                      error={errors.confirmPassword?.message}
                      icon={<Lock className="h-5 w-5 icon-flat" />}
                      passwordToggleLabels={passwordToggleLabels}
                    />
                    <Button type="button" variant="primary" onClick={() => handleNext()} fullWidth>
                      {tCommon('continue')}
                    </Button>
                  </>
                )}

                {step === 2 && (
                  <>
                    <OrganizationDetailsFields
                      register={register as unknown as UseFormRegister<OrganizationDetailsFormValues>}
                      errors={errors as FieldErrors<OrganizationDetailsFormValues>}
                      organizationType={organizationType}
                      setValue={setValue as unknown as UseFormSetValue<OrganizationDetailsFormValues>}
                    />
                    <div className="flex flex-col-reverse gap-3 sm:flex-row">
                      <Button type="button" variant="outline" onClick={() => setStep(1)}>
                        {tCommon('back')}
                      </Button>
                      <Button type="submit" variant="primary" isLoading={submitting} fullWidth>
                        {t('activateOrganization')}
                      </Button>
                    </div>
                  </>
                )}
              </form>
            )}
          </>
        )}
      </div>
    </AuthPageShell>
  );
}

function AcceptOrganizationInviteFallback() {
  const t = useTranslations('auth');
  return (
    <div className="min-h-[100dvh] app-web-bg flex items-center justify-center px-4">
      <p className="text-sm text-text-secondary">{t('loadingInvitation')}</p>
    </div>
  );
}

export default function AcceptOrganizationInvitePage() {
  return (
    <Suspense fallback={<AcceptOrganizationInviteFallback />}>
      <AcceptOrganizationInviteContent />
    </Suspense>
  );
}
