// Package device 提供设备控制相关功能的控制器
// 实现设备控制、查询等操作
package device

import (
	"git.huangwc.com/pig/pig-farm-controller/internal/api/middleware"
	"git.huangwc.com/pig/pig-farm-controller/internal/controller"
	"git.huangwc.com/pig/pig-farm-controller/internal/logs"
	"git.huangwc.com/pig/pig-farm-controller/internal/model"
	"git.huangwc.com/pig/pig-farm-controller/internal/service"
	"git.huangwc.com/pig/pig-farm-controller/internal/storage/repository"
	"github.com/gin-gonic/gin"
)

// Controller 设备控制控制器
type Controller struct {
	deviceControlRepo repository.DeviceControlRepo
	deviceRepo        repository.DeviceRepo
	websocketService  *service.WebSocketService
	logger            *logs.Logger
}

// NewController 创建设备控制控制器实例
func NewController(deviceControlRepo repository.DeviceControlRepo, deviceRepo repository.DeviceRepo, websocketService *service.WebSocketService) *Controller {
	return &Controller{
		deviceControlRepo: deviceControlRepo,
		deviceRepo:        deviceRepo,
		websocketService:  websocketService,
		logger:            logs.NewLogger(),
	}
}

// SwitchRequest 设备控制请求结构体
type SwitchRequest struct {
	ParentID   *uint  `json:"parent_id"` // 区域主控ID
	DeviceType string `json:"device_type" binding:"required,oneof=fan water_curtain"`
	DeviceID   string `json:"device_id" binding:"required"`
	Action     string `json:"action" binding:"required,oneof=on off"`
}

// SwitchResponseData 设备控制响应数据结构体
type SwitchResponseData struct {
	DeviceType string `json:"device_type"`
	DeviceID   string `json:"device_id"`
	Action     string `json:"action"`
}

// Switch 设备控制接口
func (c *Controller) Switch(ctx *gin.Context) {
	// 从上下文中获取用户信息
	userValue, exists := ctx.Get("user")
	if !exists {
		controller.SendErrorResponse(ctx, controller.UnauthorizedCode, "无法获取用户信息")
		return
	}

	user, ok := userValue.(*middleware.AuthUser)
	if !ok {
		controller.SendErrorResponse(ctx, controller.InternalServerErrorCode, "用户信息格式错误")
		return
	}

	var req SwitchRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		controller.SendErrorResponse(ctx, controller.InvalidParameterCode, "请求参数错误")
		return
	}

	// 通过WebSocket向中继设备发送控制指令
	// 这里假设中继设备ID为"relay-001"，在实际应用中应该根据设备层级结构动态获取
	controlData := map[string]interface{}{
		"device_type": req.DeviceType,
		"device_id":   req.DeviceID,
		"action":      req.Action,
	}

	err := c.websocketService.SendCommand("relay-001", "control_device", controlData)
	if err != nil {
		c.logger.Error("通过WebSocket发送设备控制指令失败: " + err.Error())
		controller.SendErrorResponse(ctx, controller.InternalServerErrorCode, "设备控制失败")
		return
	}

	// 创建设备控制记录
	if err := c.createDeviceControlRecord(
		user.ID,
		req.DeviceID,
		req.DeviceType,
		req.Action,
		"success",
		"设备控制成功",
	); err != nil {
		c.logger.Error("创建设备控制记录失败: " + err.Error())
		controller.SendErrorResponse(ctx, controller.InternalServerErrorCode, "设备控制失败")
		return
	}

	data := SwitchResponseData{
		DeviceType: req.DeviceType,
		DeviceID:   req.DeviceID,
		Action:     req.Action,
	}

	controller.SendSuccessResponse(ctx, "设备控制成功", data)
}

// createDeviceControlRecord 创建设备控制记录
func (c *Controller) createDeviceControlRecord(userID uint, deviceID, deviceType, action, status, result string) error {
	// 获取设备信息
	device, err := c.deviceRepo.FindByIDString(deviceID)
	if err != nil {
		return err
	}

	// 构建位置信息
	var location string
	switch device.Type {
	case model.DeviceTypeRelay:
		// 如果设备本身就是中继设备
		location = device.Name
	case model.DeviceTypePigPenController, model.DeviceTypeFeedMillController:
		// 如果设备本身就是区域主控设备
		if device.ParentID != nil {
			// 获取中继设备
			relayDevice, err := c.deviceRepo.FindByID(*device.ParentID)
			if err != nil {
				location = device.Name
			} else {
				location = relayDevice.Name + " -> " + device.Name
			}
		} else {
			location = device.Name
		}
	default:
		// 如果是普通设备（风机、水帘等）
		if device.ParentID != nil {
			// 获取区域主控设备
			parentDevice, err := c.deviceRepo.FindByID(*device.ParentID)
			if err != nil {
				location = "未知区域"
			} else {
				// 检查区域主控设备是否有上级设备（中继设备）
				if parentDevice.ParentID != nil {
					// 获取中继设备
					relayDevice, err := c.deviceRepo.FindByID(*parentDevice.ParentID)
					if err != nil {
						location = parentDevice.Name
					} else {
						location = relayDevice.Name + " -> " + parentDevice.Name
					}
				} else {
					location = parentDevice.Name
				}
			}
		} else {
			location = "未知区域"
		}
	}

	control := &model.DeviceControl{
		UserID:     userID,
		Location:   location,
		DeviceType: model.DeviceType(deviceType),
		DeviceID:   deviceID,
		Action:     action,
		Status:     status,
		Result:     result,
	}

	return c.deviceControlRepo.Create(control)
}
