import { Request, Response, NextFunction } from 'express';
import { EmbedService } from '../services/EmbedService';
import { EmbedView } from '../views/EmbedView';

export class EmbedController {
  constructor(private embedService = new EmbedService()) {}

  getPublicConfig = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const config = req.embedConfig!;
      const username = config.user?.username ?? config.eventType?.user?.username;
      const eventSlug = config.eventType?.slug;
      res.json(EmbedView.toPublicConfig(config, username!, eventSlug!));
    } catch (err) {
      next(err);
    }
  };

  list = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { configs, username } = await this.embedService.listForUser(req.userId!);
      res.json({
        data: configs.map((c) =>
          EmbedView.toHost(c, username, c.eventType?.slug ?? ''),
        ),
      });
    } catch (err) {
      next(err);
    }
  };

  create = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { config, username, eventSlug } = await this.embedService.create(req.userId!, req.body);
      res.status(201).json(EmbedView.toHost(config, username, eventSlug));
    } catch (err) {
      next(err);
    }
  };

  update = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { config, username, eventSlug } = await this.embedService.update(
        req.userId!,
        req.params.id,
        req.body,
      );
      res.json(EmbedView.toHost(config, username, eventSlug));
    } catch (err) {
      next(err);
    }
  };

  delete = async (req: Request, res: Response, next: NextFunction) => {
    try {
      await this.embedService.deactivate(req.userId!, req.params.id);
      res.status(204).send();
    } catch (err) {
      next(err);
    }
  };

  getForEventType = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { config, username, eventSlug } = await this.embedService.getOrCreateForEventType(
        req.userId!,
        req.params.id,
      );
      res.json(EmbedView.toHost(config, username, eventSlug));
    } catch (err) {
      next(err);
    }
  };

  updateForEventType = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { config, username, eventSlug } = await this.embedService.updateForEventType(
        req.userId!,
        req.params.id,
        req.body,
      );
      res.json(EmbedView.toHost(config, username, eventSlug));
    } catch (err) {
      next(err);
    }
  };
}
