package handler

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"go_rain_dtu/internal/dao"
	"go_rain_dtu/internal/model"
	"go_rain_dtu/internal/tcp"
	"go_rain_dtu/pkg/logger"
)

type SensorHandler struct {
	dao *dao.SensorDAO
}

func NewSensorHandler(dao *dao.SensorDAO) *SensorHandler {
	return &SensorHandler{dao: dao}
}

func (h *SensorHandler) GetAggregatedData(w http.ResponseWriter, r *http.Request) {
	interval := r.URL.Query().Get("interval")
	if interval == "" {
		interval = "1hour"
	}

	// 获取中国时区
	chinaLoc, locErr := time.LoadLocation("Asia/Shanghai")
	if locErr != nil {
		chinaLoc = time.FixedZone("CST", 8*60*60)
	}

	endTime := time.Now().In(chinaLoc)
	startTime := endTime.Add(-24 * time.Hour) // 默认显示24小时数据

	if startStr := r.URL.Query().Get("start"); startStr != "" {
		if t, parseErr := time.Parse(time.RFC3339, startStr); parseErr == nil {
			startTime = t.In(chinaLoc)
		}
	}
	if endStr := r.URL.Query().Get("end"); endStr != "" {
		if t, parseErr := time.Parse(time.RFC3339, endStr); parseErr == nil {
			endTime = t.In(chinaLoc)
		}
	}

	var data []model.AggregatedData
	var err error

	// 判断是否获取原始数据
	if interval == "raw" {
		data, err = h.dao.GetRawData(startTime, endTime)
	} else {
		data, err = h.dao.GetAggregatedData(startTime, endTime, interval)
	}

	if err != nil {
		logger.Logger.Printf("获取数据失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	// 使用自定义的编码器，设置时间格式
	encoder := json.NewEncoder(w)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(data); err != nil {
		logger.Logger.Printf("JSON编码失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}
}

// 处理静态文件
func (h *SensorHandler) ServeStatic(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/" {
		http.ServeFile(w, r, "static/index.html")
		return
	}
	http.FileServer(http.Dir("static")).ServeHTTP(w, r)
}

// GetConnectionStatus 返回当前TCP连接状态
func (h *SensorHandler) GetConnectionStatus(w http.ResponseWriter, r *http.Request) {
	connected, ip, port := tcp.GetConnectionStatus()

	status := struct {
		Connected bool   `json:"connected"`
		IP        string `json:"ip"`
		Port      string `json:"port"`
		Count     int    `json:"count"` // 添加连接数量
	}{
		Connected: connected,
		IP:        ip,
		Port:      port,
		Count:     tcp.GetActiveConnectionCount(), // 获取活跃连接数
	}

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(status); err != nil {
		logger.Logger.Printf("JSON编码失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
	}
}

// GetLatestData 获取最新的聚合数据
func (h *SensorHandler) GetLatestData(w http.ResponseWriter, r *http.Request) {
	interval := r.URL.Query().Get("interval")
	if interval == "" {
		interval = "5min" // 默认使用更细粒度的时间间隔
	}

	// 默认查询最近1小时的数据
	endTime := time.Now()
	startTime := endTime.Add(-1 * time.Hour)

	// 如果提供了时间范围，则使用提供的范围
	if startStr := r.URL.Query().Get("start"); startStr != "" {
		if t, err := time.Parse(time.RFC3339, startStr); err == nil {
			startTime = t
		}
	}
	if endStr := r.URL.Query().Get("end"); endStr != "" {
		if t, err := time.Parse(time.RFC3339, endStr); err == nil {
			endTime = t
		}
	}

	// 查询数据库获取数据
	var data []model.AggregatedData
	var err error

	// 判断是否获取原始数据
	if interval == "raw" {
		data, err = h.dao.GetRawData(startTime, endTime)
	} else {
		data, err = h.dao.GetAggregatedData(startTime, endTime, interval)
	}

	if err != nil {
		logger.Logger.Printf("获取数据失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	encoder := json.NewEncoder(w)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(data); err != nil {
		logger.Logger.Printf("JSON编码失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}
}

// GetLatestSensorRawData 获取最新的一条传感器原始数据
func (h *SensorHandler) GetLatestSensorRawData(w http.ResponseWriter, r *http.Request) {
	data, err := h.dao.GetLatestSensorData()
	if err != nil {
		logger.Logger.Printf("获取最新传感器数据失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}

	if data == nil {
		// 没有数据，返回空对象
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte("{}"))
		return
	}

	// 将时间调整为中国时区(UTC+8)
	chinaLoc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		// 如果无法加载时区，手动创建UTC+8的时区
		chinaLoc = time.FixedZone("CST", 8*60*60)
	}
	chinaTime := data.Timestamp.In(chinaLoc)

	// 转换为前端友好的格式
	response := struct {
		ID               int64     `json:"id"`
		Timestamp        time.Time `json:"timestamp"`
		FormattedTime    string    `json:"formatted_time"`
		WindSpeed        float64   `json:"wind_speed"`         // 风速(m/s)
		WindForce        int       `json:"wind_force"`         // 风力(级)
		WindDirection8   int       `json:"wind_direction_8"`   // 8方位风向
		WindDirection360 int       `json:"wind_direction_360"` // 360度风向
		Humidity         float64   `json:"humidity"`           // 湿度(%)
		Temperature      float64   `json:"temperature"`        // 温度(℃)
		AtmPressure      float64   `json:"atm_pressure"`       // 大气压(kPa)
		SolarRadiation   int       `json:"solar_radiation"`    // 太阳辐射(W/m²)
		Rainfall         float64   `json:"rainfall"`           // 累计雨量(mm)
	}{
		ID:               data.ID,
		Timestamp:        data.Timestamp,
		FormattedTime:    chinaTime.Format("2006-01-02 15:04:05"),
		WindSpeed:        float64(data.WindSpeed) / 100.0,
		WindForce:        data.WindForce,
		WindDirection8:   data.WindDirection8,
		WindDirection360: data.WindDirection360,
		Humidity:         float64(data.Humidity) / 10.0,
		Temperature:      float64(data.Temperature) / 10.0,
		AtmPressure:      float64(data.AtmPressure) / 10.0,
		SolarRadiation:   data.SolarRadiation,
		Rainfall:         float64(data.OpticalRain) / 10.0,
	}

	w.Header().Set("Content-Type", "application/json")
	encoder := json.NewEncoder(w)
	encoder.SetIndent("", "  ")
	if err := encoder.Encode(response); err != nil {
		logger.Logger.Printf("JSON编码失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}
}

// TriggerManualQuery 手动触发向所有设备发送查询指令
func (h *SensorHandler) TriggerManualQuery(w http.ResponseWriter, r *http.Request) {
	count := tcp.TriggerManualQuery()

	response := struct {
		Success bool   `json:"success"`
		Message string `json:"message"`
		Count   int    `json:"count"`
	}{
		Success: count > 0,
		Message: fmt.Sprintf("成功向%d个设备发送查询指令", count),
		Count:   count,
	}

	w.Header().Set("Content-Type", "application/json")
	encoder := json.NewEncoder(w)
	if err := encoder.Encode(response); err != nil {
		logger.Logger.Printf("JSON编码失败: %v", err)
		http.Error(w, "服务器内部错误", http.StatusInternalServerError)
	}
}
