package tui

import (
	"strings"

	"github.com/charmbracelet/bubbles/textinput"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

// SSHConfigModel handles SSH connection input
type SSHConfigModel struct {
	inputs     []textinput.Model
	focusIndex int
	submitted  bool
	cancelled  bool

	// Parsed values
	Host     string
	Port     string
	User     string
	Password string
}

const (
	inputHost = iota
	inputPort
	inputUser
	inputPassword
)

// NewSSHConfigModel creates a new SSH config input model
func NewSSHConfigModel() SSHConfigModel {
	inputs := make([]textinput.Model, 4)

	// Host input
	inputs[inputHost] = textinput.New()
	inputs[inputHost].Placeholder = "192.168.1.100"
	inputs[inputHost].Focus()
	inputs[inputHost].CharLimit = 256
	inputs[inputHost].Width = 30
	inputs[inputHost].Prompt = "Host: "

	// Port input
	inputs[inputPort] = textinput.New()
	inputs[inputPort].Placeholder = "22"
	inputs[inputPort].CharLimit = 5
	inputs[inputPort].Width = 10
	inputs[inputPort].Prompt = "Port: "
	inputs[inputPort].SetValue("22")

	// User input
	inputs[inputUser] = textinput.New()
	inputs[inputUser].Placeholder = "root"
	inputs[inputUser].CharLimit = 64
	inputs[inputUser].Width = 20
	inputs[inputUser].Prompt = "User: "

	// Password input
	inputs[inputPassword] = textinput.New()
	inputs[inputPassword].Placeholder = "password"
	inputs[inputPassword].CharLimit = 128
	inputs[inputPassword].Width = 30
	inputs[inputPassword].Prompt = "Password: "
	inputs[inputPassword].EchoMode = textinput.EchoPassword
	inputs[inputPassword].EchoCharacter = '•'

	return SSHConfigModel{
		inputs:     inputs,
		focusIndex: 0,
	}
}

// Init initializes the model
func (m SSHConfigModel) Init() tea.Cmd {
	return textinput.Blink
}

// Update handles messages
func (m SSHConfigModel) Update(msg tea.Msg) (SSHConfigModel, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "ctrl+c", "esc":
			m.cancelled = true
			return m, nil

		case "tab", "down":
			m.focusIndex++
			if m.focusIndex >= len(m.inputs) {
				m.focusIndex = 0
			}
			return m, m.updateFocus()

		case "shift+tab", "up":
			m.focusIndex--
			if m.focusIndex < 0 {
				m.focusIndex = len(m.inputs) - 1
			}
			return m, m.updateFocus()

		case "enter":
			if m.focusIndex == len(m.inputs)-1 {
				// Submit on last field
				m.submitted = true
				m.Host = m.inputs[inputHost].Value()
				m.Port = m.inputs[inputPort].Value()
				m.User = m.inputs[inputUser].Value()
				m.Password = m.inputs[inputPassword].Value()
				return m, nil
			}
			// Move to next field
			m.focusIndex++
			return m, m.updateFocus()
		}
	}

	// Update focused input
	cmd := m.updateInputs(msg)
	return m, cmd
}

func (m *SSHConfigModel) updateFocus() tea.Cmd {
	cmds := make([]tea.Cmd, len(m.inputs))
	for i := range m.inputs {
		if i == m.focusIndex {
			cmds[i] = m.inputs[i].Focus()
		} else {
			m.inputs[i].Blur()
		}
	}
	return tea.Batch(cmds...)
}

func (m *SSHConfigModel) updateInputs(msg tea.Msg) tea.Cmd {
	cmds := make([]tea.Cmd, len(m.inputs))
	for i := range m.inputs {
		m.inputs[i], cmds[i] = m.inputs[i].Update(msg)
	}
	return tea.Batch(cmds...)
}

// View renders the SSH config form
func (m SSHConfigModel) View() string {
	var b strings.Builder

	titleStyle := lipgloss.NewStyle().
		Bold(true).
		Foreground(lipgloss.Color("#7D56F4")).
		MarginBottom(1)

	b.WriteString(titleStyle.Render("🔌 SSH Connection"))
	b.WriteString("\n\n")

	for i := range m.inputs {
		b.WriteString(m.inputs[i].View())
		b.WriteString("\n")
	}

	helpStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#626262"))
	b.WriteString("\n")
	b.WriteString(helpStyle.Render("Tab/↑↓ navigate • Enter submit • Esc cancel"))

	return b.String()
}

// IsSubmitted returns true if the form was submitted
func (m SSHConfigModel) IsSubmitted() bool {
	return m.submitted
}

// IsCancelled returns true if the form was cancelled
func (m SSHConfigModel) IsCancelled() bool {
	return m.cancelled
}

// GetConfig returns the SSH config values
func (m SSHConfigModel) GetConfig() (host, port, user, password string) {
	return m.Host, m.Port, m.User, m.Password
}
