package wizard

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

// Focusable 定义可聚焦组件的通用接口
type Focusable interface {
	// Focus 激活焦点（比如输入框闪烁光标、按钮高亮）
	Focus() tea.Cmd
	// Blur 失活焦点（取消高亮/闪烁）
	Blur()
	// IsFocused 判断是否处于焦点状态
	IsFocused() bool
	// View 渲染组件（和 bubbletea 统一）
	View() string
}

// --------------- 为常用组件实现 Focusable 接口 ---------------

// TextInput 适配 bubbles/textinput
type TextInput struct {
	textinput.Model
	focused bool
}

func NewTextInput(placeholder string, defaultValue string) *TextInput {
	ti := textinput.New()
	ti.Placeholder = placeholder
	ti.SetValue(defaultValue)
	ti.Blur()
	return &TextInput{Model: ti, focused: false}
}

func (t *TextInput) Focus() tea.Cmd {
	t.focused = true
	return t.Model.Focus()
}

func (t *TextInput) Blur() {
	t.focused = false
	t.Model.Blur()
}

func (t *TextInput) IsFocused() bool {
	return t.focused
}

// Button 适配 bubbles/button
type Button struct {
	label       string
	focused     bool
	buttonBlur  lipgloss.Style
	buttonFocus lipgloss.Style
}

func NewButton(label string) *Button {
	return &Button{
		label:       label,
		focused:     false,
		buttonBlur:  btnBaseStyle,
		buttonFocus: btnSelectedStyle,
	}
}

func (b *Button) Focus() tea.Cmd {
	b.focused = true
	b.buttonBlur = b.buttonFocus
	return nil
}

func (b *Button) Blur() {
	b.focused = false
	b.buttonBlur = btnBaseStyle
}

func (b *Button) IsFocused() bool {
	return b.focused
}

func (b *Button) View() string {
	if b.focused {
		return b.buttonFocus.Render(b.label)
	}
	return b.buttonBlur.Render(b.label)
}

// List 适配 bubbles/list
type List struct {
	list.Model
	focused bool
}

func NewList(items []list.Item) List {
	l := list.New(items, list.NewDefaultDelegate(), 0, 0)
	l.SetShowHelp(false)
	return List{Model: l, focused: false}
}

func (l *List) Focus() tea.Cmd {
	l.focused = true
	return nil
}

func (l *List) Blur() {
	l.focused = false
}

func (l *List) IsFocused() bool {
	return l.focused
}

// FocusManager 焦点管理器
type FocusManager struct {
	// 所有可聚焦组件（key=唯一标识，比如 "form1.ip_input"、"form1.next_btn"）
	components map[string]Focusable
	// 组件切换顺序（按这个顺序切换焦点）
	order []string
	// 当前焦点组件的标识
	currentFocusID string
	// 是否循环切换（到最后一个后回到第一个）
	loop bool
}

// NewFocusManager 创建焦点管理器
func NewFocusManager(loop bool) *FocusManager {
	return &FocusManager{
		components:     make(map[string]Focusable),
		order:          make([]string, 0),
		currentFocusID: "",
		loop:           loop,
	}
}

/*
Register 注册可聚焦组件（指定标识和切换顺序）
ID 组件的唯一标识，用于后续切换和获取焦点
例如 "form1.ip_input"、"form1.next_btn"
*/
func (fm *FocusManager) Register(id string, comp Focusable) {

	// 防御性检查：避免 components 未初始化为nil导致 panic
	if fm.components == nil {
		fm.components = make(map[string]Focusable)
	}

	// 避免重复注册
	if _, exists := fm.components[id]; exists {
		return
	}

	// id  : accept_btn, form1.reject_btn
	// comp: 接受协议按钮, 拒绝协议按钮
	fm.components[id] = comp
	fm.order = append(fm.order, id)

	// 如果是第一个注册的组件，默认聚焦
	if fm.currentFocusID == "" {
		fm.currentFocusID = id
		comp.Focus()
	}
}

// Next 切换到下一个组件
func (fm *FocusManager) Next() tea.Cmd {

	if len(fm.order) == 0 {
		return nil
	}

	// 1. 找到当前组件的索引
	currentIdx := -1
	for i, id := range fm.order {
		if id == fm.currentFocusID {
			currentIdx = i
			break
		}
	}

	// 2. 计算下一个索引
	nextIdx := currentIdx + 1
	if fm.loop && nextIdx >= len(fm.order) {
		nextIdx = 0
	}
	if nextIdx >= len(fm.order) {
		return nil // 不循环则到最后一个停止
	}

	// 3. 切换焦点（当前组件失活，下一个激活）
	fm.components[fm.currentFocusID].Blur()
	nextID := fm.order[nextIdx]
	fm.currentFocusID = nextID
	return fm.components[nextID].Focus()
}

// Prev 切换到上一个组件
func (fm *FocusManager) Prev() tea.Cmd {
	if len(fm.order) == 0 {
		return nil
	}

	currentIdx := -1
	for i, id := range fm.order {
		if id == fm.currentFocusID {
			currentIdx = i
			break
		}
	}

	prevIdx := currentIdx - 1
	if fm.loop && prevIdx < 0 {
		prevIdx = len(fm.order) - 1
	}
	if prevIdx < 0 {
		return nil
	}

	//fm.components[fm.currentFocusID].Blur()
	fm.components[fm.currentFocusID].Blur()
	prevID := fm.order[prevIdx]
	fm.currentFocusID = prevID
	return fm.components[prevID].Focus()
}

// GetCurrent 获取当前焦点组件
func (fm *FocusManager) GetCurrent() (Focusable, bool) {
	comp, exists := fm.components[fm.currentFocusID]
	return comp, exists
}

// HandleInput 统一处理焦点切换输入（比如 Tab/Shift+Tab）
func (fm *FocusManager) HandleInput(msg tea.KeyMsg) tea.Cmd {
	switch msg.String() {
	case "tab": // Tab 下一个
		return fm.Next()
	case "shift+tab": // Shift+Tab 上一个
		return fm.Prev()
	case "left": // Left 上一个
		return fm.Prev()
	case "right": // Right 下一个
		return fm.Next()
	default:
		return nil
	}
}

func (m *model) switchPage(targetPage PageType) tea.Cmd {
	// 边界检查（不能超出 1-6 页面)
	if targetPage < PageAgreement || targetPage > PageSummary {
		return nil
	}

	// 更新当前页面
	m.currentPage = targetPage

	// 初始化新页面的焦点
	m.initPageFocus(targetPage)

	// 返回空指令(或返回第一个组件的Focus命令)
	return nil
}

func (m *model) initPageFocus(page PageType) {

	m.focusManager = NewFocusManager(true)

	pageComps, exists := m.pageComponents[page]
	if !exists {
		return
	}

	var componentOrder []string
	var defaultFocusID string

	switch page {
	case PageAgreement:
		componentOrder = []string{"accept_btn", "reject_btn"}
		defaultFocusID = "accept_btn"
	case PageData:
		componentOrder = []string{
			"Homepage_input",
			"ClusterName_input",
			"Country_input",
			"State_input",
			"City_input",
			"Contact_input",
			"Timezone_input",
			"DistroDir_input",
			"next_btn",
			"prev_btn",
		}
		defaultFocusID = "next_btn"
	case PagePublicNetwork:
		componentOrder = []string{
			"PublicHostname_input",
			"PublicInterface_input",
			"PublicIPAddress_input",
			"PublicNetmask_input",
			"PublicGateway_input",
			"PublicDomain_input",
			"PublicMTU_input",
			"next_btn",
			"prev_btn",
		}
		defaultFocusID = "next_btn"
	case PageInternalNetwork:
		componentOrder = []string{
			"PrivateHostname_input",
			"PrivateInterface_input",
			"PrivateIPAddress_input",
			"PrivateNetmask_input",
			"PrivateDomain_input",
			"PrivateMTU_input",
			"next_btn",
			"prev_btn",
		}
		defaultFocusID = "next_btn"
	case PageDNS:
		componentOrder = []string{
			"Pri_DNS_input",
			"Sec_DNS_input",
			"next_btn",
			"prev_btn",
		}
		defaultFocusID = "next_btn"
	case PageSummary:
		componentOrder = []string{"confirm_btn", "cancel_btn"}
		defaultFocusID = "confirm_btn"
	}

	for _, compID := range componentOrder {
		if comp, exists := pageComps[compID]; exists {
			m.focusManager.Register(compID, comp)
		}
	}

	if defaultFocusID != "" {
		if currentComp, exists := m.focusManager.GetCurrent(); exists {
			currentComp.Blur()
		}
		if targetComp, exists := pageComps[defaultFocusID]; exists {
			m.focusManager.currentFocusID = defaultFocusID
			targetComp.Focus()
		}
	}
}
