import { Request, Response } from 'express';
import scheduledMessagesService from '../services/scheduledMessages.service';
import logger from '../utils/logger';

class ScheduledMessagesController {
  async getAll(_req: Request, res: Response): Promise<void> {
    try {
      const rules = await scheduledMessagesService.getAll();
      res.json({ success: true, data: rules });
    } catch (error) {
      logger.error('ScheduledMessagesController.getAll error', { error });
      res.status(500).json({ success: false, message: 'Regeln konnten nicht geladen werden' });
    }
  }

  async getById(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const userId = req.user?.id;
      const rule = await scheduledMessagesService.getById(id, userId);
      if (!rule) {
        res.status(404).json({ success: false, message: 'Regel nicht gefunden' });
        return;
      }
      res.json({ success: true, data: rule });
    } catch (error) {
      logger.error('ScheduledMessagesController.getById error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Regel konnte nicht geladen werden' });
    }
  }

  async create(req: Request, res: Response): Promise<void> {
    try {
      const userId = req.user!.id;
      const rule = await scheduledMessagesService.create(req.body, userId);
      res.status(201).json({ success: true, data: rule });
    } catch (error) {
      logger.error('ScheduledMessagesController.create error', { error });
      res.status(500).json({ success: false, message: 'Regel konnte nicht erstellt werden' });
    }
  }

  async update(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const rule = await scheduledMessagesService.update(id, req.body);
      if (!rule) {
        res.status(404).json({ success: false, message: 'Regel nicht gefunden' });
        return;
      }
      res.json({ success: true, data: rule });
    } catch (error) {
      logger.error('ScheduledMessagesController.update error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Regel konnte nicht aktualisiert werden' });
    }
  }

  async delete(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const deleted = await scheduledMessagesService.delete(id);
      if (!deleted) {
        res.status(404).json({ success: false, message: 'Regel nicht gefunden' });
        return;
      }
      res.status(204).send();
    } catch (error) {
      logger.error('ScheduledMessagesController.delete error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Regel konnte nicht gelöscht werden' });
    }
  }

  async getRooms(_req: Request, res: Response): Promise<void> {
    try {
      const result = await scheduledMessagesService.getRooms();
      if (!result.configured) {
        res.json({ configured: false });
        return;
      }
      res.json({ configured: true, data: result.data });
    } catch (error) {
      logger.error('ScheduledMessagesController.getRooms error', { error });
      res.status(500).json({ success: false, message: 'Räume konnten nicht geladen werden' });
    }
  }

  async subscribe(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const userId = req.user!.id;
      const { room_token } = req.body as Record<string, string>;
      if (!room_token) {
        res.status(400).json({ success: false, message: 'room_token ist erforderlich' });
        return;
      }
      await scheduledMessagesService.subscribe(id, userId, room_token);
      res.json({ success: true });
    } catch (error) {
      logger.error('ScheduledMessagesController.subscribe error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Abonnement konnte nicht erstellt werden' });
    }
  }

  async getMyBotRoom(req: Request, res: Response): Promise<void> {
    try {
      const userId = req.user!.id;
      const result = await scheduledMessagesService.getOrCreateBotRoom(userId);
      if (result === null) {
        res.status(400).json({ success: false, configured: false, message: 'Bot nicht konfiguriert' });
        return;
      }
      if (result === 'not_connected') {
        res.status(400).json({ success: false, connected: false, message: 'Nextcloud-Konto nicht verbunden' });
        return;
      }
      res.json({ success: true, data: { room_token: result } });
    } catch (error) {
      logger.error('ScheduledMessagesController.getMyBotRoom error', { error });
      res.status(500).json({ success: false, message: 'Bot-Raum konnte nicht ermittelt werden' });
    }
  }

  async unsubscribe(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const userId = req.user!.id;
      await scheduledMessagesService.unsubscribe(id, userId);
      res.status(204).send();
    } catch (error) {
      logger.error('ScheduledMessagesController.unsubscribe error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Abonnement konnte nicht entfernt werden' });
    }
  }

  async triggerNow(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const rule = await scheduledMessagesService.getById(id);
      if (!rule) {
        res.status(404).json({ success: false, message: 'Regel nicht gefunden' });
        return;
      }
      const rooms = await scheduledMessagesService.getRooms();
      if (!rooms.configured) {
        res.status(400).json({ success: false, configured: false, message: 'Bot nicht konfiguriert' });
        return;
      }
      await scheduledMessagesService.buildAndSend(rule);
      res.json({ success: true });
    } catch (error) {
      logger.error('ScheduledMessagesController.triggerNow error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Nachricht konnte nicht gesendet werden' });
    }
  }

  async getOneTimeMessages(_req: Request, res: Response): Promise<void> {
    try {
      const messages = await scheduledMessagesService.getOneTimeMessages();
      res.json({ success: true, data: messages });
    } catch (error) {
      logger.error('ScheduledMessagesController.getOneTimeMessages error', { error });
      res.status(500).json({ success: false, message: 'Einzelnachrichten konnten nicht geladen werden' });
    }
  }

  async createOneTimeMessage(req: Request, res: Response): Promise<void> {
    try {
      const { message, target_room_token, target_room_name, send_at } = req.body as Record<string, string>;
      if (!message || !target_room_token || !send_at) {
        res.status(400).json({ success: false, message: 'message, target_room_token und send_at sind erforderlich' });
        return;
      }
      const msg = await scheduledMessagesService.createOneTimeMessage(
        { message, target_room_token, target_room_name: target_room_name ?? null, send_at },
        req.user!.id,
      );
      res.status(201).json({ success: true, data: msg });
    } catch (error) {
      logger.error('ScheduledMessagesController.createOneTimeMessage error', { error });
      res.status(500).json({ success: false, message: 'Einzelnachricht konnte nicht erstellt werden' });
    }
  }

  async deleteOneTimeMessage(req: Request, res: Response): Promise<void> {
    try {
      const { id } = req.params as Record<string, string>;
      const deleted = await scheduledMessagesService.deleteOneTimeMessage(id);
      if (!deleted) {
        res.status(404).json({ success: false, message: 'Einzelnachricht nicht gefunden' });
        return;
      }
      res.status(204).send();
    } catch (error) {
      logger.error('ScheduledMessagesController.deleteOneTimeMessage error', { error, id: req.params.id });
      res.status(500).json({ success: false, message: 'Einzelnachricht konnte nicht gelöscht werden' });
    }
  }
}

export default new ScheduledMessagesController();
