import { auth }                         from "@/auth";
import { VerifyEmailCard }              from '@/components/verify-email-card';
import { VerifyEmailConfirmationCard }  from '@/components/verify-email-confirmation-card';
import { headers }                      from 'next/headers';
import { redirect }                     from 'next/navigation';
import { getOption, setOption } from '@/lib/option';

export default async function Page({
  searchParams
}: {
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
  const { token } = await searchParams;

  if (typeof token === 'string' && token.length > 0) {
    try {
      const verifyEmail = await auth.api.verifyEmail({
        query: {
          token: token
        }
      });

      return <VerifyEmailConfirmationCard pass={verifyEmail?.status ?? false} />
    } catch (error) {
      return <VerifyEmailConfirmationCard pass={false} />
    }
  }

  const session = await auth.api.getSession({ headers: await headers() });

  if (!session?.user.email) {
    redirect('/login');
  }

  if (session.user.emailVerified) {
    redirect('/dashboard');
  }

  const lastSendOption = await getOption('email_verification_last_send', session.user.id);
  
  let lastSend = 0;
  let count = 0;

  if (lastSendOption) {
    try {
      const opt = JSON.parse(lastSendOption) as { lastSend: string, count: number };
      lastSend = new Date(opt.lastSend).getTime();
      count = typeof opt.count === 'number' ? opt.count : 1;
    } catch (e) {
      lastSend = new Date(lastSendOption).getTime();
      count = 1;
    }
  }

  const cooldownConfig = {
    strategy: 'multiply', // Options: 'multiply' or 'add'
    factor: 2,            // Multiplier (e.g., 2) or Addition in ms (e.g., 60000)
    base: 5 * 60 * 1000,  // Initial cooldown: 5 minutes
    max: 60 * 60 * 1000   // Maximum cooldown: 1 hour (0 for infinity)
  };

  const calculateCooldown = (cnt: number): number => {
    if (cnt <= 0) return 0;
    let duration = cooldownConfig.base;
    if (cooldownConfig.strategy === 'multiply') {
      duration = cooldownConfig.base * Math.pow(cooldownConfig.factor, cnt - 1);
    } else {
      duration = cooldownConfig.base + (cooldownConfig.factor * (cnt - 1));
    }

    return (cooldownConfig.max === 0) ? duration : Math.min(duration, cooldownConfig.max);
  };

  let cooldown = calculateCooldown(count);

  if (lastSend === 0 || ((Date.now() - lastSend) > cooldown)) {
    await auth.api.sendVerificationEmail({
      body: {
        email: session.user.email,
        callbackURL: undefined,
      },
      headers: await headers(),
    });

    const lastSendTime = new Date();
    count++;

    await setOption('email_verification_last_send', JSON.stringify({
      lastSend: lastSendTime.toISOString(),
      count: count
    }), session.user.id);
    lastSend = lastSendTime.getTime();
    cooldown = calculateCooldown(count);
  }
  return <VerifyEmailCard email={session.user.email} lastSend={lastSend} cooldown={cooldown} />
}
