package services

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

var (
	logDir    string
	isDevMode bool
	logLevel  string = "INFO" // DEBUG, INFO, WARN, ERROR
)

func init() {
	// 检测是否为开发模式
	// 通过环境变量 DEV 或可执行文件名判断
	isDevMode = os.Getenv("DEV") == "true" ||
		strings.Contains(os.Args[0], "dev") ||
		strings.Contains(os.Args[0], ".dev")

	// 开发模式下默认使用 DEBUG 级别
	if isDevMode {
		logLevel = "DEBUG"
		log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile)
	} else {
		log.SetFlags(log.LstdFlags)
	}

	// 设置日志目录
	exePath, err := os.Executable()
	if err != nil {
		logDir = "./Log"
	} else {
		logDir = filepath.Join(filepath.Dir(exePath), "Log")
	}
	os.MkdirAll(logDir, 0755)
}

// SetLogLevel 设置日志级别
func SetLogLevel(level string) {
	logLevel = strings.ToUpper(level)
}

// IsDevMode 返回是否为开发模式
func IsDevMode() bool {
	return isDevMode
}

// shouldLog 判断是否应该记录该级别的日志
func shouldLog(level string) bool {
	levels := map[string]int{
		"DEBUG": 0,
		"INFO":  1,
		"WARN":  2,
		"ERROR": 3,
	}
	currentLevel, ok := levels[logLevel]
	if !ok {
		currentLevel = 1
	}
	msgLevel, ok := levels[strings.ToUpper(level)]
	if !ok {
		msgLevel = 1
	}
	return msgLevel >= currentLevel
}

// getCallerInfo 获取调用者信息（仅在开发模式下）
func getCallerInfo() string {
	if !isDevMode {
		return ""
	}
	pc, file, line, ok := runtime.Caller(3)
	if ok {
		funcName := runtime.FuncForPC(pc).Name()
		// 只取函数名，去掉包路径
		parts := strings.Split(funcName, ".")
		funcName = parts[len(parts)-1]
		// 只取文件名
		fileParts := strings.Split(file, "/")
		fileName := fileParts[len(fileParts)-1]
		return fmt.Sprintf("[%s:%d %s]", fileName, line, funcName)
	}
	return ""
}

// LogInfo 记录信息日志
func LogInfo(message string) {
	if !shouldLog("INFO") {
		return
	}
	callerInfo := getCallerInfo()
	logMessage("INFO", callerInfo+" "+message)
}

// LogError 记录错误日志
func LogError(message string) {
	if !shouldLog("ERROR") {
		return
	}
	callerInfo := getCallerInfo()
	logMessage("ERROR", callerInfo+" "+message)
}

// LogWarn 记录警告日志
func LogWarn(message string) {
	if !shouldLog("WARN") {
		return
	}
	callerInfo := getCallerInfo()
	logMessage("WARN", callerInfo+" "+message)
}

// LogDebug 记录调试日志
func LogDebug(message string) {
	if !shouldLog("DEBUG") {
		return
	}
	callerInfo := getCallerInfo()
	logMessage("DEBUG", callerInfo+" "+message)
}

// LogDebugf 格式化调试日志
func LogDebugf(format string, args ...interface{}) {
	if !shouldLog("DEBUG") {
		return
	}
	callerInfo := getCallerInfo()
	message := fmt.Sprintf(format, args...)
	logMessage("DEBUG", callerInfo+" "+message)
}

// LogInfof 格式化信息日志
func LogInfof(format string, args ...interface{}) {
	if !shouldLog("INFO") {
		return
	}
	callerInfo := getCallerInfo()
	message := fmt.Sprintf(format, args...)
	logMessage("INFO", callerInfo+" "+message)
}

// LogErrorf 格式化错误日志
func LogErrorf(format string, args ...interface{}) {
	if !shouldLog("ERROR") {
		return
	}
	callerInfo := getCallerInfo()
	message := fmt.Sprintf(format, args...)
	logMessage("ERROR", callerInfo+" "+message)
}

// LogWarnf 格式化警告日志
func LogWarnf(format string, args ...interface{}) {
	if !shouldLog("WARN") {
		return
	}
	callerInfo := getCallerInfo()
	message := fmt.Sprintf(format, args...)
	logMessage("WARN", callerInfo+" "+message)
}

// logMessage 写入日志消息
func logMessage(level, message string) {
	timestamp := time.Now().Format("2006-01-02 15:04:05.000")

	// 控制台输出（仅在开发模式下显示，避免发布版本弹窗）
	if isDevMode {
		log.Printf("[%s] %s %s", timestamp, level, message)
	}
	// 发布模式下不输出到控制台，只写入文件

	// 文件输出（开发模式和发布模式都写入）
	logFile := filepath.Join(logDir, fmt.Sprintf("log%s.log", time.Now().Format("20060102")))
	file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return
	}
	defer file.Close()

	fileTimestamp := time.Now().Format("15:04:05.000")
	file.WriteString(fmt.Sprintf("%s [%s] %s\n", fileTimestamp, level, message))
}
