import chatService from '../services/chatService.js';
import Joi from 'joi';

class ChatController {
  constructor() {
    this.getMessages = this.getMessages.bind(this);
    this.findRandomChatMatch = this.findRandomChatMatch.bind(this);
    this.registerUser = this.registerUser.bind(this);
    this.sendMessage = this.sendMessage.bind(this);
    this.stopChat = this.stopChat.bind(this);
    this.removeUser = this.removeUser.bind(this);
    this.initOneToOne = this.initOneToOne.bind(this);
    this.sendOneToOneMessage = this.sendOneToOneMessage.bind(this);
    this.getOneToOneMessageHistory = this.getOneToOneMessageHistory.bind(this);
    this.getRoomList = this.getRoomList.bind(this);
  }

  async getMessages(req, res) {
    const schema = Joi.object({
      to: Joi.string().required(),
      from: Joi.string().required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      const messages = await chatService.getMessages(value.to, value.from);
      res.status(200).json(messages);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async findRandomChatMatch(req, res) {
    const schema = Joi.object({
      genders: Joi.array().items(Joi.string()).required(),
      age: Joi.number().integer().min(0).required(),
      id: Joi.string().required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      const match = await chatService.findMatch(value.genders, value.age, value.id);
      if (match) {
        res.status(200).json({ status: 'matched', user: match });
      } else {
        res.status(200).json({ status: 'waiting' });
      }
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async registerUser(req, res) {
    const schema = Joi.object({
      gender: Joi.string().required(),
      age: Joi.number().integer().min(0).required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      const userId = await chatService.registerUser(value.gender, value.age);
      res.status(200).json({ id: userId });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async sendMessage(req, res) {
    const schema = Joi.object({
      from: Joi.string().required(),
      to: Joi.string().required(),
      text: Joi.string().min(1).max(2000).required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      const message = await chatService.addMessage(value.from, value.to, value.text);
      res.status(200).json(message);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async removeUser(req, res) {
    const schema = Joi.object({
      id: Joi.string().required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      await chatService.removeUser(value.id);
      res.sendStatus(200);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async stopChat(req, res) {
    const schema = Joi.object({
      id: Joi.string().required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      await chatService.endChat(value.id);
      res.sendStatus(200);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async initOneToOne(req, res) {
    const schema = Joi.object({
      partnerHashId: Joi.string().required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    const { userid: hashedUserId } = req.headers;
    try {
      await chatService.initOneToOne(hashedUserId, value.partnerHashId);
      res.status(200).json({ message: 'One-to-one chat initialization is pending implementation.' });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async sendOneToOneMessage(req, res) {
    const schema = Joi.object({
      user1HashId: Joi.string().required(),
      user2HashId: Joi.string().required(),
      message: Joi.string().min(1).max(2000).required()
    });
    const { error, value } = schema.validate(req.body);
    if (error) {
      return res.status(400).json({ error: error.details[0].message });
    }
    try {
      await chatService.sendOneToOneMessage(value.user1HashId, value.user2HashId, value.message);
      res.status(200).json({ status: 'message sent' });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async getOneToOneMessageHistory(req, res) {
    const { user1HashId, user2HashId } = req.query;
    try {
      const history = await chatService.getOneToOneMessageHistory(user1HashId, user2HashId);
      res.status(200).json({ history });
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }

  async getRoomList(req, res) {
    // Öffentliche Räume für Chat-Frontend
    try {
      const rooms = await chatService.getRoomList();
      res.status(200).json(rooms);
    } catch (error) {
      res.status(500).json({ error: error.message });
    }
  }
}

export default ChatController;
