package handlers

import (
	"encoding/json"
	"net/http"
	"otaupdate/background"
	"otaupdate/services"

	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/common/actionlogger"
	"github.com/fiskerinc/cloud-services/pkg/httphandlers"
	"github.com/fiskerinc/cloud-services/pkg/logger"
	"github.com/fiskerinc/cloud-services/pkg/loggerdataresp"
	"github.com/fiskerinc/cloud-services/pkg/utils"
)

// HandleVehicleImmobilizerList godoc
// @Summary List vehicles in immobilizer list
// @Description
// @Accept  json
// @Produce  json
// @Param Authorization header string false "Bearer <ID token>"
// @Param Api-Key header string false "<API token>"
// @Success 200 {object} map[string]background.CarTrack
// @Failure 400 {object} common.JSONError "Bad request"
// @Failure 401 {object} common.JSONError "Unauthorized"
// @Failure 503 {object} common.JSONError "Service unavailable"
// @Router /vehiclecommand/immobilize [get]
func HandleVehicleImmobilizerList(w http.ResponseWriter, r *http.Request) {
	err := json.NewEncoder(w).Encode(background.GetImmobilizer().GetVINInformation())
	if loggerdataresp.BadDataErrorResp(w, err, http.StatusInternalServerError) {
		logger.Err(err).Msg("failed to encode immobilizer vin information")
		return
	}
}

// HandleVehicleImmobilizerAdd godoc
// @Summary Add vehicles to immobilizer list
// @Description
// @Accept  json
// @Produce  json
// @Param Authorization header string false "Bearer <ID token>"
// @Param Api-Key header string false "<API token>"
// @Param data body HandleImmobilizerBody true "List of VINs to add to immobilizer"
// @Success 200 {object} common.JSONMessage
// @Failure 400 {object} common.JSONError "Bad request"
// @Failure 401 {object} common.JSONError "Unauthorized"
// @Failure 503 {object} common.JSONError "Service unavailable"
// @Router /vehiclecommand/immobilize [post]
func HandleVehicleImmobilizerAdd(w http.ResponseWriter, r *http.Request) {
	body := HandleImmobilizerBody{}
	err := json.NewDecoder(r.Body).Decode(&body)
	if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
		return
	}
	go func(body *HandleImmobilizerBody, clientID string) {
		alDB := services.GetDB().GetActionLog()
		var description string
		if body.Immobilize {
			description = "immobilizing command"
		}else {
			description = "mobilizing command"
		}
		for _, v := range body.VINs {
			actionLog := actionlogger.ActionLog{
				VIN:            v,
				Action:         actionlogger.RemoteCommand,
				UserIdentifier: clientID,
				CallLocation:   "github.com/fiskerinc/cloud-services/services/ota_update_go/handlers/vehiclecommand_immobilizer.go",
				Description:    description,
			}
			err = alDB.Insert(actionLog)
			if err != nil {
				logger.Err(err).Msg("failed to insert action log inside HandleVehicleCommand")
			}
		}

	}(&body, httphandlers.GetClientID(r))
	background.GetImmobilizer().AddVINs(body.VINs, body.Immobilize)
	utils.RespJSON(w, http.StatusOK, common.JSONMessage{
		Message: "OK",
	})
}

// HandleVehicleImmobilizerDelete godoc
// @Summary Delete vehicles from immobilizer list
// @Description
// @Accept  json
// @Produce  json
// @Param Authorization header string false "Bearer <ID token>"
// @Param Api-Key header string false "<API token>"
// @Param data body []string true "List of VINs to remove from immobilizer"
// @Success 200 {object} common.JSONMessage
// @Failure 400 {object} common.JSONError "Bad request"
// @Failure 401 {object} common.JSONError "Unauthorized"
// @Failure 503 {object} common.JSONError "Service unavailable"
// @Router /vehiclecommand/immobilize [delete]
func HandleVehicleImmobilizerDelete(w http.ResponseWriter, r *http.Request) {
	body := []string{}
	err := json.NewDecoder(r.Body).Decode(&body)
	if loggerdataresp.BadDataErrorResp(w, err, http.StatusBadRequest) {
		return
	}
	background.GetImmobilizer().RemoveVINs(body)
	utils.RespJSON(w, http.StatusOK, common.JSONMessage{
		Message: "OK",
	})
}

type HandleImmobilizerBody struct {
	VINs       []string `json:"vins"`
	Immobilize bool     `json:"immobilize"` // True: Immobilize cars, False: Mobilize the car
}
