package router

import (
	"ARKItems/configs"
	"archive/zip"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

var (
	BackupFileList = make([]string, 0)
	// ServerConfigUrls 实际服务器目录，商店插件配置文件位置
	ServerConfigUrls = make([]string, 0)
)

func init() {
	ReadBackupFileList()
}
func ARKFileRouter(api *gin.RouterGroup) {
	//安装插件
	api.GET("/installPlugin", InstallArkApiZip)
	//保存配置到配置文件
	api.GET("/saveConfig", WriteFileConfig)
	//更新实际配置文件内容
	api.GET("/updateServerShopApiConfig", UpdateServerShopApiConfig)
}
func UpdateServerShopApiConfig(c *gin.Context) {
	marshal, err := json.Marshal(ARKConfig)
	if err != nil {
		fmt.Println(err)
		c.JSON(200, CreateResultError(500, "配置文件读取失败"))
	}
	for i := range ServerConfigUrls {
		ioutil.WriteFile(ServerConfigUrls[i], marshal, 0644)
	}
	//TODO 可能需要调用rcon功能，更新配置

	c.JSON(200, CreateResult())
}

// InstallArkApiZip 安装ArkApi
func InstallArkApiZip(c *gin.Context) {
	value := c.Query("compulsion")
	//TODO 是否将最新的商店文件写入配置中
	//writeNow := c.Query("writeNow")
	//是否强制安装
	compulsion := value == "true"

	urls := ReadArkBackupUrl(configs.ArkApiInstallUrl)
	var signal = make(chan int)
	for _, url := range urls {
		ServerConfigUrls = append(ServerConfigUrls, url+"/Plugins/ArkShop/config.json")
		go InstallZip(compulsion, url, signal)
	}
	for s := <-signal; s != len(urls); {
		time.Sleep(1 * time.Millisecond)
	}
	c.JSON(200, CreateResult())
}

// WriteFileConfig 备份实体的配置文件
func WriteFileConfig(c *gin.Context) {
	err := BackupFile()
	if err != nil {
		fmt.Println(err)
		c.JSON(200, CreateResultError(500, "备份失败"))
	}
	//修改目标文件
	marshal, err := json.Marshal(ARKConfig)
	if err != nil {
		fmt.Println(err)
		c.JSON(200, CreateResultError(500, "写入失败"))
	}
	err = os.WriteFile(configs.ARKJsonFilePath, marshal, 0644)

}

// ReadBackupFileList 读取备份文件列表
func ReadBackupFileList() {
	entities, err := os.ReadDir(configs.ARKBackupDir)
	if err != nil {
		fmt.Println(err)
	}
	//获取备份文件位置
	for i := range entities {
		BackupFileList = append(BackupFileList, configs.ARKBackupDir+"/"+entities[i].Name())
	}
	//获取实际的插件配置位置
	urls := ReadArkBackupUrl(configs.ArkApiInstallUrl)
	for _, url := range urls {
		ServerConfigUrls = append(ServerConfigUrls, url+"/Plugins/ArkShop/config.json")
	}
}
func BackupFile() error {
	//穿件备份文件夹
	os.MkdirAll(configs.ARKBackupDir, 0755)
	name := ""
	//创建备份文件
	split := strings.Split(configs.ARKJsonFilePath, "/")
	split = strings.Split(split[len(split)-1], ".")
	name = split[0] + "-" + time.Now().Format("20060102150405")
	for i := 1; i < len(split); i++ {
		name += "." + split[i]
	}
	return CopyFile(configs.ARKJsonFilePath, configs.ARKBackupDir+"/"+name)
}

// CopyFile 复制文件
func CopyFile(src, dest string) error {
	// 打开源文件
	sourceFile, err := os.Open(src)
	if err != nil {
		return err
	}
	defer sourceFile.Close()
	// 创建目标文件
	split := strings.Split(dest, "/")
	str := ""
	for i := 0; i < len(split)-1; i++ {
		str += split[i] + "/"
		err := os.MkdirAll(str, 0755)
		if err != nil {
			fmt.Println(err)
		}
	}
	destinationFile, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer destinationFile.Close()

	// 复制文件内容
	_, err = io.Copy(destinationFile, sourceFile)
	if err != nil {
		return err
	}
	// 确保数据写入目标文件
	err = destinationFile.Sync()
	if err != nil {
		return err
	}

	return nil
}

// InstallZip 安装服务器插件
func InstallZip(compulsion bool, url string, signal chan int) {
	entries, err := os.ReadDir(url)
	if err != nil {
		fmt.Println(err)
	}
	if !compulsion {
		for i := range entries {
			if entries[i].IsDir() && entries[i].Name() == "ArkApi" {
				signal <- i + 1
				return
			}
		}
	} else {
		for i := range entries {
			if entries[i].IsDir() && entries[i].Name() == "ArkApi" {
				//删除
				os.RemoveAll(url + "/ArkApi")
				break
			}
		}
	}

	err = Unzip(configs.ARKAPiZipPath, url)
	i := <-signal
	signal <- i + 1
}

// ReadArkBackupUrl 读取服务器路径的实际位置
func ReadArkBackupUrl(dir string) []string {
	resourcesDir := make([]string, 0)
	// 读取目录内容
	entries, err := os.ReadDir(dir)
	if err != nil {
		fmt.Println(err)
		return resourcesDir
	}
	// 遍历目录内容
	for _, entry := range entries {
		if entry.IsDir() {
			readDir, err := os.ReadDir(entry.Name())
			if err != nil {
				fmt.Println(err)
				return resourcesDir
			}
			existEngineDir := false
			existShooterGameDir := false
			existSteamapps := false

			for _, subentry := range readDir {
				if subentry.IsDir() && subentry.Name() == "Engine" {
					existEngineDir = true
				}
				if subentry.IsDir() && subentry.Name() == "ShooterGame" {
					existShooterGameDir = true
				}
				if subentry.IsDir() && subentry.Name() == "steamapps" {
					existSteamapps = true
				}
			}
			if existEngineDir && existShooterGameDir && existSteamapps {
				resourcesDir = append(resourcesDir, dir+"/"+entry.Name()+"/ShooterGame/Binaries/Win64")
			}
		}
	}
	return resourcesDir
}

// Unzip 解压缩ZIP文件到目标路径
func Unzip(src, dest string) error {
	// 打开ZIP文件
	reader, err := zip.OpenReader(src)
	if err != nil {
		return err
	}
	defer reader.Close()

	// 创建目标路径
	if err := os.MkdirAll(dest, 0755); err != nil {
		return err
	}

	// 解压每个文件
	for _, file := range reader.File {
		filePath := filepath.Join(dest, file.Name)

		// 检查文件的目录结构
		if !strings.HasPrefix(filePath, filepath.Clean(dest)+string(os.PathSeparator)) {
			return fmt.Errorf("非法文件路径: %s", filePath)
		}

		if file.FileInfo().IsDir() {
			// 创建目录
			if err := os.MkdirAll(filePath, file.Mode()); err != nil {
				return err
			}
		} else {
			// 创建文件所在的目录
			if err := os.MkdirAll(filepath.Dir(filePath), file.Mode()); err != nil {
				return err
			}

			// 打开ZIP中的文件
			zipFile, err := file.Open()
			if err != nil {
				return err
			}
			defer zipFile.Close()

			// 创建输出文件
			outputFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
			if err != nil {
				return err
			}
			defer outputFile.Close()

			// 将内容拷贝到输出文件
			_, err = io.Copy(outputFile, zipFile)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
