package ui

import (
	"MobileMkch/api"
	"MobileMkch/models"
	"MobileMkch/settings"
	"fmt"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"MobileMkch/cache"
)

type UIManager struct {
	app       fyne.App
	window    fyne.Window
	apiClient *api.Client

	navigationStack []Screen
	currentScreen   Screen

	mainContainer *fyne.Container
	headerBar     *fyne.Container
	content       *fyne.Container

	settings *settings.Settings
}

type Screen interface {
	GetContent() fyne.CanvasObject
	GetTitle() string
	OnShow()
	OnHide()
}

func NewUIManager(app fyne.App, window fyne.Window, apiClient *api.Client) *UIManager {
	appSettings, err := settings.Load()
	if err != nil {
		appSettings = &settings.Settings{
			Theme:       "dark",
			LastBoard:   "",
			AutoRefresh: true,
			ShowFiles:   true,
			CompactMode: false,
			Key:         "",
		}
	}

	manager := &UIManager{
		app:             app,
		window:          window,
		apiClient:       apiClient,
		navigationStack: make([]Screen, 0),
		content:         container.NewMax(),
		settings:        appSettings,
	}

	if appSettings.Theme == "dark" {
		app.Settings().SetTheme(theme.DarkTheme())
	} else {
		app.Settings().SetTheme(theme.LightTheme())
	}

	manager.setupHeader()
	manager.setupMainContainer()

	boardsScreen := NewBoardsScreen(manager)
	manager.ShowScreen(boardsScreen)

	return manager
}

func (ui *UIManager) setupHeader() {
	backButton := widget.NewButton("<- Назад", func() {
		ui.GoBack()
	})
	backButton.Hide()

	titleLabel := widget.NewLabel("MobileMkch")
	titleLabel.TextStyle = fyne.TextStyle{Bold: true}
	titleLabel.Alignment = fyne.TextAlignCenter

	refreshButton := widget.NewButton("🔄", func() {
		if ui.currentScreen != nil {
			ui.currentScreen.OnShow()
		}
	})

	settingsButton := widget.NewButton("⚙️", func() {
		settingsScreen := NewSettingsScreen(ui)
		ui.ShowScreen(settingsScreen)
	})

	rightButtons := container.NewHBox(refreshButton, settingsButton)

	ui.headerBar = container.NewBorder(
		nil, nil, backButton, rightButtons, titleLabel,
	)
}

func (ui *UIManager) setupMainContainer() {
	ui.mainContainer = container.NewBorder(
		ui.headerBar,
		nil,
		nil,
		nil,
		ui.content,
	)
}

func (ui *UIManager) GetMainContent() fyne.CanvasObject {
	return ui.mainContainer
}

func (ui *UIManager) ShowScreen(screen Screen) {
	if ui.currentScreen != nil {
		ui.currentScreen.OnHide()
	}

	ui.navigationStack = append(ui.navigationStack, screen)
	ui.currentScreen = screen
	ui.content.RemoveAll()
	ui.content.Add(screen.GetContent())
	ui.updateHeader(screen.GetTitle())
	ui.content.Refresh()

	screen.OnShow()
}

func (ui *UIManager) GoBack() {
	if len(ui.navigationStack) <= 1 {
		return
	}

	if ui.currentScreen != nil {
		ui.currentScreen.OnHide()
	}

	ui.navigationStack = ui.navigationStack[:len(ui.navigationStack)-1]

	ui.currentScreen = ui.navigationStack[len(ui.navigationStack)-1]
	ui.content.RemoveAll()
	ui.content.Add(ui.currentScreen.GetContent())
	ui.content.Refresh()

	ui.updateHeader(ui.currentScreen.GetTitle())

	ui.currentScreen.OnShow()
}

func (ui *UIManager) toggleTheme() {
	if ui.settings.Theme == "dark" {
		ui.settings.Theme = "light"
		ui.app.Settings().SetTheme(theme.LightTheme())
	} else {
		ui.settings.Theme = "dark"
		ui.app.Settings().SetTheme(theme.DarkTheme())
	}

	settings.Save(ui.settings)
	ui.window.Canvas().Refresh(ui.window.Canvas().Content())
}

func (ui *UIManager) updateHeader(title string) {
	ui.window.SetTitle(title)

	if len(ui.headerBar.Objects) >= 3 {
		if backBtn, ok := ui.headerBar.Objects[1].(*widget.Button); ok {
			if len(ui.navigationStack) > 1 {
				backBtn.Show()
			} else {
				backBtn.Hide()
			}
		}
	}

	ui.headerBar.Refresh()
}

func (ui *UIManager) ShowBoardThreads(board *models.Board) {
	threadsScreen := NewThreadsScreen(ui, board)
	ui.ShowScreen(threadsScreen)
}

func (ui *UIManager) ShowThreadDetail(board *models.Board, thread *models.Thread) {
	threadScreen := NewThreadDetailScreen(ui, board, thread)
	ui.ShowScreen(threadScreen)
}

func (ui *UIManager) PushScreen(screen Screen) {
	ui.ShowScreen(screen)
}

func (ui *UIManager) GetAPIClient() *api.Client {
	return ui.apiClient
}

func (ui *UIManager) GetWindow() fyne.Window {
	return ui.window
}

func (ui *UIManager) ShowError(title, message string) {
	var dialog *widget.PopUp
	dialog = widget.NewModalPopUp(
		container.NewVBox(
			widget.NewLabel(title),
			widget.NewLabel(""),
			widget.NewLabel(message),
			widget.NewLabel(""),
			widget.NewButton("OK", func() {
				dialog.Hide()
			}),
		),
		ui.window.Canvas(),
	)
	dialog.Show()
}

func (ui *UIManager) ShowInfo(title, message string) {
	var dialog *widget.PopUp
	dialog = widget.NewModalPopUp(
		container.NewVBox(
			widget.NewLabel(title),
			widget.NewLabel(""),
			widget.NewLabel(message),
			widget.NewLabel(""),
			widget.NewButton("OK", func() {
				dialog.Hide()
			}),
		),
		ui.window.Canvas(),
	)
	dialog.Show()
}

func (ui *UIManager) ShowInfoDialog() {
	var dialog *widget.PopUp
	
	content := container.NewVBox(
		widget.NewLabel("Информация о НЕОЖИДАНЫХ проблемах"),
		widget.NewLabel(""),
		widget.NewLabel("Если тебя направили сюда, то значит\nты попал на НЕИЗВЕДАННЫЕ ТЕРРИТОРИИ"),
		widget.NewLabel("ДА ДА, не ослышались, это не ошибка,\nэто особенность"),
		widget.NewLabel("Увы, разработчик имиджборда\nвставил палки в колеса"),
		widget.NewLabel("И без доната ему, например,\nпостинг работать не будет"),
		widget.NewLabel(""),
		widget.NewLabel("Увы, постинг не работает без доната"),
		widget.NewLabel("а разработчик боится что на его сайте\nбудут спам"),
		widget.NewLabel("Вкратце - на сайте работает капча"),
		widget.NewLabel("а наличие пасскода ее для вас отключает"),
		widget.NewLabel("увы, конфет много,\nно на всех не хватит"),
		widget.NewLabel(""),
		widget.NewButton("Закрыть", func() {
			dialog.Hide()
		}),
	)
	
	dialog = widget.NewModalPopUp(content, ui.window.Canvas())
	dialog.Show()
}

func (ui *UIManager) GetSettings() *settings.Settings {
	return ui.settings
}

func (ui *UIManager) SaveSettings() error {
	return settings.Save(ui.settings)
}

func (ui *UIManager) RefreshCurrentScreen() {
	if ui.currentScreen != nil {
		ui.currentScreen.OnShow()
	}
}

func (ui *UIManager) ClearCacheForBoard(boardCode string) {
	cacheKey := "threads_" + boardCode
	cache.GetCache().Delete(cacheKey)
}

func (ui *UIManager) ClearCacheForThread(threadID int) {
	commentsKey := fmt.Sprintf("comments_%d", threadID)
	threadDetailKey := fmt.Sprintf("thread_detail_%d", threadID)
	
	cache.GetCache().Delete(commentsKey)
	cache.GetCache().Delete(threadDetailKey)
}

func (ui *UIManager) GetCurrentScreen() Screen {
	return ui.currentScreen
}

func (ui *UIManager) SetLastBoard(boardCode string) {
	ui.settings.LastBoard = boardCode
	ui.SaveSettings()
}

func (ui *UIManager) GetLastBoard() string {
	return ui.settings.LastBoard
}

func (ui *UIManager) GetPasscode() string {
	return ui.settings.Passcode
}

func (ui *UIManager) GetKey() string {
	return ui.settings.Key
}

func (ui *UIManager) ShowAbout() {
	aboutWindow := ui.app.NewWindow("Об аппке")
	aboutWindow.Resize(fyne.NewSize(400, 300))

	content := container.NewVBox(
		widget.NewLabel("MobileMkch"),
		widget.NewLabel("Мобильный клиент для мкача"),
		widget.NewSeparator(),
		widget.NewLabel("Версия: 3.0.0-alpha (Always in alpha lol)"),
		widget.NewLabel("Автор: w^x (лейн, платон, а похуй как угодно)"),
		widget.NewLabel("Разработано с ❤️ на Go + Fyne"),
	)

	closeButton := widget.NewButton("Закрыть", func() {
		aboutWindow.Close()
	})
	content.Add(closeButton)

	aboutWindow.SetContent(content)
	aboutWindow.Show()
}
