package main

import (
	"strings"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/jixishi/SerialTerminalForWindowsTerminal/internal/event"
)

func handleLocalHotkey(m *uiModel, key string) bool {
	if m.isLocalHotkey(key, "h") {
		modifier := strings.ToUpper(normalizeHotkeyPrefix(m.app.cfg.hotkeyMod))
		m.app.ShowModal("Shortcuts", modifier+"+C => local exit\nCtrl+C => remote interrupt\n"+modifier+"+F => forward panel\n"+modifier+"+P => plugin panel\n"+modifier+"+M => mode panel\nF1 => shortcut help")
		return true
	}
	if m.isLocalHotkey(key, "f") {
		m.app.OpenPanel(event.UIPanelForward)
		return true
	}
	if m.isLocalHotkey(key, "p") {
		m.app.OpenPanel(event.UIPanelPlugin)
		return true
	}
	if m.isLocalHotkey(key, "m") {
		m.app.OpenPanel(event.UIPanelMode)
		return true
	}
	return false
}

func (m *uiModel) isLocalHotkey(key, action string) bool {
	parts := strings.Split(strings.ToLower(key), "+")
	if len(parts) < 2 || parts[len(parts)-1] != action {
		return false
	}

	hasCtrl := false
	hasAlt := false
	hasShift := false
	for _, p := range parts[:len(parts)-1] {
		switch p {
		case "ctrl":
			hasCtrl = true
		case "alt":
			hasAlt = true
		case "shift":
			hasShift = true
		}
	}

	mod := normalizeHotkeyPrefix(m.app.cfg.hotkeyMod)
	if mod == "ctrl+shift" {
		return hasCtrl && hasShift
	}
	return hasCtrl && hasAlt
}

func normalizeHotkeyPrefix(mod string) string {
	mod = strings.ToLower(strings.TrimSpace(mod))
	if mod != "ctrl+alt" && mod != "ctrl+shift" {
		mod = "ctrl+alt"
	}
	return mod
}

func hotkeyWith(mod, action string) string {
	return normalizeHotkeyPrefix(mod) + "+" + action
}

func parseCtrlKey(key string) (byte, bool) {
	if !strings.HasPrefix(key, "ctrl+") || strings.HasPrefix(key, "ctrl+shift+") {
		return 0, false
	}

	parts := strings.Split(key, "+")
	if len(parts) != 2 || len(parts[1]) != 1 {
		return 0, false
	}
	ch := parts[1][0]
	if ch < 'a' || ch > 'z' {
		return 0, false
	}
	return ch, true
}

func (m *uiModel) handleViewportKey(msg tea.KeyMsg) bool {
	if !m.ready || m.showModal {
		return false
	}

	key := strings.ToLower(msg.String())
	switch key {
	case "pgup", "ctrl+u", "alt+up", "up":
		var cmd tea.Cmd
		m.viewport, cmd = m.viewport.Update(msg)
		_ = cmd
		m.followTail = false
		return true
	case "pgdown", "ctrl+d", "alt+down", "down":
		var cmd tea.Cmd
		m.viewport, cmd = m.viewport.Update(msg)
		_ = cmd
		return true
	case "home", "g":
		m.viewport.GotoTop()
		m.followTail = false
		return true
	case "end", "shift+g":
		m.viewport.GotoBottom()
		m.followTail = true
		return true
	default:
		return false
	}
}

func (m *uiModel) resetCompletion() {
	m.completionActive = false
	m.completionBase = ""
	m.completionCandidates = nil
	m.completionIndex = 0
}

func (m *uiModel) stepCompletion(direction int) {
	if len(m.completionCandidates) == 0 {
		m.resetCompletion()
		return
	}
	if direction >= 0 {
		m.completionIndex = (m.completionIndex + 1) % len(m.completionCandidates)
	} else {
		m.completionIndex = (m.completionIndex - 1 + len(m.completionCandidates)) % len(m.completionCandidates)
	}
	m.applyCompletion()
}

func (m *uiModel) applyCompletion() {
	if len(m.completionCandidates) == 0 {
		return
	}
	m.input.SetValue(m.completionBase + m.completionCandidates[m.completionIndex] + " ")
}

func completionBase(line string) string {
	if strings.HasSuffix(line, " ") {
		return line
	}
	i := strings.LastIndex(line, " ")
	if i < 0 {
		return ""
	}
	return line[:i+1]
}
