package services

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
)

// FileService 文件服务
type FileService struct{}

// NewFileService 创建文件服务实例
func NewFileService() *FileService {
	return &FileService{}
}

// SelectFolder 选择文件夹（返回路径）
func (s *FileService) SelectFolder(ctx context.Context) (string, error) {
	LogDebug("开始选择文件夹...")
	
	// 根据操作系统使用不同的方法
	switch runtime.GOOS {
	case "darwin": // macOS
		return s.selectFolderMacOS()
	case "windows":
		return s.selectFolderWindows()
	case "linux":
		return s.selectFolderLinux()
	default:
		return "", fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
	}
}

// selectFolderMacOS 在 macOS 上选择文件夹
func (s *FileService) selectFolderMacOS() (string, error) {
	// 使用 AppleScript 打开文件夹选择对话框
	script := `tell application "System Events"
	activate
	set folderPath to choose folder with prompt "请选择文件夹"
	return POSIX path of folderPath
end tell`
	
	cmd := exec.Command("osascript", "-e", script)
	output, err := cmd.Output()
	if err != nil {
		LogErrorf("选择文件夹失败: %v", err)
		return "", fmt.Errorf("选择文件夹失败: %v", err)
	}
	
	path := strings.TrimSpace(string(output))
	LogInfof("选择的文件夹路径: %s", path)
	return path, nil
}

// selectFolderWindows 在 Windows 上选择文件夹
func (s *FileService) selectFolderWindows() (string, error) {
	// 使用 PowerShell 打开文件夹选择对话框
	script := `Add-Type -AssemblyName System.Windows.Forms
$folderBrowser = New-Object System.Windows.Forms.FolderBrowserDialog
$folderBrowser.Description = "请选择文件夹"
$result = $folderBrowser.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    Write-Output $folderBrowser.SelectedPath
}`
	
	cmd := exec.Command("powershell", "-Command", script)
	output, err := cmd.Output()
	if err != nil {
		LogErrorf("选择文件夹失败: %v", err)
		return "", fmt.Errorf("选择文件夹失败: %v", err)
	}
	
	path := strings.TrimSpace(string(output))
	LogInfof("选择的文件夹路径: %s", path)
	return path, nil
}

// selectFolderLinux 在 Linux 上选择文件夹
func (s *FileService) selectFolderLinux() (string, error) {
	// 使用 zenity 或 kdialog 打开文件夹选择对话框
	var cmd *exec.Cmd
	
	// 先尝试使用 zenity
	if _, err := exec.LookPath("zenity"); err == nil {
		cmd = exec.Command("zenity", "--file-selection", "--directory", "--title=请选择文件夹")
	} else if _, err := exec.LookPath("kdialog"); err == nil {
		cmd = exec.Command("kdialog", "--getexistingdirectory", "$HOME", "--title", "请选择文件夹")
	} else {
		return "", fmt.Errorf("未找到 zenity 或 kdialog，无法打开文件夹选择对话框")
	}
	
	output, err := cmd.Output()
	if err != nil {
		LogErrorf("选择文件夹失败: %v", err)
		return "", fmt.Errorf("选择文件夹失败: %v", err)
	}
	
	path := strings.TrimSpace(string(output))
	LogInfof("选择的文件夹路径: %s", path)
	return path, nil
}

// SelectFile 选择文件（返回路径）
func (s *FileService) SelectFile(ctx context.Context, filter string) (string, error) {
	// 在 Wails3 中，文件选择需要通过前端实现
	return "", nil
}

// OpenFolder 打开文件夹
func (s *FileService) OpenFolder(ctx context.Context, folderPath string) error {
	LogDebugf("打开文件夹: %s", folderPath)
	
	// 检查文件夹是否存在
	if _, err := os.Stat(folderPath); os.IsNotExist(err) {
		return fmt.Errorf("文件夹不存在: %s", folderPath)
	}
	
	// 根据操作系统使用不同的命令
	var cmd *exec.Cmd
	switch runtime.GOOS {
	case "darwin": // macOS
		cmd = exec.Command("open", folderPath)
	case "windows":
		cmd = exec.Command("explorer", folderPath)
	case "linux":
		cmd = exec.Command("xdg-open", folderPath)
	default:
		return fmt.Errorf("不支持的操作系统: %s", runtime.GOOS)
	}
	
	err := cmd.Run()
	if err != nil {
		LogErrorf("打开文件夹失败: %v", err)
		return fmt.Errorf("打开文件夹失败: %v", err)
	}
	
	LogInfo("文件夹已打开")
	return nil
}

// FileExists 检查文件是否存在
func (s *FileService) FileExists(ctx context.Context, filePath string) (bool, error) {
	_, err := os.Stat(filePath)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// GetFileSize 获取文件大小（字节）
func (s *FileService) GetFileSize(ctx context.Context, filePath string) (int64, error) {
	info, err := os.Stat(filePath)
	if err != nil {
		return 0, err
	}
	return info.Size(), nil
}

// EnsureDirectory 确保目录存在
func (s *FileService) EnsureDirectory(ctx context.Context, dirPath string) error {
	return os.MkdirAll(dirPath, 0755)
}

// ListFiles 列出目录中的文件
func (s *FileService) ListFiles(ctx context.Context, dirPath string, pattern string) ([]string, error) {
	patternPath := filepath.Join(dirPath, pattern)
	matches, err := filepath.Glob(patternPath)
	if err != nil {
		return nil, err
	}
	return matches, nil
}

