import Club from '../models/Club.js';
import UserClub from '../models/UserClub.js';
import User from '../models/User.js';
import Member from '../models/Member.js';
import { Op, fn, where, col } from 'sequelize';
import { getUserByToken } from '../utils/userUtils.js';

const getClubs = async (req, res) => {
  try {
    console.log('[getClubs] - get clubs');
    const clubs = await Club.findAll();
    console.log('[getClubs] - prepare response');
    res.status(200).json(clubs);
    console.log('[getClubs] - done');
  } catch (error) {
    console.log('[getClubs] - error');
    console.log(error);
    res.status(500).json({ error: "internalerror" });
  }
};

const addClub = async (req, res) => {
  console.log('[addClub] - Read out parameters');
  const { authcode: token } = req.headers;
  const { name: clubName } = req.body;
  console.log('[addClub] - find club by name');
  const club = await Club.findOne({
    where: where(fn('LOWER', col('name')), 'LIKE', `%${clubName.toLowerCase()}%`)
  });
  console.log('[addClub] - get user');
  const user = await getUserByToken(token);
  console.log('[addClub] - check if club already exists');
  if (club) {
    res.status(409).json({ error: "alreadyexists" });
    return;
  }
  console.log('[addClub] - create club');
  const newClub = await Club.create({ name: clubName });
  console.log('[addClub] - add user to new club');
  await UserClub.create({ userId: user.id, clubId: newClub.id, approved: true });
  console.log('[addClub] - prepare response');
  res.status(200).json(newClub);
  console.log('[addClub] - done');
}

const getClub = async (req, res) => {
  console.log('[getClub] - start');
  try {
    const { authcode: token } = req.headers;
    const { clubid: clubId } = req.params;
    console.log('[getClub] - get user');
    const user = await getUserByToken(token);
    console.log('[getClub] - get users club');
    const access = await UserClub.findAll({
      where: {
        userId: user.id,
        clubId: clubId,
      }
    });
    console.log('[getClub] - check access');
    if (access.length === 0 || !access[0].approved) {
      res.status(403).json({ error: "noaccess", status: access.length === 0 ? "notrequested" : "requested" });
      return;
    }
    console.log('[getClub] - get club');
    const club = await Club.findByPk(clubId, {
      include: [
        {
          model: Member,
          as: 'members',
          order: [
            ['lastName', 'ASC'],  // Sortiere nach Nachname aufsteigend
            ['firstName', 'ASC']  // Sortiere nach Vorname aufsteigend
          ],
        },
        {
          model: User,
          as: 'Users',
          through: {
            attributes: []
          }
        }
      ]
    });
    console.log('[getClub] - check club exists');
    if (!club) {
      return res.status(404).json({ message: 'Club not found' });
    }
    console.log('[getClub] - set response');
    res.status(200).json(club);
    console.log('[getClub] - done');
  } catch (error) {
    console.log(error);
    res.status(500).json({ message: 'Server error' });
  }
}

const approveClubAccess = async (req, res) => {
  const { authcode: token } = req.headers;
  const { clubid: clubId, approveemail: toApproveEmail } = req.body;
  const user = await getUserByToken(token);
  const access = await UserClub.findAll({
    where: {
      userId: user.id,
      clubId: clubId,
      approved: true
    }
  });
  if (access.length === 0) {
    res.status(403).json({ error: "noaccess" });
    return;
  }
  const toApproveUser = await User.findOne({
    where: {
      email: toApproveEmail
    }
  });
  if (!toApproveUser) {
    res.status(404).json({ error: 'usernotfound' });
    return;
  }
  const toApproveUserClub = UserClub.findAll({
    where: {
      userId: toApproveUser.id,
      clubId: clubId
    }
  });
  if (!toApproveUserClub) {
    res.status(404).json({ error: 'norequest' });
    return;
  }
  await toApproveUserClub.update({ approved: true });
  res.status(200).json({ status: 'ok' });
}

const requestClubAccess = async (req, res) => {
  const { authcode: token } = req.headers;
  const { clubid: clubId } = req.params;
  const user = await getUserByToken(token);
  console.log(user);
  const access = await UserClub.findAll({
    where: {
      userId: user.id,
      clubId: clubId,
    }
  });
  if (access.length > 0) {
    res.status(409).json({ err: "alreadyrequested" });
    return;
  }
  const club = Club.findOne({
    where: {
      id: clubId
    }
  });
  if (!club) {
    res.status(404).json({ err: "clubnotfound" });
    return;
  }
  UserClub.create({
    userId: user.id,
    clubId: clubId,
    approved: false
  });
  res.status(200).json({});
}

export { getClubs, addClub, getClub, approveClubAccess, requestClubAccess };