package common

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"runtime"
	"strconv"
	"strings"
	"time"
)

type Response struct {
	Msg  string                 `json:"msg"`
	Code int                    `json:"code"`
	Data map[string]interface{} `json:"data"`
	Type string                 `json:"type"`
}

type Resp struct {
	Code    int           `json:"code"`
	Message string        `json:"message"`
	Data    []interface{} `json:"data"`
}

type InterfaceResp struct {
	Status int         `json:"code"`
	Err    string      `json:"message"`
	Data   interface{} `json:"data"`
}

func GenLogLine() string {
	pc, _, _, ok := runtime.Caller(1)
	if !ok {
		return "unknown"
	}

	// 获取函数信息
	f := runtime.FuncForPC(pc)
	if f == nil {
		return "unknown"
	}

	// 获取文件名和行号
	file, line := f.FileLine(pc)

	// 获取函数名
	funcName := f.Name()

	return fmt.Sprintf("file:%s; func:%s %d行：", TruncateLastSlash(file), TruncateLastSlash(funcName), line)
}

func FloatSliceToString(floats []float64) string {
	var strSlice []string
	for _, f := range floats {
		strSlice = append(strSlice, strconv.FormatFloat(f, 'f', -1, 64))
	}
	return "[" + strings.Join(strSlice, ", ") + "]"
}

func TruncateLastSlash(inputString string) string {
	lastIndex := strings.LastIndex(inputString, "/")
	if lastIndex == -1 {
		// 没有反斜线，返回原始字符串
		return inputString
	}

	// 截断字符串并返回
	return inputString[lastIndex+1:]
}

func GetToken() (string, error) {
	url := ConfigData.FetchTokenUrl
	method := "POST"
	Info(GenLogLine() + "获取token")
	token := GetCache("token")
	if "" != token {
		Info(GenLogLine() + "====get token from cache====")
		return token, nil
	}

	payload := fmt.Sprintf(`{"deviceId":"%s"}`, ConfigData.DevId)
	input := strings.NewReader(payload)
	client := &http.Client{}
	req, err := http.NewRequest(method, url, input)

	if err != nil {
		return "", fmt.Errorf("create request fail: %w", err)
	}
	req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	if err != nil {
		fmt.Errorf(GenLogLine()+"%s", err)
		Error(GenLogLine()+"%s", err)
		return "", fmt.Errorf("request fail: %w", err)
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		fmt.Errorf(GenLogLine()+"%s", err)
		Error(GenLogLine()+"%s", err)
		return "", fmt.Errorf("handle resp fail: %w", err)
	}

	var response Response
	err = json.Unmarshal([]byte(string(body)), &response)
	if err != nil {
		Error("Error:", err)
	}
	Info(GenLogLine()+"token:====", response.Data["access_token"])
	result := response.Data["access_token"].(string)
	SetCacheWithExpire("token", result, 3600)
	return result, nil
}

func CovertTime(timeStr string) string {
	location, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println("Error loading location:", err)
		return ""
	}

	// 解析日期字符串
	parsedDate, err := time.ParseInLocation("2006-01-02", timeStr, location)
	if err != nil {
		fmt.Println("Error parsing date:", err)
		return ""
	}

	// 输出日期
	fmt.Println("Parsed Date:", parsedDate)

	// 将日期格式化为字符串
	formattedDate := parsedDate.Format("2006-01-02")
	fmt.Println("Formatted Date:", formattedDate)

	// 传递给 Java 的字符串日期（带时区信息）
	javaDateString := parsedDate.Format("2006-01-02T15:04:05Z07:00")
	return javaDateString
}

func exec() {
	ticker := time.NewTicker(5 * time.Minute)
	defer ticker.Stop()

	for range ticker.C {
		// 请求接口A
		respA, err := http.Get("http://localhost:8080/api/interfaceA")
		if err != nil {
			fmt.Println("请求接口A失败：", err)
			continue
		}
		defer respA.Body.Close()

		// 读取接口A返回的数据
		dataA, err := io.ReadAll(respA.Body)
		if err != nil {
			fmt.Println("读取接口A返回数据失败：", err)
			continue
		}

		// 将接口A返回的数据通过接口B发送到某个系统
		respB, err := http.Post("http://localhost:8080/api/interfaceB", "application/json", bytes.NewBuffer(dataA))
		if err != nil {
			Error("发送数据到接口B失败：", err)
			continue
		}
		defer respB.Body.Close()

		// 检查接口B的响应状态
		if respB.StatusCode == http.StatusOK {
			Info(GenLogLine() + "数据发送成功")
		} else {
			Error("数据发送失败，状态码：", respB.StatusCode)
		}
	}
}

func AryContainInt(s []int, str int) bool {
	found := false
	for _, value := range s {
		if value == str {
			found = true
			break
		}
	}
	return found
}

func AryContainStr(s []string, str string) bool {
	found := false
	for _, value := range s {
		if value == str {
			found = true
			break
		}
	}
	return found
}
