package main

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

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

// GetServeConfig fetches the server configuration
func (s *Server) GetServerConfig(c *fiber.Ctx) error {
	fmt.Println("SENDING CONFIG!")
	return c.Status(fiber.StatusOK).JSON(fiber.Map{"BasicAuth": s.Config.Authentication.BasicAuth, "Timezone": s.Config.Timezone})
}

// AddNewLocationHandler adds a new location
func (s *Server) AddNewLocationHandler(c *fiber.Ctx) error {
	form, err := c.MultipartForm()
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch new location 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
	locName := form.Value["Name"][0]
	locPhoto := form.File["CoverPhoto"][0]

	// Create the directory for this location to store the photos
	err = os.MkdirAll(s.Config.Server.LocationFilesDir+locName, 0755)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to create photos dir path: Attempted path: %s error: %s", s.Config.Server.LocationFilesDir+locName, err)
		return err
	}

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

	// Creating the empty list to store all of our additional photo URLS
	var photoURLsList []string
	// If we have additional files, handle those
	if locAdditionalPhotos := form.File["AdditionalPhotos"]; len(locAdditionalPhotos) > 0 {
		fmt.Println("Additional Photos: ", locAdditionalPhotos)
		for i, photo := range locAdditionalPhotos {
			photoPath := filepath.ToSlash(s.Config.Server.LocationFilesDir + locName + "/" + locName + "_" + strconv.Itoa(i) + filepath.Ext(photo.Filename))
			photoURL := locName + "_" + 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
			}
		}
	}

	var fileURLsList []string
	if additionalFiles := form.File["Files"]; len(additionalFiles) > 0 {
		for i, file := range additionalFiles {
			filePath := filepath.ToSlash(s.Config.Server.LocationFilesDir + locName + "/" + locName + "_" + strconv.Itoa(i) + filepath.Ext(file.Filename))
			fileUrl := locName + "_" + strconv.Itoa(i) + filepath.Ext(file.Filename)
			fileURLsList = append(fileURLsList, fileUrl)
			err = c.SaveFile(file, filePath)
			if err != nil {
				s.Log.Err(err).Msgf("Unable to write file: %s to path: %s, encountered err: %s", file.Filename, filePath, err)
				return err
			}
		}
	}

	// Parse all the other fields
	description := ""
	description = form.Value["Description"][0]

	locNotes := ""
	locNotes = form.Value["Notes"][0]

	address := ""
	if val, ok := form.Value["Address"]; ok {
		address = val[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)
	}
	latitude := ""
	latitude = form.Value["Latitude"][0]

	longitude := ""
	longitude = form.Value["Latitude"][0]

	datePurchased := ""
	if val, ok := form.Value["DatePurchased"]; ok {
		datePurchased = val[0]
	}

	purchasePrice := ""
	purchasePrice = form.Value["PurchasePrice"][0]

	newLocation := Location{
		Name:          locName,
		Description:   description,
		CoverPhoto:    coverImageURL,
		Address:       address,
		Latitude:      latitude,
		Longitude:     longitude,
		DatePurchased: datePurchased,
		PurchasePrice: purchasePrice,
		SquareFeet:    int(squareFeetInt),
		Photos:        photoURLsList,
		Files:         fileURLsList,
		Notes:         locNotes,
	}
	err = s.AddLocation(newLocation)
	if err != nil {
		return err
	}
	s.Log.Debug().Msgf("Adding new location: %v", newLocation)
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("New Location Created! %s", newLocation.Name))
}

// GetAllLocationsHandler returns all locations
func (s *Server) GetAllLocationsHandler(c *fiber.Ctx) error {
	locations, err := s.GetLocations()
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch locations: ", err)
		return err
	}
	s.Log.Debug().Msgf("Returning Locations: %+v", locations)
	return c.Status(fiber.StatusOK).JSON(locations)
}

// GetSingleLocationHandler gets a single location by locationID
func (s *Server) GetSingleLocationHandler(c *fiber.Ctx) error {
	locID, err := c.ParamsInt("locID")
	if err != nil {
		return err
	}
	location, err := s.GetLocation(locID)
	if err != nil {
		return err
	}
	fmt.Println("Returning A single location: ", location)
	return c.Status(fiber.StatusOK).JSON(location)
}

// DeleteLocationHandler deletes a location by locationID
func (s *Server) DeleteLocationHandler(c *fiber.Ctx) error {
	locID, err := c.ParamsInt("locID")
	if err != nil {
		return err
	}
	location, err := s.GetLocation(locID)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to fetch location with id: %d", locID)
		return err
	}
	err = s.DeleteLocation(location)
	if err != nil {
		s.Log.Err(err).Msgf("Unable to delete location with id: %d", locID)
		return err
	}
	return c.Status(fiber.StatusOK).SendString(fmt.Sprintf("Location Deleted! %d", locID))
}
