// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

// GSettingsShortcut 处理基于GSettings的快捷键配置
// 负责快捷键的保存、加载和同步
package shortcuts

import (
	wm "github.com/linuxdeepin/go-dbus-factory/com.deepin.wm"
	"github.com/linuxdeepin/go-gir/gio-2.0"
)

// GSettingsShortcut 表示基于GSettings的快捷键
// 封装了GSettings配置的快捷键操作
type GSettingsShortcut struct {
	BaseShortcut
	gsettings *gio.Settings // GSettings配置对象，用于读写快捷键配置
	wm        wm.Wm         // 窗口管理器DBus接口，用于Wayland环境下的快捷键设置
}

// NewGSettingsShortcut 创建新的GSettingsShortcut实例
// 参数:
//   gsettings - GSettings配置对象
//   wm - 窗口管理器DBus接口
//   id - 快捷键唯一标识符
//   type0 - 快捷键类型（系统/媒体/自定义等）
//   keystrokes - 按键字符串列表（如["<Control>c", "<Control>v"]）
//   name - 快捷键显示名称
// 返回值: 初始化完成的GSettingsShortcut实例
func NewGSettingsShortcut(gsettings *gio.Settings, wm wm.Wm, id string, type0 int32,
	keystrokes []string, name string) *GSettingsShortcut {
	gs := &GSettingsShortcut{
		BaseShortcut: BaseShortcut{
			Id:         id,
			Type:       type0,
			Keystrokes: ParseKeystrokes(keystrokes), // 解析按键字符串为Keystroke对象
			Name:       name,
		},
		gsettings: gsettings,
		wm:        wm,
	}

	return gs
}

// SaveKeystrokes 保存当前快捷键配置到GSettings
// 将Keystroke对象列表转换为字符串格式并写入GSettings
// 返回值: 保存操作可能返回的错误
func (gs *GSettingsShortcut) SaveKeystrokes() error {
	// 将Keystroke对象转换为字符串列表
	keystrokesStrv := make([]string, 0, len(gs.Keystrokes))
	for _, ks := range gs.Keystrokes {
		keystrokesStrv = append(keystrokesStrv, ks.String())
	}

	// 写入GSettings配置
	gs.gsettings.SetStrv(gs.Id, keystrokesStrv)
	gio.SettingsSync() // 同步配置更改

	// Wayland环境下需要额外设置KWin快捷键
	if _useWayland {
		ok, err := SetShortForWayland(gs, gs.wm)
		if !ok {
			return err
		}
	}
	logger.Debugf("GSettingsShortcut.SaveKeystrokes id: %v, keystrokes: %v", gs.Id, keystrokesStrv)
	return nil
}

// keystrokesEqual 比较两个按键序列是否相同
// 参数:
//   s1 - 第一个按键序列
//   s2 - 第二个按键序列
// 返回值: 如果两个序列完全相同返回true，否则返回false
func keystrokesEqual(s1 []*Keystroke, s2 []*Keystroke) bool {
	// 检查长度是否相同
	if len(s1) != len(s2) {
		return false
	}

	// 逐个比较按键字符串
	for i := range s1 {
		if s1[i].String() != s2[i].String() {
			return false
		}
	}
	return true
}

// ReloadKeystrokes 从GSettings重新加载快捷键配置
// 返回值: 如果配置发生变化返回true，否则返回false
func (gs *GSettingsShortcut) ReloadKeystrokes() bool {
	oldVal := gs.GetKeystrokes() // 获取当前按键配置
	id := gs.GetId()

	// 从GSettings读取新配置并解析
	newVal := ParseKeystrokes(gs.gsettings.GetStrv(id))

	// 更新快捷键配置
	gs.setKeystrokes(newVal)

	// 返回配置是否变化
	return !keystrokesEqual(oldVal, newVal)
}