package main

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"

	"github.com/gofiber/fiber/v2"
)

// DeleteRoomHandler deletes a room based on an ID
func (s *Server) DeleteRoomHandler(c *fiber.Ctx) error {
	roomID, err := c.ParamsInt("roomID")
	if err != nil {
		return err
	}
	room, err := s.GetRoom(roomID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch room with id: %d", roomID)
		return err
	}
	err = s.DeleteRoom(room)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to delete room with id: %d", roomID)
		return err
	}
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("Room Deleted! %d", roomID))
}

// GetRoomHandler returns a single room from an ID
func (s *Server) GetRoomHandler(c *fiber.Ctx) error {
	roomID, err := c.ParamsInt("roomID")
	if err != nil {
		return err
	}
	room, err := s.GetRoom(roomID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch room with id: %d", roomID)
		return err
	}
	return c.Status(fiber.StatusOK).JSON(room)
}

// AddNewRoomHandler adds a new room
func (s *Server) AddNewRoomHandler(c *fiber.Ctx) error {
	locID, err := c.ParamsInt("locID")
	if err != nil {
		return err
	}
	form, err := c.MultipartForm()
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch new room form details: ", err)
		return err
	}
	// Both of these should be required on frontend, so not checking them because I'm lazy
	// TODO: Check to make sure these exist
	roomName := form.Value["Name"][0]
	roomPhoto := form.File["CoverPhoto"][0]

	// Fetch the location information
	loc, err := s.GetLocation(locID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch location by id: %d with error: %s", locID, err)
		return err
	}

	// Create the directory for this room to store the photos
	err = os.MkdirAll(filepath.ToSlash(s.Config.Server.LocationFilesDir+"/"+loc.Name+"/"+roomName), 0755)
	if err != nil {
		return err
	}

	// setting the path prepend for the photos
	urlPrepend := loc.Name + "/" + roomName + "/"
	pathPrepend := s.Config.Server.LocationFilesDir + "/" + urlPrepend

	// saving the uploaded image to our images dir
	coverImagePath := filepath.ToSlash(pathPrepend + roomName + "_cover" + filepath.Ext(roomPhoto.Filename))
	err = c.SaveFile(roomPhoto, coverImagePath)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to write file: %s to path: %s, encountered err: %s", roomPhoto.Filename, coverImagePath, err)
		return err
	}
	// Creating the URL to retrieve photo
	coverImageURL := urlPrepend + roomName + "_cover" + filepath.Ext(roomPhoto.Filename)

	var photoURLsList []string
	if roomAdditionalPhotos := form.File["AdditionalPhotos"]; len(roomAdditionalPhotos) > 0 {
		for i, photo := range roomAdditionalPhotos {
			photoPath := filepath.ToSlash(pathPrepend + roomName + "_" + strconv.Itoa(i) + filepath.Ext(photo.Filename))
			photoURL := urlPrepend + roomName + "_" + strconv.Itoa(i) + filepath.Ext(photo.Filename)
			photoURLsList = append(photoURLsList, photoURL)
			err = c.SaveFile(photo, photoPath)
			if err != nil {
				s.Log.Err(err).Msgf("Unable to write photo: %s to path: %s, encountered err: %s", photo.Filename, photoPath, err)
				return err
			}

		}
	}

	// Parse all the other fields
	roomNotes := ""
	roomNotes = form.Value["Notes"][0]

	description := ""
	description = form.Value["Description"][0]

	squareFeet := ""
	squareFeet = form.Value["SquareFeet"][0]

	squareFeetInt, err := strconv.ParseInt(squareFeet, 10, 64)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to parse Square feet, input: %s error: %s", squareFeet, err)
	}

	paint := ""
	paint = form.Value["Paint"][0]

	newRoom := Room{
		Name:         roomName,
		Description:  description,
		SquareFeet:   int(squareFeetInt),
		Paint:        paint,
		CoverPhoto:   coverImageURL,
		Photos:       photoURLsList,
		Notes:        roomNotes,
		LocationID:   locID,
		LocationName: loc.Name,
	}
	err = s.AddRoom(newRoom)
	if err != nil {
		return err
	}

	roomList := loc.Rooms
	roomList = append(roomList, newRoom)

	err = s.Database.UpdateField(&Location{ID: locID}, "Rooms", roomList)
	if err != nil {
		return err
	}
	s.Log.Debug().Msgf("Adding new Room: %v", newRoom)
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("New Room Created! %s", newRoom.Name))
}

// GetAllRoomsHandler gets all of the rooms in the db
func (s *Server) GetAllRoomsHandler(c *fiber.Ctx) error {
	rooms, err := s.GetAllRooms()
	if err != nil {
		return err
	}
	return c.Status(fiber.StatusOK).JSON(rooms)
}

// GetRoomsAtLocationHandler gets rooms at a location
func (s *Server) GetRoomsAtLocationHandler(c *fiber.Ctx) error {
	locID, err := c.ParamsInt("locID")
	if err != nil {
		return err
	}
	rooms, err := s.GetRoomsAtLocation(locID)
	fmt.Println("ROOMS: ", rooms)
	if err != nil {
		return err
	}
	return c.Status(fiber.StatusOK).JSON(rooms)
}
