//! Write tmux theme.conf from colors.toml (wallpaper base16) and reload servers.

use std::path::{Path, PathBuf};
use std::process::Command;

use crate::palette::load_palette;
use crate::state;

fn theme_path() -> PathBuf {
    if let Ok(p) = std::env::var("DENDRITIC_TMUX_THEME") {
        return PathBuf::from(p);
    }
    state::home_dir()
        .map(|h| h.join(".config/tmux/theme.conf"))
        .unwrap_or_else(|| PathBuf::from("theme.conf"))
}

fn req<'a>(map: &'a std::collections::HashMap<String, String>, key: &str) -> Result<&'a str, String> {
    map.get(key)
        .map(String::as_str)
        .ok_or_else(|| format!("palette missing {key}"))
}

/// Generate powerline status colors matching modules/apps/tmux.nix layout.
pub fn write_theme_from_colors(colors_path: &Path) -> Result<PathBuf, String> {
    let p = load_palette(colors_path)?;
    let b00 = req(&p, "base00")?;
    let b02 = req(&p, "base02")?;
    let b03 = req(&p, "base03")?;
    let b04 = req(&p, "base04")?;
    let b05 = req(&p, "base05")?;
    let b06 = req(&p, "base06")?;
    let b08 = req(&p, "base08")?;
    let b0a = req(&p, "base0A")?;
    let b0b = req(&p, "base0B")?;
    let b0e = req(&p, "base0E")?;

    let body = format!(
        r##"# Generated by dendritic-appearance from colors.toml — do not edit.
# Wallpaper-derived base16 (same palette as Stylix / Ghostty / IDE).
set -g status-style "fg={b05},bg={b00}"
set -g message-style "fg={b06},bg={b02}"
set -g message-command-style "fg={b06},bg={b02}"
set -g pane-border-style "fg={b02}"
set -g pane-active-border-style "fg={b04}"
set -g mode-style "fg={b04},bg={b02}"

set -g window-status-style "fg={b05},bg={b00}"
set -g window-status-current-style "fg={b0a},bg={b00}"
set -g window-status-activity-style "fg={b05},bg={b00}"
set -g window-status-bell-style "fg={b00},bg={b08}"
set -g window-status-separator ""
set -g window-status-format "#[fg={b00},bg={b02},noitalics]#[fg={b06},bg={b02}] #I  #W#{{?window_zoomed_flag,*Z,}} #[fg={b02},bg={b00},noitalics]"
set -g window-status-current-format "#[fg={b00},bg={b0a},nobold,noitalics,nounderscore]#[fg={b02},bg={b0a}] #I #[fg={b02},bg={b0a},bold] #W#{{?window_zoomed_flag,*Z,}} #[fg={b0a},bg={b00},nobold,noitalics,nounderscore]"

set -g status-left "#[fg={b05},bg={b02}] #S #[fg={b02},bg={b00},nobold,noitalics,nounderscore]"
set -g status-right "#[fg={b03}]#{{prefix_highlight}}#[fg={b02},bg={b00}]#[fg={b04},bg={b02}] %H:%M #[range=right fg={b00},bg={b0b},bold] + #[norange]"

set -g @prefix_highlight_fg '{b00}'
set -g @prefix_highlight_bg '{b0e}'
"##,
        b00 = b00,
        b02 = b02,
        b03 = b03,
        b04 = b04,
        b05 = b05,
        b06 = b06,
        b08 = b08,
        b0a = b0a,
        b0b = b0b,
        b0e = b0e,
    );

    let dest = theme_path();
    if let Some(parent) = dest.parent() {
        std::fs::create_dir_all(parent).map_err(|e| format!("mkdir {}: {e}", parent.display()))?;
    }
    // Replace HM store symlink (same pattern as ~/.colors.toml).
    let _ = std::fs::remove_file(&dest);
    std::fs::write(&dest, body).map_err(|e| format!("write {}: {e}", dest.display()))?;
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        let _ = std::fs::set_permissions(&dest, std::fs::Permissions::from_mode(0o644));
    }
    Ok(dest)
}

pub fn reload(theme: &Path) -> Result<(), String> {
    // Only touch live servers; ignore if none.
    let st = Command::new("tmux")
        .args(["-L", "default", "source-file", theme.to_str().unwrap_or("")])
        .status();
    match st {
        Ok(s) if s.success() => Ok(()),
        Ok(_) | Err(_) => {
            // Also try without -L (some platforms use different socket names).
            let _ = Command::new("tmux")
                .args(["source-file", theme.to_str().unwrap_or("")])
                .status();
            Ok(())
        }
    }
}

pub fn apply_from_colors(colors_path: &Path) -> Result<(), String> {
    let theme = write_theme_from_colors(colors_path)?;
    let _ = reload(&theme);
    Ok(())
}
