package main

import (
	"encoding/base64"
	"encoding/json"
	"math/rand"
	"time"

	"server/serder"
)

// ---------- CONFIG ----------
const (
	Broker    = "tls://mosquitto:8883"
	GatewayID = "54d4d6102c916aed"
	DeviceEUI = "1122334455667788"
	AppId     = "188c5d25-2d6b-43e3-aaf3-07dd0a8c386e"
)

var FCount uint32 = 0

// ---------- DATA STRUCTURES ----------
type Location struct {
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
	Altitude  float64 `json:"altitude"`
}

type RXInfo struct {
	GatewayID string    `json:"gatewayID"`
	Time      time.Time `json:"time"`
	RSSI      int       `json:"rssi"`
	LoRaSNR   float64   `json:"loRaSNR"`
	Channel   int       `json:"channel"`
	RFChain   int       `json:"rfChain"`
	Board     int       `json:"board"`
	Antenna   int       `json:"antenna"`
	Location  Location  `json:"location"`
}

type TXInfo struct {
	Frequency int    `json:"frequency"`
	DR        int    `json:"dr"`
	ADR       bool   `json:"adr"`
	CodeRate  string `json:"codeRate"`
}

type Uplink struct {
	ApplicationID   string   `json:"applicationID"`
	ApplicationName string   `json:"applicationName"`
	DeviceName      string   `json:"deviceName"`
	DevEUI          string   `json:"devEUI"`
	RXInfo          []RXInfo `json:"rxInfo"`
	TXInfo          TXInfo   `json:"txInfo"`
	FCnt            uint32   `json:"fCnt"`
	FPort           uint8    `json:"fPort"`
	Data            string   `json:"data"`   // Base64-encoded payload
	Object          any      `json:"object"` // decoded JSON payload if device uses JSON codec
}

// ---------- UTILITY FUNCTIONS ----------
// func generateRandomPHY(n int) []byte {
// 	payload := make([]byte, n)
// 	for i := 0; i < n; i++ {
// 		payload[i] = byte(rand.Intn(256))
// 	}
// 	return payload
// }

// Create a random uplink
func MakePayload() (*Uplink, error) {

	// Generate random sensor data
	custom_pay := serder.PagerMessage{
		AppID: 1,
		Fields: []serder.Field{
			{
				DType: serder.DT_Array,
				Value: serder.Field{
					DType: serder.DT_Char,
					Value: []byte{
						byte(5),
						'H', 'e', 'l', 'l', 'o',
					},
				},
			},
		},
	}
	object, err := serder.Serialize(&custom_pay)

	if err != nil {
		return nil, err
	}

	// Encode object as JSON and then as base64 for Data field
	objBytes, _ := json.Marshal(object)
	dataB64 := base64.StdEncoding.EncodeToString(objBytes)

	uplink := Uplink{
		ApplicationID:   AppId,
		ApplicationName: "pagerino-app",
		DeviceName:      "pager-1",
		DevEUI:          DeviceEUI,
		RXInfo: []RXInfo{
			{
				GatewayID: GatewayID,
				Time:      time.Now().UTC(),
				RSSI:      -30 + rand.Intn(10),
				LoRaSNR:   -5 + rand.Float64()*10,
				Channel:   0,
				RFChain:   0,
				Board:     1,
				Antenna:   0,
				Location: Location{
					Latitude:  52.0 + rand.Float64(),
					Longitude: 13.0 + rand.Float64(),
					Altitude:  100 + rand.Float64()*50,
				},
			},
		},
		TXInfo: TXInfo{
			Frequency: 868100000,
			DR:        5,
			ADR:       true,
			CodeRate:  "4/5",
		},
		FCnt:   FCount,
		FPort:  1,
		Data:   dataB64,
		Object: object,
	}

	FCount++

	return &uplink, err
}
