package alert

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"sync"
	"time"
)

// WeChatAlert 企业微信告警推送
type WeChatAlert struct {
	webhookURL  string
	enabled     bool
	dedupWindow time.Duration
	client      *http.Client
	mu          sync.Mutex
	dedupCache  map[string]time.Time // 去重缓存: key = "type:target"
}

// NewWeChatAlert 创建企业微信告警器
func NewWeChatAlert(webhookURL string, enabled bool, dedupWindow time.Duration) *WeChatAlert {
	return &WeChatAlert{
		webhookURL:  webhookURL,
		enabled:     enabled,
		dedupWindow: dedupWindow,
		client: &http.Client{
			Timeout: 10 * time.Second,
		},
		dedupCache: make(map[string]time.Time),
	}
}

// AlertMessage 告警消息
type AlertMessage struct {
	Type     string // 巡检类型
	Target   string // 目标
	Level    string // 级别: warning / critical
	Title    string // 标题
	Content  string // 内容
	Time     time.Time
}

// weChatPayload 企业微信 Webhook 请求体
type weChatPayload struct {
	MsgType  string         `json:"msgtype"`
	Markdown weChatMarkdown `json:"markdown"`
}

type weChatMarkdown struct {
	Content string `json:"content"`
}

// Send 发送告警消息
func (w *WeChatAlert) Send(msg *AlertMessage) error {
	if !w.enabled {
		log.Printf("[INFO] 告警推送已禁用，跳过: %s - %s", msg.Title, msg.Target)
		return nil
	}

	// 去重检查
	dedupKey := fmt.Sprintf("%s:%s", msg.Type, msg.Target)
	if w.isDuplicate(dedupKey) {
		log.Printf("[INFO] 告警去重，跳过: %s - %s", msg.Title, msg.Target)
		return nil
	}

	content := w.formatMessage(msg)

	payload := weChatPayload{
		MsgType: "markdown",
		Markdown: weChatMarkdown{
			Content: content,
		},
	}

	body, err := json.Marshal(payload)
	if err != nil {
		return fmt.Errorf("序列化告警消息失败: %w", err)
	}

	resp, err := w.client.Post(w.webhookURL, "application/json", bytes.NewReader(body))
	if err != nil {
		return fmt.Errorf("推送企业微信告警失败: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("企业微信返回状态码 %d", resp.StatusCode)
	}

	// 更新去重缓存
	w.updateDedup(dedupKey)

	log.Printf("[INFO] 告警已推送: %s - %s", msg.Title, msg.Target)
	return nil
}

// SendBatch 批量发送告警
func (w *WeChatAlert) SendBatch(messages []*AlertMessage) []error {
	var errs []error
	for _, msg := range messages {
		if err := w.Send(msg); err != nil {
			errs = append(errs, fmt.Errorf("推送 %s 告警失败: %w", msg.Target, err))
		}
	}
	return errs
}

// formatMessage 格式化告警消息为 Markdown
func (w *WeChatAlert) formatMessage(msg *AlertMessage) string {
	var sb strings.Builder

	// 标题带颜色标识
	emoji := "⚠️"
	if msg.Level == "critical" {
		emoji = "🔴"
	}

	sb.WriteString(fmt.Sprintf("%s **%s**\n", emoji, msg.Title))
	sb.WriteString(fmt.Sprintf("> **级别**: %s\n", strings.ToUpper(msg.Level)))
	sb.WriteString(fmt.Sprintf("> **目标**: %s\n", msg.Target))
	sb.WriteString(fmt.Sprintf("> **时间**: %s\n", msg.Time.Format("2006-01-02 15:04:05")))
	sb.WriteString(fmt.Sprintf("> **详情**:\n%s\n", msg.Content))

	return sb.String()
}

// isDuplicate 检查是否为重复告警
func (w *WeChatAlert) isDuplicate(key string) bool {
	w.mu.Lock()
	defer w.mu.Unlock()

	if lastSent, ok := w.dedupCache[key]; ok {
		if time.Since(lastSent) < w.dedupWindow {
			return true
		}
		// 清理过期缓存
		delete(w.dedupCache, key)
	}
	return false
}

// updateDedup 更新去重缓存
func (w *WeChatAlert) updateDedup(key string) {
	w.mu.Lock()
	defer w.mu.Unlock()
	w.dedupCache[key] = time.Now()
}

// CleanDedupCache 清理过期的去重缓存
func (w *WeChatAlert) CleanDedupCache() {
	w.mu.Lock()
	defer w.mu.Unlock()

	now := time.Now()
	for key, sentAt := range w.dedupCache {
		if now.Sub(sentAt) > w.dedupWindow {
			delete(w.dedupCache, key)
		}
	}
}
