import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { prisma } from '@shieldai/db';
import { EmailService } from '@shieldai/shared-notifications';
import { Queue } from 'bullmq';
import { Redis } from 'ioredis';

const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379';
const connection = new Redis(redisUrl);
const waitlistEmailQueue = new Queue('waitlist-emails', { connection });

interface WaitlistSignupBody {
  email: string;
  name?: string;
  tier?: string;
  utmSource?: string;
  utmMedium?: string;
  utmCampaign?: string;
}

function getPosition(entryId: string): string {
  const hash = entryId.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
  return String(10000 + (hash % 90000));
}

const DAY_MS = 24 * 60 * 60 * 1000;

export async function waitlistRoutes(fastify: FastifyInstance) {
  fastify.post('/waitlist/signup', async (request: FastifyRequest, reply: FastifyReply) => {
    const body = request.body as WaitlistSignupBody;

    if (!body.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(body.email)) {
      return reply.code(400).send({ error: 'Valid email is required' });
    }

    const email = body.email.toLowerCase().trim();

    const existing = await prisma.waitlistEntry.findFirst({
      where: { email },
    });

    if (existing) {
      return reply.code(200).send({
        message: 'Already on the waitlist',
        id: existing.id,
      });
    }

    const validTiers = ['basic', 'plus', 'premium'] as const;
    const tier = validTiers.includes(body.tier as typeof validTiers[number])
      ? (body.tier as string)
      : undefined;

    const entry = await prisma.waitlistEntry.create({
      data: {
        email,
        name: body.name?.trim() || null,
        source: 'landing_page',
        tier: tier as any || null,
        utmSource: body.utmSource || null,
        utmMedium: body.utmMedium || null,
        utmCampaign: body.utmCampaign || null,
      },
    });

    const name = body.name?.trim() || 'there';
    const position = getPosition(entry.id);

    try {
      const emailService = EmailService.getInstance();
      const result = await emailService.sendWithTemplate(email, {
        templateId: 'waitlist_confirmation',
        variables: { name, position },
      });
      if (result.status === 'failed') {
        request.log.warn({ error: result.error }, 'Failed to send waitlist confirmation email');
      } else {
        request.log.info({ email }, 'Waitlist confirmation email sent');
      }
    } catch (err) {
      request.log.error({ err }, 'Error sending waitlist confirmation email');
    }

    try {
      await Promise.all([
        waitlistEmailQueue.add(
          'send-waitlist-intro',
          { email, name, entryId: entry.id, tier },
          { delay: 1 * DAY_MS, attempts: 3, backoff: { type: 'exponential', delay: 5000 } }
        ),
        waitlistEmailQueue.add(
          'send-waitlist-features',
          { email, name, entryId: entry.id, tier },
          { delay: 3 * DAY_MS, attempts: 3, backoff: { type: 'exponential', delay: 5000 } }
        ),
        waitlistEmailQueue.add(
          'send-waitlist-launch-teaser',
          { email, name, entryId: entry.id, tier },
          { delay: 7 * DAY_MS, attempts: 3, backoff: { type: 'exponential', delay: 5000 } }
        ),
      ]);
      request.log.info({ email }, 'Welcome sequence scheduled');
    } catch (err) {
      request.log.error({ err }, 'Failed to schedule welcome sequence emails');
    }

    return reply.code(201).send({
      message: 'Welcome to the ShieldAI waitlist',
      id: entry.id,
    });
  });

  fastify.get('/waitlist/count', async (_request: FastifyRequest, reply: FastifyReply) => {
    const count = await prisma.waitlistEntry.count();
    return reply.send({ count });
  });
}
