package models

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"

	"forge.grandlyon.com/apoyen/elections/internal/auth"
)

func (d *DataHandler) HandleElection(w http.ResponseWriter, r *http.Request) {
	id, _ := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/Election/"))
	switch method := r.Method; method {
	case "GET":
		switch auth.GetLoggedUserTechnical(w, r).Role {
		case "ADMIN":
			d.getElectionAdmin(w, r, id)
		case "CAPTURER", "VISUALIZER":
			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
		default:
			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
		}
	case "POST":
		switch auth.GetLoggedUserTechnical(w, r).Role {
		case "ADMIN":
			d.postElectionAdmin(w, r)
		case "CAPTURER", "VISUALIZER":
			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
		default:
			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
		}

	case "PUT":
		switch auth.GetLoggedUserTechnical(w, r).Role {
		case "ADMIN":
			d.putElectionAdmin(w, r, id)
		case "CAPTURER", "VISUALIZER":
			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
		default:
			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
		}
	case "DELETE":
		switch auth.GetLoggedUserTechnical(w, r).Role {
		case "ADMIN":
			d.deleteElectionAdmin(w, r, id)
		case "CAPTURER", "VISUALIZER":
			http.Error(w, ErrorNotAuthorizeMethodOnRessource, http.StatusMethodNotAllowed)
		default:
			http.Error(w, ErrorRoleOfLoggedUser, http.StatusInternalServerError)
		}
	default:
		http.Error(w, "method not allowed", 400)
	}
}

func (d *DataHandler) getElectionAdmin(w http.ResponseWriter, r *http.Request, id int) {
	if id != 0 {
		var o Election
		if err := d.db.Preload("Areas").First(&o, id).Error; err != nil {
			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
			return
		}
		json.NewEncoder(w).Encode(o)
	} else {
		var o []Election
		d.db.Preload("Areas").Find(&o)
		json.NewEncoder(w).Encode(o)
	}
}

func (d *DataHandler) postElectionAdmin(w http.ResponseWriter, r *http.Request) {
	var o Election
	err := json.NewDecoder(r.Body).Decode(&o)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	d.db.Create(&o)
	d.db.Last(&o)
	json.NewEncoder(w).Encode(o)

}

func (d *DataHandler) putElectionAdmin(w http.ResponseWriter, r *http.Request, id int) {
	var o Election
	if err := d.db.Preload("Areas").First(&o, id).Error; err != nil {
		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
		return
	}
	var election Election
	err := json.NewDecoder(r.Body).Decode(&election)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	o.Name = election.Name
	o.BallotType = election.BallotType
	d.db.Save(&o)
	json.NewEncoder(w).Encode(o)

}

func (d *DataHandler) deleteElectionAdmin(w http.ResponseWriter, r *http.Request, id int) {
	if id != 0 {
		var o Election
		if err := d.db.First(&o, id).Error; err != nil {
			http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
			return
		}
		d.db.Delete(&o)
	} else {
		http.Error(w, ErrorIDIsMissing, http.StatusNotFound)
	}
}