package bootstrap

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/break/junhong_cmp_fiber/pkg/config"
	"go.uber.org/zap"
)

type DirectoryResult struct {
	TempDir      string
	AppLogDir    string
	AccessLogDir string
	Fallbacks    []string
}

func EnsureDirectories(cfg *config.Config, logger *zap.Logger) (*DirectoryResult, error) {
	result := &DirectoryResult{}

	directories := []struct {
		path      string
		configKey string
		resultPtr *string
	}{
		{cfg.Storage.TempDir, "storage.temp_dir", &result.TempDir},
		{filepath.Dir(cfg.Logging.AppLog.Filename), "logging.app_log.filename", &result.AppLogDir},
		{filepath.Dir(cfg.Logging.AccessLog.Filename), "logging.access_log.filename", &result.AccessLogDir},
	}

	for _, dir := range directories {
		if dir.path == "" || dir.path == "." {
			continue
		}

		actualPath, fallback, err := ensureDirectory(dir.path, logger)
		if err != nil {
			return nil, fmt.Errorf("创建目录 %s (%s) 失败: %w", dir.path, dir.configKey, err)
		}

		*dir.resultPtr = actualPath
		if fallback {
			result.Fallbacks = append(result.Fallbacks, actualPath)
		}
	}

	return result, nil
}

func ensureDirectory(path string, logger *zap.Logger) (actualPath string, fallback bool, err error) {
	if err := os.MkdirAll(path, 0755); err != nil {
		if os.IsPermission(err) {
			fallbackPath := filepath.Join(os.TempDir(), "junhong", filepath.Base(path))
			if mkErr := os.MkdirAll(fallbackPath, 0755); mkErr != nil {
				return "", false, fmt.Errorf("原路径 %s 权限不足，降级路径 %s 也创建失败: %w", path, fallbackPath, mkErr)
			}
			if logger != nil {
				logger.Warn("目录权限不足，使用降级路径",
					zap.String("original", path),
					zap.String("fallback", fallbackPath),
				)
			}
			return fallbackPath, true, nil
		}
		return "", false, err
	}
	return path, false, nil
}
