package utils

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

// LogLevel 日志级别
type LogLevel int

const (
	DEBUG LogLevel = iota
	INFO
	WARN
	ERROR
	FATAL
)

// String 返回日志级别的字符串表示
func (l LogLevel) String() string {
	switch l {
	case DEBUG:
		return "DEBUG"
	case INFO:
		return "INFO"
	case WARN:
		return "WARN"
	case ERROR:
		return "ERROR"
	case FATAL:
		return "FATAL"
	default:
		return "UNKNOWN"
	}
}

// Color 返回日志级别对应的颜色代码
func (l LogLevel) Color() string {
	switch l {
	case DEBUG:
		return "\033[36m" // 青色
	case INFO:
		return "\033[32m" // 绿色
	case WARN:
		return "\033[33m" // 黄色
	case ERROR:
		return "\033[31m" // 红色
	case FATAL:
		return "\033[35m" // 紫色
	default:
		return "\033[0m" // 默认
	}
}

// Logger 统一日志记录器
type Logger struct {
	level       LogLevel
	output      io.Writer
	file        *os.File
	logToFile   bool
	logPath     string
	service     string
	colorOutput bool
}

// LoggerConfig 日志配置
type LoggerConfig struct {
	Level       LogLevel
	LogToFile   bool
	LogPath     string
	ServiceName string
	ColorOutput bool
}

// NewLogger 创建新的日志记录器
func NewLogger(config *LoggerConfig) (*Logger, error) {
	logger := &Logger{
		level:       config.Level,
		service:     config.ServiceName,
		logToFile:   config.LogToFile,
		logPath:     config.LogPath,
		colorOutput: config.ColorOutput,
	}

	// 设置默认输出
	logger.output = os.Stdout

	// 如果需要记录到文件
	if config.LogToFile && config.LogPath != "" {
		// 确保日志目录存在
		logDir := filepath.Dir(config.LogPath)
		if err := os.MkdirAll(logDir, 0755); err != nil {
			return nil, fmt.Errorf("创建日志目录失败: %v", err)
		}

		// 打开日志文件
		file, err := os.OpenFile(config.LogPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
		if err != nil {
			return nil, fmt.Errorf("打开日志文件失败: %v", err)
		}

		logger.file = file
		logger.output = io.MultiWriter(os.Stdout, file)
	}

	return logger, nil
}

// NewDefaultLogger 创建默认日志记录器
func NewDefaultLogger() (*Logger, error) {
	logPath := filepath.Join(os.TempDir(), "cos-index-default.log")
	config := &LoggerConfig{
		Level:       INFO,
		LogToFile:   true,
		LogPath:     logPath,
		ServiceName: "cos-index",
		ColorOutput: true,
	}

	return NewLogger(config)
}

// SetLevel 设置日志级别
func (l *Logger) SetLevel(level LogLevel) {
	l.level = level
}

// SetService 设置服务名称
func (l *Logger) SetService(service string) {
	l.service = service
}

// log 内部日志记录方法
func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
	if level < l.level {
		return
	}

	// 获取调用者信息
	_, file, line, ok := runtime.Caller(2)
	var caller string
	if ok {
		caller = fmt.Sprintf("%s:%d", filepath.Base(file), line)
	} else {
		caller = "unknown"
	}

	// 格式化时间
	timestamp := time.Now().Format("2006-01-02 15:04:05.000")

	// 格式化消息
	message := fmt.Sprintf(format, args...)

	// 构建日志行
	var logLine string
	if l.colorOutput {
		logLine = fmt.Sprintf("%s[%s] %s%s [%s] [%s] %s\033[0m",
			level.Color(), timestamp, level.Color(), level.String(), l.service, caller, message)
	} else {
		logLine = fmt.Sprintf("[%s] %s [%s] [%s] %s",
			timestamp, level.String(), l.service, caller, message)
	}

	// 输出日志
	fmt.Fprintln(l.output, logLine)

	// 如果是致命错误，退出程序
	if level == FATAL {
		l.Close()
		os.Exit(1)
	}
}

// Debug 记录调试信息
func (l *Logger) Debug(format string, args ...interface{}) {
	l.log(DEBUG, format, args...)
}

// Info 记录信息
func (l *Logger) Info(format string, args ...interface{}) {
	l.log(INFO, format, args...)
}

// Warn 记录警告
func (l *Logger) Warn(format string, args ...interface{}) {
	l.log(WARN, format, args...)
}

// Error 记录错误
func (l *Logger) Error(format string, args ...interface{}) {
	l.log(ERROR, format, args...)
}

// Fatal 记录致命错误并退出
func (l *Logger) Fatal(format string, args ...interface{}) {
	l.log(FATAL, format, args...)
}

// Close 关闭日志记录器
func (l *Logger) Close() error {
	if l.file != nil {
		return l.file.Close()
	}
	return nil
}

// WithField 带字段的日志记录
func (l *Logger) WithField(key, value string) *FieldLogger {
	return &FieldLogger{
		logger: l,
		fields: map[string]string{key: value},
	}
}

// WithFields 带多个字段的日志记录
func (l *Logger) WithFields(fields map[string]string) *FieldLogger {
	return &FieldLogger{
		logger: l,
		fields: fields,
	}
}

// FieldLogger 带字段的日志记录器
type FieldLogger struct {
	logger *Logger
	fields map[string]string
}

// formatFields 格式化字段
func (fl *FieldLogger) formatFields() string {
	if len(fl.fields) == 0 {
		return ""
	}

	var parts []string
	for k, v := range fl.fields {
		parts = append(parts, fmt.Sprintf("%s=%s", k, v))
	}
	return fmt.Sprintf(" {%s}", strings.Join(parts, ", "))
}

// Debug 记录调试信息
func (fl *FieldLogger) Debug(format string, args ...interface{}) {
	fld := fl.formatFields()
	if fld != "" {
		fl.logger.log(DEBUG, format+fld, args...)
	} else {
		fl.logger.log(DEBUG, format, args...)
	}
}

// Info 记录信息
func (fl *FieldLogger) Info(format string, args ...interface{}) {
	fld := fl.formatFields()
	if fld != "" {
		fl.logger.log(INFO, format+fld, args...)
	} else {
		fl.logger.log(INFO, format, args...)
	}
}

// Warn 记录警告
func (fl *FieldLogger) Warn(format string, args ...interface{}) {
	fld := fl.formatFields()
	if fld != "" {
		fl.logger.log(WARN, format+fld, args...)
	} else {
		fl.logger.log(WARN, format, args...)
	}
}

// Error 记录错误
func (fl *FieldLogger) Error(format string, args ...interface{}) {
	fld := fl.formatFields()
	if fld != "" {
		fl.logger.log(ERROR, format+fld, args...)
	} else {
		fl.logger.log(ERROR, format, args...)
	}
}

// Fatal 记录致命错误并退出
func (fl *FieldLogger) Fatal(format string, args ...interface{}) {
	fld := fl.formatFields()
	if fld != "" {
		fl.logger.log(FATAL, format+fld, args...)
	} else {
		fl.logger.log(FATAL, format, args...)
	}
}

// 全局日志记录器
var defaultLogger *Logger

// 专用日志记录器
var panelLogger *Logger // 面板操作日志
var indexLogger *Logger // 索引生成日志

// InitDefaultLogger 初始化默认日志记录器
func InitDefaultLogger() error {
	var err error
	defaultLogger, err = NewDefaultLogger()
	if err != nil {
		return err
	}

	// 设置标准库的日志输出到控制台（不写入文件）
	log.SetOutput(os.Stdout)
	log.SetFlags(log.LstdFlags)

	// 初始化专用日志记录器
	if err := initSpecializedLoggers(); err != nil {
		return err
	}

	// 启动自动清理
	go autoCleanOldLogs()

	return nil
}

// initSpecializedLoggers 初始化专用日志记录器
func initSpecializedLoggers() error {
	var err error
	workingDir, _ := os.Getwd()
	if workingDir == "" {
		workingDir = "."
	}

	// 确保logs目录存在
	logDir := filepath.Join(workingDir, "logs")
	if err := os.MkdirAll(logDir, 0755); err != nil {
		return fmt.Errorf("创建日志目录失败: %v", err)
	}

	// 面板操作日志
	panelLogPath := filepath.Join(logDir, "panel.log")
	panelLogger, err = NewLogger(&LoggerConfig{
		Level:       INFO,
		LogToFile:   true,
		LogPath:     panelLogPath,
		ServiceName: "PANEL",
		ColorOutput: false,
	})
	if err != nil {
		return fmt.Errorf("创建面板日志记录器失败: %v", err)
	}

	// 索引生成日志
	indexLogPath := filepath.Join(logDir, "index.log")
	indexLogger, err = NewLogger(&LoggerConfig{
		Level:       INFO,
		LogToFile:   true,
		LogPath:     indexLogPath,
		ServiceName: "INDEX",
		ColorOutput: false,
	})
	if err != nil {
		return fmt.Errorf("创建索引日志记录器失败: %v", err)
	}

	return nil
}

// GetDefaultLogger 获取默认日志记录器
func GetDefaultLogger() *Logger {
	if defaultLogger == nil {
		// 如果没有初始化，创建一个简单的日志记录器
		logger, _ := NewLogger(&LoggerConfig{
			Level:       INFO,
			LogToFile:   false,
			ServiceName: "cos-index",
			ColorOutput: true,
		})
		defaultLogger = logger
	}
	return defaultLogger
}

// SetDefaultLogger 设置默认日志记录器
func SetDefaultLogger(logger *Logger) {
	defaultLogger = logger
}

// 全局日志函数
func Debug(format string, args ...interface{}) {
	GetDefaultLogger().Debug(format, args...)
}

func Info(format string, args ...interface{}) {
	GetDefaultLogger().Info(format, args...)
}

func Warn(format string, args ...interface{}) {
	GetDefaultLogger().Warn(format, args...)
}

func Error(format string, args ...interface{}) {
	GetDefaultLogger().Error(format, args...)
}

func Fatal(format string, args ...interface{}) {
	GetDefaultLogger().Fatal(format, args...)
}

// WithField 创建带字段的全局日志记录器
func WithField(key, value string) *FieldLogger {
	return GetDefaultLogger().WithField(key, value)
}

// WithFields 创建带多个字段的全局日志记录器
func WithFields(fields map[string]string) *FieldLogger {
	return GetDefaultLogger().WithFields(fields)
}

// GetPanelLogger 获取面板操作日志记录器
func GetPanelLogger() *Logger {
	if panelLogger == nil {
		// 如果没有初始化，使用默认日志记录器
		return GetDefaultLogger()
	}
	return panelLogger
}

// GetIndexLogger 获取索引生成日志记录器
func GetIndexLogger() *Logger {
	if indexLogger == nil {
		// 如果没有初始化，使用默认日志记录器
		return GetDefaultLogger()
	}
	return indexLogger
}

// PanelLog 记录面板操作日志
func PanelLog(format string, args ...interface{}) {
	GetPanelLogger().Info(format, args...)
}

// IndexLog 记录索引生成日志
func IndexLog(format string, args ...interface{}) {
	GetIndexLogger().Info(format, args...)
}

// autoCleanOldLogs 自动清理7天前的日志文件
func autoCleanOldLogs() {
	// 每天检查一次
	ticker := time.NewTicker(24 * time.Hour)
	defer ticker.Stop()

	// 程序启动时立即执行一次清理
	cleanOldLogs()

	for {
		select {
		case <-ticker.C:
			cleanOldLogs()
		}
	}
}

// cleanOldLogs 清理7天前的日志文件
func cleanOldLogs() {
	workingDir, _ := os.Getwd()
	if workingDir == "" {
		workingDir = "."
	}

	logDir := filepath.Join(workingDir, "logs")
	if _, err := os.Stat(logDir); os.IsNotExist(err) {
		return // 日志目录不存在，无需清理
	}

	files, err := filepath.Glob(filepath.Join(logDir, "*.log*"))
	if err != nil {
		return // 获取文件列表失败，跳过清理
	}

	cutoff := time.Now().AddDate(0, 0, -7) // 7天前
	cleanedCount := 0

	for _, file := range files {
		if info, err := os.Stat(file); err == nil {
			if info.ModTime().Before(cutoff) {
				if err := os.Remove(file); err == nil {
					cleanedCount++
				}
			}
		}
	}

	if cleanedCount > 0 {
		// 记录清理事件到面板日志
		if panelLogger != nil {
			panelLogger.Info("自动清理了 %d 个超过7天的日志文件", cleanedCount)
		}
	}
}

// CloseSpecializedLoggers 关闭专用日志记录器
func CloseSpecializedLoggers() {
	if panelLogger != nil {
		panelLogger.Close()
		panelLogger = nil
	}
	if indexLogger != nil {
		indexLogger.Close()
		indexLogger = nil
	}
}
