package repository

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

	"be.ems/src/framework/database/db"
	"be.ems/src/modules/ne_data/model"
	"gorm.io/gorm"
)

// 实例化数据层 UEEvent 结构体
var NewCBCMessage = &CBCMessage{}

// UEEvent UE会话事件 数据层处理
type CBCMessage struct{}

// SelectCBCMessage 根据条件分页查询CB消息
func (s *CBCMessage) SelectByPage(query model.CBCMessageQuery) ([]model.CBCMessage, int, error) {
	var msg []model.CBCMessage
	var total int64

	tx := db.DB("").Table("cbc_message")

	if query.NeType != "" {
		tx = tx.Where("ne_type = ?", query.NeType)
	}
	if query.NeId != "" {
		tx = tx.Where("ne_id = ?", query.NeId)
	}
	if query.EventName != "" {
		tx = tx.Where("JSON_EXTRACT(message_json, '$.eventName') = ?", query.EventName)
	}
	if query.Status != "" {
		tx = tx.Where("status = ?", query.Status)
	}

	var startMicro, endMicro int64
	var err error
	if query.StartTime != "" {
		startMicro, err = parseTimeToMilli(query.StartTime)
		if err != nil {
			return nil, 0, fmt.Errorf("invalid start time: %w", err)
		}
	}
	if query.EndTime != "" {
		endMicro, err = parseTimeToMilli(query.EndTime)
		if err != nil {
			return nil, 0, fmt.Errorf("invalid end time: %w", err)
		}
	}
	if startMicro > 0 && endMicro > 0 {
		tx = tx.Where("created_at BETWEEN ? AND ?", startMicro, endMicro)
	} else if startMicro > 0 {
		tx = tx.Where("created_at >= ?", startMicro)
	} else if endMicro > 0 {
		tx = tx.Where("created_at <= ?", endMicro)
	}

	// 统计总数
	if err := tx.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
	}

	// 分页查询
	offset := (query.PageNum - 1) * query.PageSize
	if err := tx.Limit(query.PageSize).Offset(offset).Order("created_at desc").Find(&msg).Error; err != nil {
		return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
	}

	return msg, int(total), nil
}

// SelectCBCMessageByPage 分页查询CB消息
// @Description 分页查询CB消息
// @param page 页码
// @param pageSize 每页大小
// @return []model.CBCMessage CB消息列表
// @return int 总记录数
// @return error 错误信息
// @example
// SelectByPage(1, 10)
// func (s *CBCMessage) SelectByPage(pageNum int, pageSize int) ([]model.CBCMessage, int, error) {
// 	var tickets []model.CBCMessage
// 	var total int64

// 	// 统计总数
// 	if err := db.DB("").Table("cbc_message").Count(&total).Error; err != nil {
// 		return nil, 0, fmt.Errorf("failed to count CBC message: %w", err)
// 	}

// 	// 分页查询
// 	offset := (pageNum - 1) * pageSize
// 	if err := db.DB("").Table("cbc_message").
// 		Limit(pageSize).
// 		Offset(offset).
// 		Find(&tickets).Error; err != nil {
// 		return nil, 0, fmt.Errorf("failed to select CBC message: %w", err)
// 	}

// 	return tickets, int(total), nil
// }

// InsertCBCMessage 插入CB消息
// @Description 插入CB消息
// @param msg CB消息对象
// @return error 错误信息
// @example
// CBCMessage.InsertCBCMessage(msg)
func (s *CBCMessage) Insert(msg model.CBCMessage) error {
	msg.CreatedAt = time.Now().UnixMilli()
	// 这里可以使用ORM或其他方式将ticket插入到数据库中
	if err := db.DB("").Table("cbc_message").Create(&msg).Error; err != nil {
		return fmt.Errorf("failed to insert CBC message: %w", err)
	}
	return nil
}

// SelectCBCMessageById 根据工单ID查询CB消息
// @Description 根据工单ID查询CB消息
// @param id 工单ID
// @return *model.CBCMessage CB消息对象
// @return error 错误信息
// @example
// CBCMessage.SelectCBCMessageById(12345)
func (s *CBCMessage) SelectById(id int64) (*model.CBCMessage, error) {
	var msg model.CBCMessage
	if err := db.DB("").Table("cbc_message").
		Where("id = ?", id).
		First(&msg).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, fmt.Errorf("failed to select CBC message: %w", err)
	}
	return &msg, nil
}

// SelectByEventName 根据事件名称查询CB消息
func (s *CBCMessage) SelectByEventName(eventName string) (*model.CBCMessage, error) {
	var msg model.CBCMessage
	if err := db.DB("").Table("cbc_message").
		Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
		First(&msg).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &msg, nil
}

// UpdateCBCMessage 更新CB消息
// @Description 更新CB消息
// @param msg CB消息对象
// @return error 错误信息
// @example
// mfCBCMessageService.UpdateCBCMessage(msg)
func (s *CBCMessage) Update(id int64, messageJson json.RawMessage) (*model.CBCMessage, error) {
	var msg model.CBCMessage
	now := time.Now().UnixMilli()

	err := db.DB("").Transaction(func(tx *gorm.DB) error {
		// 在事务中更新
		if err := tx.Table("cbc_message").
			Where("id = ?", id).
			Updates(map[string]any{
				"message_json": messageJson,
				"updated_at":   now,
			}).Error; err != nil {
			return fmt.Errorf("failed to update CBC message: %w", err)
		}

		// 在事务中查询更新后的记录
		if err := tx.Table("cbc_message").
			Where("id = ?", id).
			First(&msg).Error; err != nil {
			return fmt.Errorf("failed to fetch updated CBC message: %w", err)
		}

		return nil
	})

	if err != nil {
		return nil, err
	}

	return &msg, nil
}

// UpdateCBCMessage 更新CB消息
// @Description 更新CB消息
// @param msg CB消息对象
// @return error 错误信息
// @example
// UpdateCBCMessageDetail(msg)
func (s *CBCMessage) UpdateDetail(eventName, detail string) error {
	now := time.Now().UnixMilli()
	if err := db.DB("").Table("cbc_message").
		Where("JSON_EXTRACT(message_json, '$.eventName') = ?", eventName).
		Updates(map[string]any{
			"detail":     detail,
			"updated_at": now,
		}).Error; err != nil {
		return fmt.Errorf("failed to update CBC message: %w", err)
	}

	return nil
}

// DeleteCBCMessage 删除CB消息
// @Description 删除CB消息
// @param id 工单ID
// @return error 错误信息
// @example
// DeleteCBCMessage(12345)
func (s *CBCMessage) Delete(id int64) error {
	// 执行删除操作
	if err := db.DB("").Table("cbc_message").
		Where("id = ?", id).
		Delete(&model.CBCMessage{}).Error; err != nil {
		return fmt.Errorf("failed to delete CBC message: %w", err)
	}
	return nil
}

// UpdateCBCMessageStatus 更新CB消息状态
// @Description 更新CB消息状态，并根据状态变化发送相应的HTTP请求
// @param status 新状态
// @return error 错误信息
func (s *CBCMessage) UpdateStatus(id int64, status model.CBCEventStatus) error {
	// 更新数据库状态
	now := time.Now().UnixMilli()
	if err := db.DB("").Table("cbc_message").
		Where("id = ?", id).
		Updates(map[string]interface{}{
			"status":     status,
			"updated_at": now,
		}).Error; err != nil {
		return fmt.Errorf("failed to update CBC message status: %w", err)
	}

	return nil
}

// Select 查询所有CB消息
func (s *CBCMessage) Select(msgs *[]model.CBCMessage) error {
	if err := db.DB("").Table("cbc_message").Find(&msgs).Error; err != nil {
		return fmt.Errorf("failed to query CB messages: %w", err)
	}
	return nil
}

// SelectByNeId 根据网元ID查询CB消息
func (s *CBCMessage) SelectByNeId(neId string, msgs *[]model.CBCMessage) error {
	if err := db.DB("").Table("cbc_message").Where("ne_id = ?", neId).Find(&msgs).Error; err != nil {
		return fmt.Errorf("failed to query CB messages: %w", err)
	}
	return nil
}

// 假设 query.StartTime 和 query.EndTime 是 "2006-01-02 15:04:05" 格式字符串
func parseTimeToMilli(ts string) (int64, error) {
	if ts == "" {
		return 0, nil
	}
	t, err := time.ParseInLocation("2006-01-02 15:04:05", ts, time.Local)
	if err != nil {
		return 0, err
	}
	return t.UnixMilli(), nil
}
