import { Request, Response } from "express";
import BoatType from "../db/models/BoatType";
import Boat from "../db/models/Boat";

//create boat
const createBoat = async (req: Request, res: Response) => {
  try {
    if (!(res.locals.user.role == "coordinator")) {
      return res
        .status(403)
        .json({ success: false, error: "MustBeCoordinator" });
    }

    const newBoatInput = req.body;

    const boatType = await BoatType.findByPk(newBoatInput.boattype);
    if (!boatType) {
      return res
        .status(404)
        .json({ success: false, error: "boattypeNotFound" });
    }
    const newBoat = await Boat.create(newBoatInput);

    if (newBoat) {
      return res.status(201).json({
        success: true,
        result: {
          id: newBoat.id,
          name: newBoat.name,
          boatTypeId: newBoat.boattype,
          status: newBoat.status,
          tags: newBoat.tags,
        },
      });
    }
  } catch (error) {
    console.error(error.message);
    return res.status(500).json({ success: false, error: "serverError" });
  }
};

//show all boats
const showAllBoatsController = async (req: Request, res: Response) => {
  try {
    const allBoats = await Boat.findAll();
    return res.status(200).send({
      success: true,
      result: allBoats.map((boat) => {
        return {
          id: boat.id,
          name: boat.name,
          boatType: boat.boattype,
          status: boat.status,
          tags: boat.tags,
        };
      }),
    });
  } catch (error) {
    console.error("server error: ", error.message);
    return res.status(500).json({ success: false, error: "serverError" });
  }
};

//show specific boat using given id
const showBoatById = async (req: Request, res: Response) => {
  try {
    const givenId = req.params.id;
    const boat = await Boat.findByPk(givenId);
    if (boat) {
      return res.status(200).json({
        success: true,
        result: {
          name: boat.name,
          boatTypeId: boat.boattype,
          status: boat.status,
          tags: boat.tags,
        },
      });
    }
    return res.status(404).json({ success: false, error: "boatIdNotFound" });
  } catch (error) {
    console.error("server error: ", error.message);
    return res.status(500).json({ success: false, error: "serverError" });
  }
};

//delete specific boat using given id
const deleteBoatById = async (req: Request, res: Response) => {
  try {
    if (!(res.locals.user.role === "coordinator")) {
      return res
        .status(403)
        .json({ success: false, error: "MustBeCoordinator" });
    }
    const givenId = req.params.id;
    const boatToDelete = await Boat.destroy({
      where: {
        id: givenId,
      },
    });
    if (boatToDelete == 0) {
      return res
        .status(404)
        .json({ success: false, error: "BoatIdDoesNotExist" });
    }
    return res.status(204).json({ success: true });
  } catch (error) {
    console.error("server error: ", error.message);
    return res.status(500).json({ success: false, error: "serverError" });
  }
};

//update boat by given id
const updateBoatById = async (req: Request, res: Response) => {
  try {
    //check authority
    if (!(res.locals.user.role === "coordinator")) {
      return res
        .status(403)
        .json({ success: false, error: "MustBeCoordinator" });
    }

    //get new input
    const input = req.body;

    //return 200 with empty response if no data was given
    if (Object.keys(input).length === 0) {
      return res
        .status(200)
        .json({ success: true, result: {}, message: "noInputFound" });
    }

    //get id
    const givenId = req.params.id;

    //check if boat can be found using givenId
    const foundBoat = await Boat.findByPk(givenId);

    if (!foundBoat) {
      return res.status(404).json({ success: false, error: "boatIdNotFound" });
    }

    //try to update
    const updatedBoat = await Boat.update(input, {
      where: {
        id: givenId,
      },
      returning: true,
    });

    //return after updating
    const boatDataAfterUpdate = updatedBoat[1][0];
    return res.status(200).json({
      success: true,
      result: {
        id: boatDataAfterUpdate.id,
        name: boatDataAfterUpdate.name,
        boattype: boatDataAfterUpdate.boattype,
        status: boatDataAfterUpdate.status,
        tags: boatDataAfterUpdate.tags,
      },
    });
  } catch (error) {
    console.error("server error: ", error.message);
    return res.status(500).json({ success: false, error: "serverError" });
  }
};

const boatControllers = {
  showAllBoatsController,
  showBoatById,
  deleteBoatById,
  createBoat,
  updateBoatById,
};

export default boatControllers;