package main

import (
	"errors"
	"fmt"
	_ "github.com/eclipse/paho.mqtt.golang"
	"github.com/gin-gonic/gin"
	"github.com/labstack/gommon/log"
	"golang.org/x/net/context"
	"net/http"
	"os"
)

// @Summary Request Influx data
// @Description Request data from InfluxDB for a specific device in a room
// @Tags request
// @Accept json
// @Produce json
// @Security BasicAuth
// @Param user query string true "User name" example(remi)
// @Param room query string true "Room name" example(Bedroom)
// @Param device query string true "Device name" example(DoorSensor)
// @Success 200 {object} map[string]interface{} "Returns a map of field names to their latest values."
// @Failure 500 {object} gin.H
// @Router /raclette [get]
func (gh *Gateway) requestInflux(c *gin.Context) error {
	// Get the user from the authenticated context
	//userId := c.MustGet(gin.AuthUserKey).(string)

	// Get room and device from the query parameters
	user, ret := c.GetQuery("user")
	if !ret {
		return errors.New("no user found")
	}
	room, ret := c.GetQuery("room")
	if !ret {
		return errors.New(`no room found`)
	}
	device, ret := c.GetQuery("device")
	if !ret {
		return errors.New(`no device found`)
	}

	// Get env variables and set default values if not set
	INFLUXDB_ORG, ok := os.LookupEnv("INFLUXDB_ORG")
	if !ok {
		log.Error("INFLUXDB_ORG not set, using default value: raclette")
		INFLUXDB_ORG = "raclette"
	}

	INFLUXDB_BUCKET, ok := os.LookupEnv("INFLUXDB_BUCKET")
	if !ok {
		log.Error("INFLUXDB_BUCKET not set, using default value: raclette")
		INFLUXDB_BUCKET = "raclette"
	}

	queryAPI := gh.influx.QueryAPI(INFLUXDB_ORG)
	MEASUREMENT_NAME, ok := os.LookupEnv("MEASUREMENT_NAME")
	if !ok {
		log.Error("MEASUREMENT_NAME not set, using default value: softweng")
		MEASUREMENT_NAME = "THC"
	}
	// The Flux query uses a large range (-1000d) and aggregates the latest values.
	// This ensures we always get the most recent data, even if the database contains old entries.
	query := fmt.Sprintf(`from(bucket: %q)
				|> range(start: -1000d)
 				|> filter(fn: (r) => r["_measurement"] == %q)
				|> filter(fn: (r) => r["user"] == %q)
				|> filter(fn: (r) => r["room"] == %q)
				|> filter(fn: (r) => r["device"] == %q)
				|> sort(columns: ["_time"], desc: true)
				|> limit(n: 100)
				`, INFLUXDB_BUCKET, MEASUREMENT_NAME, user, room, device)
	results, err := queryAPI.Query(context.Background(), query)
	if err != nil {
		log.Fatal(err)
	}

	type measurement = map[string]interface{}
	var values []measurement

	for results.Next() {
		m := measurement{}
		record := results.Record()
		field := record.Field()
		value := record.Value()
		m["time"] = record.Time()
		m["value"] = value.(float64)
		if field == "temperature" {
			m["type"] = "temperature"
		}
		if field == "humidity" {
			m["type"] = "humidity"
		}
		values = append(values, m)
		fmt.Println(results.Record())
	}
	if err := results.Err(); err != nil {
		log.Fatal(err)
	}

	c.JSON(http.StatusOK, values)
	return nil
}
