package main

import (
	"strings"

	"github.com/charmbracelet/lipgloss"
)

func renderLayout(m model) string {
	serverBarWidth := 8
	channelWidth := 24
	memberWidth := 20
	statusHeight := 1

	chatHeight := m.height - statusHeight - 2
	if chatHeight < 5 {
		chatHeight = 5
	}

	chatWidth := m.width - serverBarWidth - channelWidth
	if m.showMembers {
		chatWidth -= memberWidth
	}
	if chatWidth < 20 {
		chatWidth = 20
	}

	// ---- Server bar (left column) ----
	serverBar := ServerBar(m.servers, m.currentServer, m.hoverServer, m.height-statusHeight)

	// ---- Channel list ----
	channelList := ChannelList(m.channels, m.currentChannel, m.hoverChannel, channelWidth-2, m.height-statusHeight)

	// Apply focus border to channel list
	if m.focus == focusChannels {
		channelList = FocusedBorder.Render(channelList)
	}

	// ---- Chat pane ----
	// Channel header
	ch := ChannelByFlatIndex(m.channels, m.currentChannel)
	headerText := "# general"
	if ch != nil {
		headerText = formatChannelHeader(*ch)
	}

	header := TitleStyle.
		Width(chatWidth - 2).
		Render(headerText)

	// Typing indicator
	typingBar := ""
	if m.typing != "" {
		typingBar = HelpStyle.Render("  " + m.typing + " is typing...")
	}

	// Voice status
	voiceBar := ""
	if m.voice.Connected {
		voiceBar = VoiceStatusStyle.
			Width(chatWidth - 2).
			Render(m.voice.StatusText())
	}

	// Input
	inputStyle := InputPaneStyle.Width(chatWidth - 2)
	inputView := inputStyle.Render("> " + m.input.View())

	// Chat viewport
	chatPane := lipgloss.JoinVertical(lipgloss.Left,
		header,
		m.viewport.View(),
	)

	if typingBar != "" {
		chatPane = lipgloss.JoinVertical(lipgloss.Left, chatPane, typingBar)
	}
	if voiceBar != "" {
		chatPane = lipgloss.JoinVertical(lipgloss.Left, chatPane, voiceBar)
	}

	chatPane = lipgloss.JoinVertical(lipgloss.Left, chatPane, inputView)

	// Focus border for chat
	if m.focus == focusChat || m.focus == focusInput {
		chatPane = FocusedBorder.Width(chatWidth).Render(chatPane)
	}

	// ---- Member list ----
	var memberView string
	if m.showMembers {
		memberView = MemberList(m.user, m.members, memberWidth-2, m.height-statusHeight, true)
		if m.focus == focusMembers {
			memberView = FocusedBorder.Render(memberView)
		}
	}

	// ---- Status bar ----
	statusParts := []string{}
	if m.err != "" {
		statusParts = append(statusParts, ErrorStyle.Render("⚠ "+m.err))
	} else if m.statusMsg != "" {
		statusParts = append(statusParts, SuccessStyle.Render(m.statusMsg))
	} else if m.typing != "" {
		statusParts = append(statusParts, HelpStyle.Render(m.typing+" is typing..."))
	}

	// Show current user
	if m.user.Username != "" {
		right := UsernameStyle.Render(m.user.Username)
		statusParts = append(statusParts, lipgloss.PlaceHorizontal(
			m.width-lipgloss.Width(right)-2, lipgloss.Right, right))
	}

	statusBar := lipgloss.NewStyle().
		Background(bgT).
		Foreground(fg).
		Width(m.width).
		Padding(0, 1).
		Render(strings.Join(statusParts, " "))

	// ---- Help overlay ----
	if m.showHelp {
		return renderHelp(m)
	}

	// ---- Compose layout ----
	var rows []string

	// Top row: servers | channels | chat | members
	topRow := lipgloss.JoinHorizontal(lipgloss.Top,
		serverBar,
		channelList,
		chatPane,
	)
	if m.showMembers && memberView != "" {
		topRow = lipgloss.JoinHorizontal(lipgloss.Top, topRow, memberView)
	}

	rows = append(rows, topRow)
	rows = append(rows, statusBar)

	return lipgloss.JoinVertical(lipgloss.Left, rows...)
}

func renderHelp(m model) string {
	helpText := []string{
		"",
		TitleStyle.Render("🗑  Dumpster Chat — Help"),
		"",
		"  Navigation",
		"  ──────────",
		"  j/k or ↑/↓    Navigate up/down",
		"  g / G          Jump to top/bottom",
		"  Tab            Cycle focus between panes",
		"  Enter          Select server/channel",
		"",
		"  Chat",
		"  ──────────",
		"  i              Focus message input",
		"  Enter          Send message (in input)",
		"  Esc            Unfocus input",
		"",
		"  Panels",
		"  ──────────",
		"  m              Toggle member list / mute (in voice)",
		"  ?              Toggle this help",
		"  q / Ctrl+C     Quit",
		"",
		HelpStyle.Render("  Press ? to close"),
	}

	return lipgloss.NewStyle().
		Background(bg).
		Foreground(fg).
		Width(m.width).
		Height(m.height).
		Padding(1, 2).
		Render(strings.Join(helpText, "\n"))
}
