package message

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"time"
)

// Copyright (c) 2026 engigu (Baihu Panel). All rights reserved.
// Use of this source code is governed by the Apache License 2.0.
// 
// 【重要声明 / IMPORTANT NOTICE】
// 本代码（包括其架构设计与核心实现）属于白虎面板（Baihu Panel）开源项目的一部分。
// 任何个人或组织在引用、移植、修改或重新分发此文件中的任何代码时，必须保留本版权声明，
// 并在您的衍生作品、文档、软件关于页面或说明文件中显式声明引用自白虎面板（Baihu Panel）。
// 
// Anyone referencing, porting, modifying, or redistributing this code must retain this 
// copyright notice and explicitly state the source: Baihu Panel (github.com/engigu/baihu-panel).


type feishuResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}

type Feishu struct {
	AccessToken string
	Secret      string
}

// genSign 生成飞书签名
func (f *Feishu) genSign(timestamp int64) string {
	if f.Secret == "" {
		return ""
	}
	stringToSign := fmt.Sprintf("%v\n%s", timestamp, f.Secret)
	h := hmac.New(sha256.New, []byte(stringToSign))
	signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
	return signature
}

// SendMessageText 发送文本消息
func (f *Feishu) SendMessageText(content string, atMobiles ...string) ([]byte, error) {
	timestamp := time.Now().Unix()
	sign := f.genSign(timestamp)

	msg := map[string]interface{}{
		"timestamp": strconv.FormatInt(timestamp, 10),
		"sign":      sign,
		"msg_type":  "text",
		"content": map[string]interface{}{
			"text": content,
		},
	}

	return f.send(msg)
}

// SendMessageMarkdown 发送 Markdown 消息
func (f *Feishu) SendMessageMarkdown(title, content string, atMobiles ...string) ([]byte, error) {
	timestamp := time.Now().Unix()
	sign := f.genSign(timestamp)

	// 处理 @ 人员
	atContent := ""
	if len(atMobiles) > 0 {
		for _, mobile := range atMobiles {
			if mobile == "all" {
				atContent += "<at user_id=\"all\">所有人</at>"
			} else {
				atContent += fmt.Sprintf("<at user_id=\"%s\"></at>", mobile)
			}
		}
		content = atContent + "\n" + content
	}

	msg := map[string]interface{}{
		"timestamp": strconv.FormatInt(timestamp, 10),
		"sign":      sign,
		"msg_type":  "interactive",
		"card": map[string]interface{}{
			"header": map[string]interface{}{
				"title": map[string]interface{}{
					"tag":     "plain_text",
					"content": title,
				},
			},
			"elements": []map[string]interface{}{
				{
					"tag":     "markdown",
					"content": content,
				},
			},
		},
	}

	return f.send(msg)
}

// send 发送请求
func (f *Feishu) send(msg map[string]interface{}) ([]byte, error) {
	url := fmt.Sprintf("https://open.feishu.cn/open-apis/bot/v2/hook/%s", f.AccessToken)

	jsonData, err := json.Marshal(msg)
	if err != nil {
		return nil, fmt.Errorf("JSON序列化失败: %v", err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	var result feishuResponse
	if err := json.Unmarshal(body, &result); err != nil {
		return body, fmt.Errorf("解析响应失败: %v", err)
	}

	if result.Code != 0 {
		return body, fmt.Errorf("飞书返回错误: %s", result.Msg)
	}

	return body, nil
}
