//go:build !android && !ios && !freebsd && !js

package main

import (
	"runtime"
	"strings"

	log "github.com/sirupsen/logrus"

	"github.com/netbirdio/netbird/client/ui/services"
)

func (t *Tray) applyIcon() {
	t.statusMu.Lock()
	connected := t.connected
	statusLabel := t.lastStatus
	t.statusMu.Unlock()
	hasUpdate := false
	if t.updater != nil {
		hasUpdate = t.updater.hasUpdate()
	}

	log.Infof("tray applyIcon: connected=%v hasUpdate=%v status=%q goos=%s",
		connected, hasUpdate, statusLabel, runtime.GOOS)

	icon, dark := t.iconForState()
	if runtime.GOOS == "darwin" {
		t.tray.SetTemplateIcon(icon)
		return
	}
	if runtime.GOOS == "linux" {
		// Wails' Linux SNI backend ignores SetDarkModeIcon (its
		// setDarkModeIcon just calls setIcon, last-write-wins), so we pick
		// the black-vs-white silhouette ourselves in iconForState based on
		// the panel theme and push a single SetIcon. Calling
		// SetDarkModeIcon here would only clobber that choice.
		t.tray.SetIcon(icon)
		return
	}
	t.tray.SetIcon(icon)
	if dark != nil {
		t.tray.SetDarkModeIcon(dark)
	}
}

// panelIsDark reports whether the desktop panel uses a dark colour scheme, so
// the Linux branch of iconForState can choose the white silhouette. Defaults
// to true when no detector is wired (panelDark nil — non-Linux, or the
// freedesktop portal was unavailable), matching the common dark Linux panel.
func (t *Tray) panelIsDark() bool {
	if t.panelDark == nil {
		return true
	}
	return t.panelDark()
}

func (t *Tray) iconForState() (icon, dark []byte) {
	t.statusMu.Lock()
	connected := t.connected
	statusLabel := t.lastStatus
	t.statusMu.Unlock()
	hasUpdate := false
	if t.updater != nil {
		hasUpdate = t.updater.hasUpdate()
	}

	connecting := strings.EqualFold(statusLabel, services.StatusConnecting)
	errored := strings.EqualFold(statusLabel, statusError) ||
		strings.EqualFold(statusLabel, services.StatusDaemonUnavailable)
	needsLogin := strings.EqualFold(statusLabel, services.StatusNeedsLogin) ||
		strings.EqualFold(statusLabel, services.StatusSessionExpired) ||
		strings.EqualFold(statusLabel, services.StatusLoginFailed)

	if runtime.GOOS == "darwin" {
		switch {
		case connecting:
			return iconConnectingMacOS, nil
		case errored:
			return iconErrorMacOS, nil
		case needsLogin:
			return iconNeedsLoginMacOS, nil
		case connected && hasUpdate:
			return iconUpdateConnectedMacOS, nil
		case connected:
			return iconConnectedMacOS, nil
		case hasUpdate:
			return iconUpdateDisconnectedMacOS, nil
		default:
			return iconDisconnectedMacOS, nil
		}
	}

	if runtime.GOOS == "linux" {
		// Linux: monochrome silhouette chosen by panel theme. Wails' SNI
		// backend can't switch icons per theme itself (see applyIcon), so we
		// resolve black (light panel) vs white (dark panel) here and the
		// caller pushes a single SetIcon. The second return is unused on
		// Linux.
		dark := t.panelIsDark()
		pick := func(black, white []byte) ([]byte, []byte) {
			if dark {
				return white, nil
			}
			return black, nil
		}
		switch {
		case connecting:
			return pick(iconConnectingMono, iconConnectingMonoDark)
		case errored:
			return pick(iconErrorMono, iconErrorMonoDark)
		case needsLogin:
			return pick(iconNeedsLoginMono, iconNeedsLoginMonoDark)
		case connected && hasUpdate:
			return pick(iconUpdateConnectedMono, iconUpdateConnectedMonoDark)
		case connected:
			return pick(iconConnectedMono, iconConnectedMonoDark)
		case hasUpdate:
			return pick(iconUpdateDisconnectedMono, iconUpdateDisconnectedMonoDark)
		default:
			return pick(iconDisconnectedMono, iconDisconnectedMonoDark)
		}
	}

	// Windows: colored PNGs.
	switch {
	case connecting:
		return iconConnecting, nil
	case errored:
		return iconError, nil
	case needsLogin:
		return iconNeedsLogin, nil
	case connected && hasUpdate:
		return iconUpdateConnected, nil
	case connected:
		return iconConnected, iconConnectedDark
	case hasUpdate:
		return iconUpdateDisconnected, nil
	default:
		return iconDisconnected, nil
	}
}
