package model

import (
	"sync"

	"github.com/segmentio/kafka-go"
)

// Settings defines configuration parameters for presence detection behavior.
type SettingsVal struct {
	LocationConfidence   int64 `json:"location_confidence"`
	LastSeenThreshold    int64 `json:"last_seen_threshold"`
	BeaconMetricSize     int   `json:"beacon_metrics_size"`
	HASendInterval       int64 `json:"ha_send_interval"`
	HASendChangesOnly    bool  `json:"ha_send_changes_only"`
	RSSIMinThreshold     int64 `json:"rssi_min_threshold"`
	RSSIEnforceThreshold bool  `json:"enforce_rssi_threshold"`
}

type Settings struct {
	Settings SettingsVal
	Lock     sync.RWMutex
}

// BeaconAdvertisement represents the JSON payload received from beacon advertisements.
type BeaconAdvertisement struct {
	Hostname        string `json:"hostname"`
	MAC             string `json:"mac"`
	RSSI            int64  `json:"rssi"`
	ScanResponse    string `json:"is_scan_response"`
	Type            string `json:"type"`
	Data            string `json:"data"`
	BeaconType      string `json:"beacon_type"`
	UUID            string `json:"uuid"`
	Major           string `json:"major"`
	Minor           string `json:"minor"`
	TXPower         string `json:"tx_power"`
	NamespaceID     string `json:"namespace"`
	InstanceID      string `json:"instance_id"`
	HSButtonCounter int64  `json:"hb_button_counter"`
	HSButtonPrev    int64  `json:"hb_button_counter_prev"`
	HSBatteryLevel  int64  `json:"hb_button_battery"`
	HSRandomNonce   string `json:"hb_button_random"`
	HSButtonMode    string `json:"hb_button_mode"`
}

// Advertisement describes a generic beacon advertisement payload.
type Advertisement struct {
	Type    string
	Content string
	Seen    int64
}

// BeaconMetric stores signal and distance data for a beacon.
type BeaconMetric struct {
	Location  string
	Distance  float64
	RSSI      int64
	Timestamp int64
}

// Location defines a physical location and synchronization control.
type Location struct {
	Name string
	Lock sync.RWMutex
}

// BestLocation represents the most probable location of a beacon.
type BestLocation struct {
	Distance float64
	Name     string
	LastSeen int64
}

// HTTPLocation describes a beacon's state as served over HTTP.
type HTTPLocation struct {
	Method                    string  `json:"method"`
	PreviousConfidentLocation string  `json:"previous_confident_location"`
	Distance                  float64 `json:"distance"`
	ID                        string  `json:"id"`
	Location                  string  `json:"location"`
	LastSeen                  int64   `json:"last_seen"`
}

// LocationChange defines a change event for a beacon's detected location.
type LocationChange struct {
	Method           string `json:"method"`
	BeaconRef        Beacon `json:"beacon_info"`
	Name             string `json:"name"`
	BeaconName       string `json:"beacon_name"`
	PreviousLocation string `json:"previous_location"`
	NewLocation      string `json:"new_location"`
	Timestamp        int64  `json:"timestamp"`
}

// HAMessage represents a Home Assistant integration payload.
type HAMessage struct {
	ID         string  `json:"id"`
	BeaconName string  `json:"name"`
	Distance   float64 `json:"distance"`
}

// Beacon holds all relevant information about a tracked beacon device.
type Beacon struct {
	Name                      string              `json:"name"`
	ID                        string              `json:"beacon_id"`
	BeaconType                string              `json:"beacon_type"`
	BeaconLocation            string              `json:"beacon_location"`
	LastSeen                  int64               `json:"last_seen"`
	IncomingJSON              BeaconAdvertisement `json:"incoming_json"`
	Distance                  float64             `json:"distance"`
	PreviousLocation          string
	PreviousConfidentLocation string
	ExpiredLocation           string
	LocationConfidence        int64
	LocationHistory           []string
	BeaconMetrics             []BeaconMetric
	Location                  string `json:"location"`
	HSButtonCounter           int64  `json:"hs_button_counter"`
	HSButtonPrev              int64  `json:"hs_button_counter_prev"`
	HSBattery                 int64  `json:"hs_button_battery"`
	HSRandomNonce             string `json:"hs_button_random"`
	HSButtonMode              string `json:"hs_button_mode"`
	Event                     int    `json:"beacon_event"`
}

type BeaconEvent struct {
	Name    string
	ID      string
	Type    string
	Battery uint32
	Event   int
}

// Button represents a hardware button beacon device.
type Button struct {
	Name            string              `json:"name"`
	ButtonID        string              `json:"button_id"`
	ButtonType      string              `json:"button_type"`
	ButtonLocation  string              `json:"button_location"`
	IncomingJSON    BeaconAdvertisement `json:"incoming_json"`
	Distance        float64             `json:"distance"`
	LastSeen        int64               `json:"last_seen"`
	HSButtonCounter int64               `json:"hs_button_counter"`
	HSBattery       int64               `json:"hs_button_battery"`
	HSRandomNonce   string              `json:"hs_button_random"`
	HSButtonMode    string              `json:"hs_button_mode"`
}

// BeaconsList holds all known beacons and their synchronization lock.
type BeaconsList struct {
	Beacons map[string]Beacon `json:"beacons"`
	Lock    sync.RWMutex
}

type BeaconEventList struct {
	Beacons map[string]BeaconEvent
	Lock    sync.RWMutex
}

// LocationsList holds all known locations with concurrency protection.
type LocationsList struct {
	Locations map[string]Location
	Lock      sync.RWMutex
}

// Message defines the WebSocket or broadcast message payload.
type Message struct {
	Email    string `json:"email"`
	Username string `json:"username"`
	Message  string `json:"message"`
}

// RawReading represents an incoming raw sensor reading.
type RawReading struct {
	Timestamp string `json:"timestamp"`
	Type      string `json:"type"`
	MAC       string `json:"mac"`
	RSSI      int    `json:"rssi"`
	RawData   string `json:"rawData"`
}

type LatestBeaconsList struct {
	LatestList map[string]Beacon
	Lock       sync.RWMutex
}

type HTTPLocationsList struct {
	Beacons []HTTPLocation `json:"beacons"`
}

type HTTPResultsList struct {
	HTTPResultsLock sync.RWMutex
	HTTPResults     HTTPLocationsList
}

type ApiUpdate struct {
	Method string
	Beacon Beacon
	ID     string
}

type KafkaReadersList struct {
	KafkaReadersLock sync.RWMutex
	KafkaReaders     []*kafka.Reader
}

type KafkaWritersList struct {
	KafkaWritersLock sync.RWMutex
	KafkaWriters     []*kafka.Writer
}

var HTTPHostPathPtr *string
var HTTPWSHostPathPtr *string
