import { Router, Request, Response } from 'express';
import { NotificationService } from '../services/notification.service';
import type { EmailNotification, SMSNotification, PushNotification } from '../types/notification.types';

const router = Router();
const notificationService = NotificationService.getInstance();

export interface SendNotificationRequest {
  channel: 'email' | 'sms' | 'push';
  to?: string;
  userId?: string;
  subject?: string;
  body: string;
  htmlBody?: string;
  title?: string;
  data?: Record<string, unknown>;
  metadata?: Record<string, string>;
  category?: string;
}

router.post('/send', async (req: Request, res: Response) => {
  try {
    const { channel, ...payload } = req.body as SendNotificationRequest;

    let notification: EmailNotification | SMSNotification | PushNotification;

    switch (channel) {
      case 'email':
        if (!payload.to || !payload.subject || !payload.htmlBody) {
          res.status(400).json({ error: 'Email requires to, subject, and htmlBody' });
          return;
        }
        notification = {
          channel: 'email',
          to: payload.to,
          subject: payload.subject,
          htmlBody: payload.htmlBody,
          textBody: payload.body,
          metadata: payload.metadata,
        };
        break;

      case 'sms':
        if (!payload.to) {
          res.status(400).json({ error: 'SMS requires to field' });
          return;
        }
        notification = {
          channel: 'sms',
          to: payload.to,
          body: payload.body,
          metadata: payload.metadata,
        };
        break;

      case 'push':
        if (!payload.userId || !payload.title) {
          res.status(400).json({ error: 'Push requires userId and title' });
          return;
        }
        notification = {
          channel: 'push',
          userId: payload.userId,
          title: payload.title,
          body: payload.body,
          data: payload.data,
        };
        break;

      default:
        res.status(400).json({ error: `Unknown channel: ${channel}` });
        return;
    }

    const result = await notificationService.sendWithPreferences(
      notification,
      payload.category || 'default'
    );

    res.json(result);
  } catch (error) {
    res.status(500).json({
      error: error instanceof Error ? error.message : 'Unknown error',
    });
  }
});

router.post('/send/batch', async (req: Request, res: Response) => {
  try {
    const notifications = req.body.notifications as SendNotificationRequest[];
    const results = await Promise.all(
      notifications.map(n => {
        const notif = {
          channel: n.channel,
          to: n.to,
          userId: n.userId,
          subject: n.subject,
          body: n.body,
          htmlBody: n.htmlBody,
          title: n.title,
          data: n.data,
          metadata: n.metadata,
        };
        return notificationService.sendWithPreferences(
          notif as EmailNotification | SMSNotification | PushNotification,
          n.category || 'default'
        );
      })
    );
    res.json({ results });
  } catch (error) {
    res.status(500).json({
      error: error instanceof Error ? error.message : 'Unknown error',
    });
  }
});

router.post('/preferences/:userId', async (req: Request, res: Response) => {
  try {
    const { userId } = req.params;
    const { channel, enabled, categories } = req.body;

    const preference = await notificationService.setPreference(
      userId,
      channel,
      enabled,
      categories
    );

    res.json(preference);
  } catch (error) {
    res.status(500).json({
      error: error instanceof Error ? error.message : 'Unknown error',
    });
  }
});

router.get('/preferences/:userId', async (req: Request, res: Response) => {
  try {
    const { userId } = req.params;
    const { channel } = req.query;

    if (channel) {
      const preference = await notificationService.getPreference(
        userId,
        channel as 'email' | 'sms' | 'push'
      );
      res.json(preference);
    } else {
      res.json({ userId });
    }
  } catch (error) {
    res.status(500).json({
      error: error instanceof Error ? error.message : 'Unknown error',
    });
  }
});

export { router as notificationRoutes };
