package media

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"

	"fr.latosa-escrima/core"
	"fr.latosa-escrima/core/models"
	"fr.latosa-escrima/utils"
	"github.com/golang-jwt/jwt/v5"
	"github.com/google/uuid"
)

func HandleUpload(w http.ResponseWriter, r *http.Request) {
	// Parse the multipart form
	err := r.ParseMultipartForm(10 << 20) // Limit file size to 10 MB
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusRequestEntityTooLarge)
		return
	}

	// Retrieve the file from the form
	file, fileHeader, err := r.FormFile("file")
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusBadRequest)
		return
	}
	defer file.Close()

	// Create the destination file
	if !utils.DoesPathExist("media") {
		fmt.Println("Creating media forlder")
		err = os.MkdirAll("media", os.ModePerm)
		if err != nil {
			core.JSONError{
				Status:  core.Error,
				Message: err.Error(),
			}.Respond(w, http.StatusInternalServerError)
			return
		}
	}
	p := filepath.Join("media", fileHeader.Filename)
	dst, err := os.Create(p)
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}
	defer dst.Close()

	// Copy the file content to the destination file
	_, err = io.Copy(dst, file)
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	token, ok := r.Context().Value("token").(*jwt.Token)
	if !ok {
		core.JSONError{
			Status:  core.Error,
			Message: "Couldn't retrieve your JWT.",
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	claims, ok := token.Claims.(jwt.MapClaims)
	if !ok {
		core.JSONError{
			Status:  core.Error,
			Message: "Invalid token claims.",
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	id, err := uuid.Parse(claims["user_id"].(string))
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}
	media := &models.Media{
		AuthorID: id,
		Type:     fileHeader.Header.Get("Content-Type"),
		Alt:      "To be implemented",
		Path:     p,
		Size:     fileHeader.Size,
	}

	_, err = core.DB.NewInsert().Model(media).Exec(context.Background())
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	core.JSONSuccess{
		Status:  core.Success,
		Message: "File uploaded successfully.",
	}.Respond(w, http.StatusCreated)
}
