#!/usr/bin/env bash
# ────────────────────────────────────────────────────────────────────────
#  eyecolor —— GNOME Terminal 护眼配色一键切换
#
#  用法(不用装,直接跑):
#     bash eyecolor-setup.sh            列出 9 款配色,小样就是它真实的底色/字色
#     bash eyecolor-setup.sh 7          套用 7 号(开着的窗口立刻变,不用重开)
#     bash eyecolor-setup.sh 0          还原成你自己原来的配色
#     bash eyecolor-setup.sh install    装成 eyecolor 命令,以后直接敲 eyecolor
#
#  它只改 GNOME Terminal 的颜色(背景/前景/光标/选中/16 色调色板),
#  不动字体、不动窗口大小、不装任何东西。第一次套用前会自动把你原来的
#  配色备份到 ~/.config/eyecolor-original.dconf,`0` 就是从那里还原。
#
#  ★ 一个容易被忽略的细节:调色板的 color7 必须是浅暖色。
#    很多终端程序(比如 Claude Code 的输入框)拿 color7 当底色,
#    把它压深会在浅色主题里出现一条突兀的灰带。下面几款都已经处理好。
# ────────────────────────────────────────────────────────────────────────
set -u

ORIG="${XDG_CONFIG_HOME:-$HOME/.config}/eyecolor-original.dconf"
PROFDIR="/org/gnome/terminal/legacy/profiles:/"

# ── 用 root 跑时自动切回桌面用户(配色存在桌面用户的 dconf 库里)────────
# 不切的话 dconf 会去读 root 的空库,命令会静默不生效。
if [ "$(id -u)" = 0 ] && [ -z "${EYECOLOR_REEXEC:-}" ]; then
  du=$(ps -o user= -C gnome-shell 2>/dev/null | head -1)
  [ -n "${du:-}" ] || du=$(ps -o user= -C gnome-session-binary 2>/dev/null | head -1)
  if [ -n "${du:-}" ] && [ "$du" != root ]; then
    duid=$(id -u "$du"); dhome=$(getent passwd "$du" | cut -d: -f6)
    exec sudo -u "$du" env EYECOLOR_REEXEC=1 HOME="$dhome" USER="$du" LOGNAME="$du" \
      XDG_RUNTIME_DIR="/run/user/$duid" \
      DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$duid/bus" \
      bash "$0" "$@"
  fi
fi

# ── 环境自检 ────────────────────────────────────────────────────────────
for c in dconf gsettings; do
  command -v $c >/dev/null || { echo "缺少 $c 命令。Ubuntu/Debian: sudo apt install dconf-cli libglib2.0-bin" >&2; exit 1; }
done
if ! gsettings list-schemas 2>/dev/null | grep -q '^org.gnome.Terminal.ProfilesList$'; then
  echo "这台机器上没有 GNOME Terminal(Ubuntu 默认那个终端)。" >&2
  echo "kitty / konsole / Alacritty / GNOME Console(kgx)等请另配,这个脚本管不了。" >&2
  exit 1
fi

# ── 配色 ────────────────────────────────────────────────────────────────
# 浅底通用调色板:1~6/9~14 压深(浅底上看得清),color7/15 保持浅暖(见开头说明)
pal_light="#3B3B36:#B02A26:#2F6B2A:#9A6B00:#2060B0:#8A3FA0:#0F7580:#E9DFB6:#6B6A63:#D03A2E:#3E8C36:#B58900:#2C7BD0:#A65BBE:#17909E:#FFFBEA"
# 仿古深墨:偏柔和,配奶油/灰绿底很稳
pal_ink="#45433D:#B74D4D:#567A3D:#9A6918:#426D96:#885D89:#3E7875:#E9DFB6:#76736A:#C76060:#6E9452:#B7832D:#5A83AA:#A175A0:#59918C:#FFFBEA"

name_0="还原 —— 回到你自己原来的配色"
bg_0="#FAF9DE"; fg_0="#3B3B36"

name_1="杏仁黄    黄味清淡,久看不累   ★"
bg_1="#FAF9DE"; fg_1="#3B3B36"; cur_1="#A15C00"; selbg_1="#E4E0B8"; selfg_1="#2A2A26"; pal_1="$pal_light"

name_2="Solarized 米黄    老牌久坐配色,对比度最讲究"
bg_2="#FDF6E3"; fg_2="#586E75"; cur_2="#B58900"; selbg_2="#EEE8D5"; selfg_2="#073642"
pal_2="#073642:#DC322F:#859900:#B58900:#268BD2:#D33682:#2AA198:#EEE8D5:#002B36:#CB4B16:#586E75:#657B83:#839496:#6C71C4:#93A1A1:#FDF6E3"

name_3="秋叶褐    偏橙,暖光房间/晚上"
bg_3="#FFF2E2"; fg_3="#4A3F35"; cur_3="#B45309"; selbg_3="#F0DEC6"; selfg_3="#3A312A"; pal_3="$pal_light"

name_4="羊皮纸    更深的米黄,白天强光下不反白"
bg_4="#EFE7CF"; fg_4="#3A352B"; cur_4="#8A6D1F"; selbg_4="#DCD0AE"; selfg_4="#2A261F"; pal_4="$pal_light"

name_5="暖夜黄    深底暖黄字,夜里低蓝光"
bg_5="#23201B"; fg_5="#E6D3A3"; cur_5="#F0C674"; selbg_5="#4A4133"; selfg_5="#F5EAD0"
pal_5="#2B2721:#CC6666:#B5BD68:#F0C674:#81A2BE:#B294BB:#8ABEB7:#D6CBB0:#5A5145:#D98A8A:#C8D08A:#F5D98F:#9BB8D3:#C4A9CB:#A3D0C9:#F2EAD5"

name_6="暖灰纸    近白偏灰,最素净"
bg_6="#F0EEE5"; fg_6="#403C34"; cur_6="#C47A28"; selbg_6="#E9D88D"; selfg_6="#2F2B25"; pal_6="$pal_ink"

name_7="灰绿雾    极淡的灰绿,最耐看   ★"
bg_7="#EAEFE9"; fg_7="#3A403A"; cur_7="#4E7A63"; selbg_7="#CBDCCF"; selfg_7="#26302A"; pal_7="$pal_ink"

name_8="奶油鹅黄  黄味最重"
bg_8="#FFF4C2"; fg_8="#403C34"; cur_8="#C47A28"; selbg_8="#E9D88D"; selfg_8="#2F2B25"; pal_8="$pal_ink"

N=8

# ── 工具 ────────────────────────────────────────────────────────────────
# ★ 必须用 gsettings 取:从没改过终端设置的机器,dconf 用户库里没有这一项,
#   但 gsettings 会回落到 schema 默认值,照样能拿到那个默认 profile 的 UUID。
profiles() {
  local ids
  ids=$(gsettings get org.gnome.Terminal.ProfilesList list 2>/dev/null \
        | grep -oE '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}')
  [ -n "$ids" ] || ids=$(dconf list "$PROFDIR" 2>/dev/null | grep '^:' | tr -d ':/')
  printf ':%s\n' $ids
}
gt_get() { gsettings get "org.gnome.Terminal.Legacy.Profile:$PROFDIR$1/" "$2" 2>/dev/null; }
rgb() { printf '%d;%d;%d' "0x${1:1:2}" "0x${1:3:2}" "0x${1:5:2}"; }
swatch() { printf '\033[48;2;%s;38;2;%sm%s\033[0m' "$(rgb "$1")" "$(rgb "$2")" "$3"; }

backup_now() {
  local p first=1
  mkdir -p "$(dirname "$ORIG")" 2>/dev/null
  : > "$ORIG" 2>/dev/null || { echo "写不了备份文件 $ORIG" >&2; return 1; }
  for p in $(profiles); do
    { [ $first -eq 1 ] || echo; echo "[$p]"; } >> "$ORIG"
    first=0
    # 先记生效值:没自定义过的机器 dconf dump 是空的,只靠它备份=还原不回去
    echo "use-theme-colors=$(gt_get "$p" use-theme-colors)" >> "$ORIG"
    dconf dump "$PROFDIR$p/" | grep -E '^(background-color|foreground-color|bold-color|bold-color-same-as-fg|bold-is-bright|cursor-colors-set|cursor-background-color|cursor-foreground-color|highlight-colors-set|highlight-background-color|highlight-foreground-color|palette)=' >> "$ORIG"
  done
  [ -s "$ORIG" ] || { echo "备份内容为空,没敢继续" >&2; return 1; }
}

do_list() {
  echo
  echo "  GNOME Terminal 护眼配色 —— 小样就是它真实的底色/字色:"
  echo
  local i n b f
  for i in $(seq 0 $N); do
    eval "n=\$name_$i b=\$bg_$i f=\$fg_$i"
    printf '  %s  ' "$i"
    swatch "$b" "$f" "  \$ ls -l  /etc/nginx  # 注释文字  "
    printf '  %s\n' "$n"
  done
  echo
  echo "  套用:$SELF 7      还原:$SELF 0      装成命令:$SELF install"
  echo
}

do_show() {
  local p b f
  for p in $(profiles); do
    b=$(dconf read "$PROFDIR$p/background-color" | tr -d "'")
    f=$(dconf read "$PROFDIR$p/foreground-color" | tr -d "'")
    [ -n "$b" ] || { echo "  $p  用的是系统主题原色"; continue; }
    printf '  %s  底 %s 字 %s  ' "$p" "$b" "$f"; swatch "$b" "$f" " 示例 "; echo
  done
}

do_restore() {
  if [ -s "$ORIG" ]; then
    dconf load "$PROFDIR" < "$ORIG"
    echo "已还原成你原来的配色。"
    return
  fi
  # 没有备份点(比如备份文件被删了)——退而求其次:把颜色交还给系统主题,
  # 只动颜色相关的键,字体/窗口大小/滚动这些一律不碰。
  local p k
  for p in $(profiles); do
    dconf write "$PROFDIR$p/use-theme-colors" true
    for k in background-color foreground-color bold-color bold-color-same-as-fg \
             cursor-colors-set cursor-background-color cursor-foreground-color \
             highlight-colors-set highlight-background-color highlight-foreground-color palette; do
      dconf reset "$PROFDIR$p/$k" 2>/dev/null
    done
  done
  echo "没找到备份点,已把颜色恢复成系统默认(字体和窗口设置没动)。"
}

do_apply() {
  local i=$1 n b f c sb sf pal p
  local -a arr
  eval "n=\$name_$i b=\$bg_$i f=\$fg_$i c=\$cur_$i sb=\$selbg_$i sf=\$selfg_$i pal=\$pal_$i"
  if [ ! -s "$ORIG" ]; then
    backup_now || { echo "备份失败,为免你退不回去,这次不改颜色。" >&2; exit 1; }
    echo "(已把你原来的配色备份到 $ORIG,随时 $SELF 0 还原)"
  fi
  IFS=: read -r -a arr <<< "$pal"
  local plist="['${arr[0]}'" k
  for k in "${arr[@]:1}"; do plist="$plist, '$k'"; done; plist="$plist]"
  for p in $(profiles); do
    local d="$PROFDIR$p/"
    dconf write "${d}use-theme-colors"           "false"
    dconf write "${d}background-color"           "'$b'"
    dconf write "${d}foreground-color"           "'$f'"
    dconf write "${d}bold-color-same-as-fg"      "true"
    dconf write "${d}cursor-colors-set"          "true"
    dconf write "${d}cursor-background-color"    "'$c'"
    dconf write "${d}cursor-foreground-color"    "'$b'"
    dconf write "${d}highlight-colors-set"       "true"
    dconf write "${d}highlight-background-color" "'$sb'"
    dconf write "${d}highlight-foreground-color" "'$sf'"
    dconf write "${d}palette"                    "$plist"
    dconf write "${d}use-transparent-background"  "false"
  done
  echo "已套用 $i:$n"
  echo "换一款 $SELF <号>,回原样 $SELF 0"
}

do_install() {
  [ -f "$0" ] || { echo "请先把脚本存成文件再 install(不能从管道里装)。" >&2; exit 1; }
  local dest="$HOME/.local/bin/eyecolor"
  mkdir -p "$HOME/.local/bin"
  cp "$0" "$dest"; chmod 755 "$dest"
  echo "已装到 $dest"
  case ":$PATH:" in
    *":$HOME/.local/bin:"*) echo "以后直接敲:eyecolor" ;;
    *) echo "你的 PATH 里没有 ~/.local/bin,补一行再开新终端:"
       echo "  echo 'export PATH=\"\$HOME/.local/bin:\$PATH\"' >> ~/.bashrc" ;;
  esac
}

# 从管道跑(curl ... | bash)时 $0 是 "bash",提示文字要给个像样的名字
if [ -f "$0" ]; then SELF="bash $(basename "$0")"; else SELF="bash eyecolor-setup.sh"; fi
[ "$(basename "$0")" = eyecolor ] && SELF=eyecolor

case "${1:-list}" in
  ''|list|-l|--list|-h|--help) do_list ;;
  show|-s)                     do_show ;;
  save)                        backup_now; echo "已把当前配色存为还原点:$ORIG" ;;
  install)                     do_install ;;
  0|restore)                   do_restore ;;
  [1-9])
    if [ "$1" -le $N ]; then do_apply "$1"
    else echo "只有 1..$N,0=还原。" >&2; exit 1; fi ;;
  *) echo "用法:$SELF [list|show|save|install|0|1..$N]" >&2; exit 1 ;;
esac
