package main

import (
	"WM_CMS_SERVER/config"
	"WM_CMS_SERVER/mongodb"
	"WM_CMS_SERVER/util"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"
)

var (
	// currentLogFile *os.File
	logMutex sync.Mutex
)

func UpdateProductRoutine() {
	log.Println("Update Product Goroutine Started.")
	for {
		now := time.Now()
		// 檢查是否為工作日（週一至週五）
		if now.Weekday() >= time.Monday && now.Weekday() <= time.Friday {
			hour := now.Hour()
			minute := now.Minute()
			// 檢查是否在工作時間內（8:30-18:30）且為指定分鐘數
			if hour >= 8 && hour <= 18 && (minute == 1 || minute == 31) {
				log.Printf("開始執行更新，當前時間: %v", now.Format("2006-01-02 15:04:05"))
				UpdateAllProduct()
				log.Println("更新完成")
				time.Sleep(60 * time.Second)
				continue
			}
		}
		time.Sleep(1 * time.Minute)
	}
}

func UpdateSSOACInfoLogRoutine() {
	log.Println("Update HRISDB Goroutine Started.")
	for {
		now := time.Now()
		// 檢查是否為週一至週五
		// if now.Weekday() >= time.Monday && now.Weekday() <= time.Friday {
		// 檢查是否在早上8:10
		if now.Hour() == 8 && now.Minute() == 10 {
			ssoACInfoList, err := mongodb.CheckHRISDBData()
			if err != nil {
				log.Printf("UpdateHRISDBDataRoutine fail - %v\n", err)
			} else {
				fileName := time.Now().Format("2006-01-02") + "_" + config.SSO_AC_INFO_LOG_FILE
				for _, ssoACInfo := range ssoACInfoList {
					// log.Printf("使用者 %s (%s) 已被停用", ssoACInfo.Username, ssoACInfo.DisplayName)
					ssoACInfoLog := &util.SSOACInfoLog{
						AppDate: time.Now().Format("20060102"),
						AppID:   config.APP_ID,
						// CompID:         ssoACInfo.CompID,
						// CompName:       ssoACInfo.CompName,
						CompID:         "SPHBK1",
						CompName:       "永豐銀行",
						DeptID:         ssoACInfo.BrID,
						DeptName:       ssoACInfo.BrName,
						EmpID:          ssoACInfo.Username,
						EmpName:        ssoACInfo.DisplayName,
						FunID:          "User",
						FunName:        "使用者管理",
						GrantType:      "系統授權",
						GrantDesc:      "",
						WorkStatus:     ssoACInfo.WorkStatus,
						WorkStatusDesc: ssoACInfo.WorkStatusDesc,
						GrantUserID:    "SYSTEM",
						GrantUserName:  "SYSTEM",
						Remark:         "",
					}
					util.WriteSSOACInfoLog(fileName, ssoACInfoLog)
				}
				util.UpdateSSOACInfoLog()
			}
			time.Sleep(60 * time.Second) // 執行後休息一分鐘，避免重複執行
			continue
		}
		// }

		time.Sleep(1 * time.Minute)
	}
}

func UpdateSSOAPLoginLogRoutine() {
	log.Println("Update SSOAPLoginLog Goroutine Started.")
	for {
		now := time.Now()
		if now.Hour() == 3 {
			util.UpdateSSOAPLoginLog()
			time.Sleep(1 * time.Hour) // 執行後休息一小時，避免重複執行
			continue
		}
		time.Sleep(1 * time.Hour) // 每60分鐘檢查一次
	}
}

func UpdateSSOAPLogControlRoutine() {
	log.Println("Update UpdateSSOAPLogControl Goroutine Started.")
	for {
		now := time.Now()
		if now.Hour() == 4 && now.Minute() == 10 {
			util.UpdateSSOAPLogControl()
			time.Sleep(60 * time.Second) // 執行後休息一分鐘，避免重複執行
			continue
		}
		time.Sleep(1 * time.Minute)
	}
}

func ChangeLogFile() {
	setLogFile()
	ticker := time.NewTicker(time.Minute)
	defer ticker.Stop()
	for range ticker.C {
		// 檢查是否需要切換日誌文件
		// fmt.Println("檢查是否需要切換Log檔")
		setLogFile()
	}
}

func setLogFile() {
	logMutex.Lock()
	defer logMutex.Unlock()

	now := time.Now()
	logFileName := fmt.Sprintf("%s_WM_CMS_SERVER_LOG.log", now.Format("2006-01-02"))
	logDir := "../logs"
	logPath := filepath.Join(logDir, logFileName)

	// 如果當前文件已經打開且路徑相同，則直接返回
	if currentLogFile != nil {
		if filepath.Clean(currentLogFile.Name()) == filepath.Clean(logPath) {
			return
		}
	}

	// 創建 logs 目錄
	if err := os.MkdirAll(logDir, 0755); err != nil {
		log.Printf("[setLogFile] 創建日誌目錄失敗: %v", err)
		return
	}

	// 打開日誌文件
	file, err := os.OpenFile(
		logPath,
		os.O_CREATE|os.O_WRONLY|os.O_APPEND,
		0666,
	)
	if err != nil {
		log.Printf("[setLogFile] 打開日誌文件失敗: %v", err)
		return
	}

	// 創建多重輸出
	multiWriter := io.MultiWriter(file, os.Stdout)

	// 如果之前有開啟的檔案，確保安全關閉
	if currentLogFile != nil {
		if err := currentLogFile.Close(); err != nil {
			fmt.Fprintf(os.Stderr, "[setLogFile] 關閉舊日誌文件時發生錯誤: %v\n", err)
		}
	}

	// 更新當前檔案指標
	currentLogFile = file

	// 設置使用多重輸出
	log.SetOutput(multiWriter)

	log.Printf("Log檔設定至: %s", logPath)

	// 清理兩個月前的日誌檔案
	cleanOldLogs(logDir)
}

// 新增清理舊日誌的函數
func cleanOldLogs(logDir string) {
	// 計算兩個月前的時間
	twoMonthsAgo := time.Now().AddDate(0, -1, 0)

	// 讀取日誌目錄
	entries, err := os.ReadDir(logDir)
	if err != nil {
		log.Printf("[cleanOldLogs] 讀取日誌目錄失敗: %v", err)
		return
	}

	// 遍歷所有檔案
	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}

		// 檢查檔案名稱是否符合格式 "2006-01-02_WM_CMS_SERVER_LOG.log"
		fileName := entry.Name()
		if len(fileName) < 10 {
			continue
		}

		// 解析檔案名稱中的日期
		dateStr := fileName[:10] // 取得 "2006-01-02" 部分
		fileTime, err := time.Parse("2006-01-02", dateStr)
		if err != nil {
			continue
		}

		// 如果檔案日期在兩個月前，則刪除
		if fileTime.Before(twoMonthsAgo) {
			filePath := filepath.Join(logDir, fileName)
			if err := os.Remove(filePath); err != nil {
				log.Printf("[cleanOldLogs] 刪除舊日誌檔案失敗 %s: %v", fileName, err)
			} else {
				log.Printf("[cleanOldLogs] 已刪除舊日誌檔案: %s", fileName)
			}
		}
	}
}
