package ui

import (
	"fmt"
	"strings"

	"termdoku/internal/database"
	"termdoku/internal/stats"
	"termdoku/internal/theme"

	"github.com/charmbracelet/lipgloss"
)

// viewProfile displays a simple profile landing page with navigation options.
func (a App) viewProfile() string {
	adaptiveColors := theme.NewAdaptiveColors(a.th)
	gradientColors := adaptiveColors.GetGradientColors()
	profileGrad := gradientColors["banner"]

	title := gradientText("User Profile", profileGrad[0], profileGrad[1])

	var content strings.Builder
	content.WriteString(title + "\n\n")

	content.WriteString(a.renderProfileSummary())
	content.WriteString("\n\n")

	instructionStyle := lipgloss.NewStyle().
		Foreground(lipgloss.Color(a.th.Palette.Accent)).
		Bold(true)

	content.WriteString(instructionStyle.Render("Navigation:") + "\n")
	content.WriteString(a.styles.Status.Render("  Press 's' to view detailed profile data (Stats, Achievements, Leaderboard)"))
	content.WriteString("\n")
	content.WriteString(a.styles.Status.Render("  Press 'd' to view database info"))
	content.WriteString("\n")
	content.WriteString(a.styles.Status.Render("  Press 'm' or Enter to return to menu"))

	panel := a.styles.Panel.Render(content.String())
	if a.width > 0 && a.height > 0 {
		return a.styles.App.Render(lipgloss.Place(a.width, a.height, lipgloss.Center, lipgloss.Center, panel))
	}
	return a.styles.App.Render(panel)
}

// viewProfileSubmenu displays a dropdown menu for selecting profile data type.
func (a App) viewProfileSubmenu() string {
	adaptiveColors := theme.NewAdaptiveColors(a.th)
	gradientColors := adaptiveColors.GetGradientColors()
	profileGrad := gradientColors["banner"]

	title := gradientText(">> Select Profile Data", profileGrad[0], profileGrad[1])

	var content strings.Builder
	content.WriteString(title + "\n\n")

	var items []string
	accentColors := adaptiveColors.GetAccentColors()
	selectedStyle := lipgloss.NewStyle().
		Foreground(lipgloss.Color(accentColors["selected"])).
		Bold(true)

	for i, name := range a.profileMenuItems {
		if i == a.profileSelectedIdx {
			prefix := "▶ "
			label := prefix + name
			items = append(items, selectedStyle.Render(label))
		} else {
			prefix := "  "
			label := prefix + name
			items = append(items, a.styles.MenuItem.Render(label))
		}
	}

	menuContent := strings.Join(items, "\n")

	menuStyle := lipgloss.NewStyle().
		Border(lipgloss.RoundedBorder()).
		BorderForeground(lipgloss.Color(profileGrad[0])).
		Padding(1, 2).
		MarginTop(1).
		MarginBottom(1)

	content.WriteString(menuStyle.Render(menuContent))
	content.WriteString("\n\n")

	content.WriteString(a.styles.Status.Render("Use ↑/↓ or k/j to navigate, Enter to select"))
	content.WriteString("\n")
	content.WriteString(a.styles.Status.Render("Press 'm' or Esc to return to profile"))

	panel := a.styles.Panel.Render(content.String())
	if a.width > 0 && a.height > 0 {
		return a.styles.App.Render(lipgloss.Place(a.width, a.height, lipgloss.Center, lipgloss.Center, panel))
	}
	return a.styles.App.Render(panel)
}

// renderProfileSummary renders the user summary card.
func (a App) renderProfileSummary() string {
	var sb strings.Builder

	totalGames := a.stats.TotalGames
	completed := a.stats.CompletedGames
	winRate := 0.0
	if totalGames > 0 {
		winRate = float64(completed) / float64(totalGames) * 100
	}

	rank := a.calculateRank(completed)
	rankEmoji := a.getRankEmoji(rank)

	summaryStyle := lipgloss.NewStyle().
		Border(lipgloss.RoundedBorder()).
		BorderForeground(lipgloss.Color(a.th.Palette.Accent)).
		Padding(1, 2).
		MarginTop(1)

	summaryContent := fmt.Sprintf(
		"%s Rank: %s"+
			"\n>> Total Games: %d"+
			"\n>> Completed: %d"+
			"\n>> Win Rate: %.1f%%"+
			"\n>> Current Streak: %d days"+
			"\n>> Best Streak: %d days",
		rankEmoji, rank,
		totalGames,
		completed,
		winRate,
		a.stats.CurrentStreak,
		a.stats.BestStreak,
	)

	sb.WriteString(summaryStyle.Render(summaryContent))

	return sb.String()
}

// calculateRank determines user rank based on completed games.
func (a App) calculateRank(completed int) string {
	switch {
	case completed >= 1000:
		return "Grandmaster"
	case completed >= 500:
		return "Master"
	case completed >= 250:
		return "Expert"
	case completed >= 100:
		return "Advanced"
	case completed >= 50:
		return "Intermediate"
	case completed >= 25:
		return "Apprentice"
	case completed >= 10:
		return "Novice"
	case completed >= 1:
		return "Beginner"
	default:
		return "Newcomer"
	}
}

// getRankEmoji returns an emoji for the rank.
func (a App) getRankEmoji(rank string) string {
	switch rank {
	case "Grandmaster":
		return "👑"
	case "Master":
		return "🎖️"
	case "Expert":
		return "🏅"
	case "Advanced":
		return "⭐"
	case "Intermediate":
		return "🌟"
	case "Apprentice":
		return "✨"
	case "Novice":
		return "🔰"
	case "Beginner":
		return "🌱"
	default:
		return "👤"
	}
}

// viewDatabaseInfo displays detailed database information.
func (a App) viewDatabaseInfo() string {
	adaptiveColors := theme.NewAdaptiveColors(a.th)
	gradientColors := adaptiveColors.GetGradientColors()
	dbGrad := gradientColors["banner"]

	title := gradientText("Database Info", dbGrad[0], dbGrad[1])

	var content strings.Builder
	content.WriteString(title + "\n\n")

	db, err := database.Open()
	if err != nil {
		content.WriteString(a.styles.Status.Render(fmt.Sprintf("Error opening database: %v\n", err)))
	} else {
		defer db.Close()

		dbStats, err := db.GetStats()
		if err != nil {
			content.WriteString(a.styles.Status.Render(fmt.Sprintf("Error reading stats: %v\n", err)))
		} else {
			statsStyle := lipgloss.NewStyle().
				Border(lipgloss.RoundedBorder()).
				BorderForeground(lipgloss.Color(a.th.Palette.Accent)).
				Padding(1, 2)

			statsContent := fmt.Sprintf(
				"Total Games: %d"+
					"\n>> Completed Games: %d"+
					"\n>> Current Streak: %d"+
					"\n>> Best Streak: %d"+
					"\n>> Hints Used: %d"+
					"\n>> Last Played: %s",
				dbStats.TotalGames,
				dbStats.CompletedGames,
				dbStats.CurrentStreak,
				dbStats.BestStreak,
				dbStats.HintsUsed,
				dbStats.LastPlayedDate,
			)

			content.WriteString(statsStyle.Render(statsContent))
		}

		content.WriteString("\n\n")
		headerStyle := lipgloss.NewStyle().
			Bold(true).
			Foreground(lipgloss.Color(a.th.Palette.Accent)).
			Render("Achievements")
		content.WriteString(headerStyle + "\n")

		achievements, err := db.GetAchievements()
		if err != nil {
			content.WriteString(a.styles.Status.Render(fmt.Sprintf("Error reading achievements: %v\n", err)))
		} else {
			unlockedCount := 0
			for _, ach := range achievements {
				if ach.Unlocked {
					unlockedCount++
				}
			}
			content.WriteString(a.styles.Status.Render(fmt.Sprintf("Unlocked: %d/%d\n", unlockedCount, len(achievements))))
		}

		content.WriteString("\n")
		headerStyle = lipgloss.NewStyle().
			Bold(true).
			Foreground(lipgloss.Color(a.th.Palette.Accent)).
			Render("Recent Games")
		content.WriteString(headerStyle + "\n")

		recentGames, err := db.GetRecentGames(5)
		if err != nil {
			content.WriteString(a.styles.Status.Render(fmt.Sprintf("Error reading games: %v\n", err)))
		} else {
			if len(recentGames) == 0 {
				content.WriteString(a.styles.Status.Render("No games in database\n"))
			} else {
				for _, game := range recentGames {
					statusIcon := "✅"
					if !game.Completed {
						statusIcon = "❌"
					}
					timeStr := stats.FormatTime(game.TimeSeconds)
					line := fmt.Sprintf("%s %s - %s", statusIcon, game.Difficulty, timeStr)
					if game.IsDaily {
						line += " 📅"
					}
					content.WriteString(a.styles.Status.Render(line + "\n"))
				}
			}
		}
	}

	content.WriteString("\n" + a.styles.Status.Render("Press 'm' or Enter to return to menu"))

	panel := a.styles.Panel.Render(content.String())
	if a.width > 0 && a.height > 0 {
		return a.styles.App.Render(lipgloss.Place(a.width, a.height, lipgloss.Center, lipgloss.Center, panel))
	}
	return a.styles.App.Render(panel)
}
