package env

import (
	"fmt"
	"log/slog"
	"net"
	"os"
	"strconv"
	"strings"

	"github.com/joho/godotenv"
)

var (
	RunMode = "dev" // 运行模式，dev: 开发模式，prod: 生产模式

	AppCtrlPort      uint16 = 18080
	AppDataPort      uint16 = 18081
	AppWebPort       uint16 = 8848
	AppLogMode              = "dev"
	AppExitTimeout          = 5  // 等待服务停止的超时时间
	AppDataTimeout          = 20 // 等待数据通道连接的超时时间
	AppUserRWTimeout        = 10 // 等待用户连接读写超时时间
	AppDataRWTimeout        = 10 // 等待数据通道读写超时时间
	AppCtrlRWTimeout        = 10 // 等待控制通道读写超时时间
	AppCtrlHBTimeout        = 30 // 控制通道心跳超时时间（断开连接等待时间为：心跳等待时间 * 2 + 读写等待时间）

	AuthWhitelist []net.IP // 全局白名单，可以将白名单 IP 视为一个可信任代理

	ClientId     string
	ClientSecret string

	RedisHost = "localhost"
	RedisPort = "6379"
	RedisDb   = 0
	RedisPass = ""

	EndpointOnline  string
	EndpointOffline string
	EndpointUpdate  string
)

func Init() {
	var err = godotenv.Load()
	if err != nil {
		slog.Debug("没有本地环境变量文件")
	}
	var value string

	value = os.Getenv("RUN_MODE")
	switch value {
	case "dev", "prod":
		RunMode = value
	case "":
	default:
		panic(fmt.Sprintf("环境变量 RUN_MODE 格式错误: %s", value))
	}

	value = os.Getenv("APP_CTRL_PORT")
	if value != "" {
		appCtrlPort, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_CTRL_PORT 格式错误: %v", err))
		}
		AppCtrlPort = uint16(appCtrlPort)
	}

	value = os.Getenv("APP_DATA_PORT")
	if value != "" {
		appDataPort, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_DATA_PORT 格式错误: %v", err))
		}
		AppDataPort = uint16(appDataPort)
	}

	value = os.Getenv("APP_WEB_PORT")
	if value != "" {
		appWebPort, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_WEB_PORT 格式错误: %v", err))
		}
		AppWebPort = uint16(appWebPort)
	}

	value = os.Getenv("APP_LOG_MODE")
	if value != "" {
		AppLogMode = value
	}

	value = os.Getenv("APP_EXIT_TIMEOUT")
	if value != "" {
		appExitTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_EXIT_TIMEOUT 格式错误: %v", err))
		}
		AppExitTimeout = appExitTimeout
	}

	value = os.Getenv("APP_DATA_TIMEOUT")
	if value != "" {
		appDataTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_DATA_TIMEOUT 格式错误: %v", err))
		}
		AppDataTimeout = appDataTimeout
	}

	value = os.Getenv("APP_USER_RW_TIMEOUT")
	if value != "" {
		appUserTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_USER_RW_TIMEOUT 格式错误: %v", err))
		}
		AppUserRWTimeout = appUserTimeout
	}

	value = os.Getenv("APP_DATA_RW_TIMEOUT")
	if value != "" {
		appDataRWTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_DATA_RW_TIMEOUT 格式错误: %v", err))
		}
		AppDataRWTimeout = appDataRWTimeout
	}

	value = os.Getenv("APP_CTRL_RW_TIMEOUT")
	if value != "" {
		appCtrlRWTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_CTRL_RW_TIMEOUT 格式错误: %v", err))
		}
		AppCtrlRWTimeout = appCtrlRWTimeout
	}

	value = os.Getenv("APP_CTRL_HB_TIMEOUT")
	if value != "" {
		appCtrlHBTimeout, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 APP_CTRL_HB_TIMEOUT 格式错误: %v", err))
		}
		AppCtrlHBTimeout = appCtrlHBTimeout
	}

	value = os.Getenv("AUTH_WHITELIST")
	if value != "" {
		ips := strings.Split(value, ",")
		for _, ip := range ips {
			ip = strings.TrimSpace(ip)
			if ip == "" {
				continue
			}
			parsedIP := net.ParseIP(ip)
			if parsedIP == nil {
				panic(fmt.Sprintf("环境变量 AUTH_WHITELIST 格式错误: %s", ip))
			}
			AuthWhitelist = append(AuthWhitelist, parsedIP)
		}
	}

	value = os.Getenv("CLIENT_ID")
	if value != "" {
		ClientId = value
	} else {
		panic("环境变量 CLIENT_ID 未设置")
	}

	value = os.Getenv("CLIENT_SECRET")
	if value != "" {
		ClientSecret = value
	} else {
		panic("环境变量 CLIENT_SECRET 未设置")
	}

	value = os.Getenv("REDIS_HOST")
	if value != "" {
		RedisHost = value
	}

	value = os.Getenv("REDIS_PORT")
	if value != "" {
		RedisPort = value
	}

	value = os.Getenv("REDIS_DB")
	if value != "" {
		redisDb, err := strconv.Atoi(value)
		if err != nil {
			panic(fmt.Sprintf("环境变量 REDIS_DB 格式错误: %v", err))
		}
		RedisDb = redisDb
	}

	value = os.Getenv("REDIS_PASS")
	if value != "" {
		RedisPass = value
	}

	value = os.Getenv("ENDPOINT_ONLINE")
	if value != "" {
		EndpointOnline = value
	} else {
		panic("环境变量 ENDPOINT_ONLINE 未设置")
	}

	value = os.Getenv("ENDPOINT_OFFLINE")
	if value != "" {
		EndpointOffline = value
	} else {
		panic("环境变量 ENDPOINT_OFFLINE 未设置")
	}

	value = os.Getenv("ENDPOINT_UPDATE")
	if value != "" {
		EndpointUpdate = value
	} else {
		panic("环境变量 ENDPOINT_UPDATE 未设置")
	}
}
