package handlers

import (
	"context"
	"encoding/json"
	"net/http"
	"os"
	"portfolio/api/service/jwt"
	"portfolio/api/service/parse"
	"portfolio/database/ent"
	"portfolio/database/query"
	"strconv"
	"time"
)

func CreateProjectHandler(w http.ResponseWriter, r *http.Request) {

	id, _, err := jwt.VerifyUser(r)
	if err != nil {
		UnauthorizedHandler(w)
		return
	}

	var p *ent.Project

	if err = json.NewDecoder(r.Body).Decode(&p); err != nil {
		InternalServerErrorHandler(w, err)
		return
	}

	if err = query.CreateProject(context.Background(), *p, id); err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}
}

func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) {

	if _, _, err := jwt.VerifyUser(r); err != nil {
		UnauthorizedHandler(w)
		return
	}

	var p *ent.Project

	projectID, err := strconv.Atoi(r.PathValue("id"))
	if err != nil {
		BadRequestHandler(w)
		return
	}

	p, err = query.GetFullProject(context.Background(), projectID)
	if err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}

	if err = json.NewDecoder(r.Body).Decode(&p); err != nil {
		InternalServerErrorHandler(w, err)
		return
	}

	if err = query.UpdateProject(context.Background(), *p, projectID); err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}
}

func UpdateProjectsHandler(w http.ResponseWriter, r *http.Request) {

	var newProjects []*ent.Project
	var p []*ent.Project
	var err error

	isHtmx := r.Header.Get("HX-Request")

	if _, _, err := jwt.VerifyUser(r); err != nil {
		UnauthorizedHandler(w)
		return
	}

	if isHtmx == "true" {
		p = parse.ProjectInput(r)
	} else {

		p, err = query.GetFullProjects(context.Background())
		if err != nil {
			UnprocessableEntityHandler(w, err)
			return
		}

		err = json.NewDecoder(r.Body).Decode(&newProjects)
		if err != nil {
			InternalServerErrorHandler(w, err)
			return
		}

		for _, project := range p {
			for _, newProject := range newProjects {
				if project.ID == newProject.ID {
					// todo add update from api
				}
			}
		}
	}

	for _, project := range p {
		if err = query.UpdateProject(context.Background(), *project, project.ID); err != nil {
			UnprocessableEntityHandler(w, err)
			return
		}
	}

}

func GetProjectHandler(w http.ResponseWriter, r *http.Request) {

	projectID, err := strconv.Atoi(r.PathValue("id"))
	if err != nil {
		BadRequestHandler(w)
	}

	p, err := query.GetProject(context.Background(), projectID)
	if err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}

	w.Header().Set("Content-Type", "application/json")

	if err = json.NewEncoder(w).Encode(p); err != nil {
		InternalServerErrorHandler(w, err)
		return
	}
}

func GetProjectsHandler(w http.ResponseWriter, r *http.Request) {

	p, err := query.GetProjects(context.Background())
	if err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}

	w.Header().Set("Content-Type", "application/json")

	if err = json.NewEncoder(w).Encode(p); err != nil {
		InternalServerErrorHandler(w, err)
		return
	}
}

func GetProjectsBackupHandler(w http.ResponseWriter, r *http.Request) {
	p, err := query.GetProjects(context.Background())
	if err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}

	w.Header().Set("Content-Type", "application/json")

	backup, _ := json.Marshal(p)

	if err = os.WriteFile(
		"/web/assets/json/backup-"+strconv.Itoa(int(time.Now().Unix()))+".json",
		backup,
		0644,
	); err != nil {
		UnprocessableEntityHandler(w, err)
		return
	}

	if err = json.NewEncoder(w).Encode(p); err != nil {
		InternalServerErrorHandler(w, err)
		return
	}
}
