package main

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

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

// DeleteCabinetHandler deletes a cabinet based on an ID
func (s *Server) DeleteCabinetHandler(c *fiber.Ctx) error {
	cabinetID, err := c.ParamsInt("cabinetID")
	if err != nil {
		return err
	}
	cabinet, err := s.GetCabinet(cabinetID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch cabinet with id: %d", cabinetID)
		return err
	}
	err = s.DeleteCabinet(cabinet)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to delete cabinet with id: %d", cabinetID)
		return err
	}
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("Cabinet Deleted! %d", cabinetID))
}

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

// AddNewCabinetHandler adds a new cabinet
func (s *Server) AddNewCabinetHandler(c *fiber.Ctx) error {
	roomID, err := c.ParamsInt("roomID")
	if err != nil {
		return err
	}
	form, err := c.MultipartForm()
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch cabinet details: ", err)
		return err
	}
	cabinetName := form.Value["Name"][0]
	fmt.Println("COverphoto: ", form.File["CoverPhoto"])
	cabinetPhoto := form.File["CoverPhoto"][0]
	if err != nil {
		s.Log.Err(err).Msgf("Unable to get CoverPhoto for Cabinet: ", err)
		return err
	}

	// Fetch the location information
	room, err := s.GetRoom(roomID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch room by id: %d with error: %s", roomID, err)
		return err
	}
	loc, err := s.GetLocation(room.LocationID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch location by id: %d with error: %s", room.LocationID, err)
		return err
	}
	// setting the path prepend for the photos
	urlPrepend := loc.Name + "/" + room.Name + "/" + cabinetName + "/"
	pathPrepend := s.Config.Server.LocationFilesDir + "/" + urlPrepend

	// Create the directory for this cabinet to store the photos
	err = os.MkdirAll(filepath.ToSlash(pathPrepend), 0755)
	if err != nil {
		return err
	}

	// create files on server for all uploads
	cabinetNotes := form.Value["Notes"][0]

	// saving the uploaded image to our images dir
	coverImagePath := filepath.ToSlash(pathPrepend + cabinetName + "_cover" + filepath.Ext(cabinetPhoto.Filename))
	// Creating the URL to retrieve photo
	coverImageURL := urlPrepend + cabinetName + "_cover" + filepath.Ext(cabinetPhoto.Filename)
	src, err := cabinetPhoto.Open()
	if err != nil {
		return err
	}
	defer src.Close()
	coverImageData, err := io.ReadAll(src)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to read cover photo file: ", err)
		return err
	}
	err = os.WriteFile(coverImagePath, coverImageData, 0644)
	if err != nil {
		return err
	}
	newCabinet := Cabinet{
		Name:       cabinetName,
		CoverPhoto: coverImageURL,
		Notes:      cabinetNotes,
		RoomID:     roomID,
		RoomName:   loc.Name,
	}
	err = s.AddCabinet(newCabinet)
	if err != nil {
		return err
	}
	// Update our room in the db to add the new cabinet as attached to the ID
	cabinetList := room.Cabinets
	cabinetList = append(cabinetList, newCabinet)

	err = s.Database.UpdateField(&Room{ID: roomID}, "Cabinets", cabinetList)
	if err != nil {
		return err
	}
	s.Log.Debug().Msgf("Adding new Cabinet: %v", newCabinet)
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("New Cabinet Created! %s", newCabinet.Name))
}

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

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