package ui

import (
	"fmt"
	"log"
	"strings"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"

	"MobileMkch/models"
)

type ThreadsScreen struct {
	uiManager     *UIManager
	board         *models.Board
	content       *fyne.Container
	threads       []models.Thread
	loading       bool
	debouncer     *Debouncer
	currentPage   int
	pageSize      int
	totalPages    int
	pageContainer *fyne.Container
}

func NewThreadsScreen(uiManager *UIManager, board *models.Board) *ThreadsScreen {
	screen := &ThreadsScreen{
		uiManager: uiManager,
		board:     board,
		loading:   false,
		pageSize:  uiManager.GetSettings().PageSize,
	}

	screen.debouncer = NewDebouncer(100*time.Millisecond, func() {
		screen.displayThreads()
	})

	screen.setupContent()
	return screen
}

func (ts *ThreadsScreen) setupContent() {
	ts.content = container.NewVBox()

	header := widget.NewLabel(fmt.Sprintf("/%s/ - %s", ts.board.Code, ts.board.Description))
	header.TextStyle = fyne.TextStyle{Bold: true}
	ts.content.Add(header)

	ts.content.Add(widget.NewLabel("Загрузка тредов..."))
}

func (ts *ThreadsScreen) GetContent() fyne.CanvasObject {
	return container.NewScroll(ts.content)
}

func (ts *ThreadsScreen) GetTitle() string {
	return fmt.Sprintf("/%s/", ts.board.Code)
}

func (ts *ThreadsScreen) OnShow() {
	if !ts.loading {
		ts.loadThreads()
	}
}

func (ts *ThreadsScreen) OnHide() {
	// Ничего не делаем
}

func (ts *ThreadsScreen) loadThreads() {
	ts.loading = true

	ts.showLoading()

	go func() {
		defer func() {
			ts.loading = false
		}()

		threads, err := ts.uiManager.GetAPIClient().GetThreads(ts.board.Code)
		if err != nil {
			log.Printf("Ошибка загрузки тредов: %v", err)

			fyne.Do(func() {
				ts.showError(fmt.Sprintf("Ошибка загрузки тредов:\n%v", err))
			})
			return
		}

		ts.threads = threads

		fyne.Do(func() {
			ts.debouncer.Trigger()
		})
	}()
}

func (ts *ThreadsScreen) showLoading() {
	ts.content.RemoveAll()

	header := widget.NewLabel(fmt.Sprintf("/%s/ - %s", ts.board.Code, ts.board.Description))
	header.TextStyle = fyne.TextStyle{Bold: true}
	ts.content.Add(header)

	progressBar := widget.NewProgressBarInfinite()
	ts.content.Add(progressBar)
	progressBar.Start()

	ts.content.Add(widget.NewLabel("Загрузка тредов..."))

	ts.content.Refresh()
}

func (ts *ThreadsScreen) showError(message string) {
	ts.content.RemoveAll()

	header := widget.NewLabel(fmt.Sprintf("/%s/ - %s", ts.board.Code, ts.board.Description))
	header.TextStyle = fyne.TextStyle{Bold: true}
	ts.content.Add(header)

	errorLabel := widget.NewLabel("❌ " + message)
	errorLabel.Wrapping = fyne.TextWrapWord
	ts.content.Add(errorLabel)

	retryButton := widget.NewButton("Повторить", func() {
		ts.loadThreads()
	})
	ts.content.Add(retryButton)

	ts.content.Refresh()
}

func (ts *ThreadsScreen) displayThreads() {
	ts.content.RemoveAll()

	header := widget.NewLabel(fmt.Sprintf("/%s/ - %s", ts.board.Code, ts.board.Description))
	header.TextStyle = fyne.TextStyle{Bold: true}
	ts.content.Add(header)

	buttonsContainer := container.NewHBox()

	createThreadButton := widget.NewButton("Создать тред", func() {
		createThreadScreen := NewCreateThreadScreen(ts.uiManager, ts.board.Code)
		ts.uiManager.PushScreen(createThreadScreen)
	})
	buttonsContainer.Add(createThreadButton)

	ts.content.Add(buttonsContainer)

	if len(ts.threads) == 0 {
		ts.content.Add(widget.NewLabel("Тредов не найдено"))
		ts.content.Refresh()
		return
	}

	ts.totalPages = (len(ts.threads) + ts.pageSize - 1) / ts.pageSize
	ts.pageContainer = container.NewVBox()

	start := ts.currentPage * ts.pageSize
	end := start + ts.pageSize
	if end > len(ts.threads) {
		end = len(ts.threads)
	}

	for i := start; i < end; i++ {
		thread := &ts.threads[i]
		threadCard := ts.createThreadCard(thread)
		ts.pageContainer.Add(threadCard)
	}

	ts.addPaginationControls()

	ts.content.Add(ts.pageContainer)
	ts.content.Refresh()
}

func (ts *ThreadsScreen) createThreadCard(thread *models.Thread) fyne.CanvasObject {
	title := fmt.Sprintf("#%d: %s", thread.ID, thread.Title)

	if len(title) > 20 {
		title = title[:17] + "..."
	}

	info := fmt.Sprintf("Дата: %s",
		thread.GetCreationTime().Format("02.01.2006 15:04"))

	if thread.IsPinned() {
		info += " | 📌 Закреплён"
	}

	if rating := thread.GetRatingValue(); rating != 0 {
		info += fmt.Sprintf(" | ⭐ %d", rating)
	}

	if len(thread.Files) > 0 && ts.uiManager.GetSettings().ShowFiles {
		info += fmt.Sprintf(" | 📎 %d", len(thread.Files))
	}

	preview := thread.Text

	preview = strings.ReplaceAll(preview, "\n", " ")
	preview = strings.ReplaceAll(preview, "\r", " ")

	if len(preview) > 90 {
		maxLen := 50
		if len(preview) < maxLen {
			maxLen = len(preview)
		}
		preview = preview[:maxLen] + "..."
	}

	buttonText := fmt.Sprintf("%s\n%s\n%s", title, info, preview)

	button := widget.NewButton(buttonText, func() {
		ts.uiManager.ShowThreadDetail(ts.board, thread)
	})

	return button
}

func (ts *ThreadsScreen) RefreshThreads() {
	ts.loadThreads()
}

func (ts *ThreadsScreen) addPaginationControls() {
	if ts.totalPages <= 1 {
		return
	}

	paginationContainer := container.NewHBox()

	prevButton := widget.NewButton("←", func() {
		if ts.currentPage > 0 {
			ts.currentPage--
			ts.displayThreads()
		}
	})
	if ts.currentPage == 0 {
		prevButton.Disable()
	}
	paginationContainer.Add(prevButton)

	pageInfo := widget.NewLabel(fmt.Sprintf("Страница %d из %d", ts.currentPage+1, ts.totalPages))
	paginationContainer.Add(pageInfo)

	nextButton := widget.NewButton("→", func() {
		if ts.currentPage < ts.totalPages-1 {
			ts.currentPage++
			ts.displayThreads()
		}
	})
	if ts.currentPage >= ts.totalPages-1 {
		nextButton.Disable()
	}
	paginationContainer.Add(nextButton)

	ts.pageContainer.Add(paginationContainer)
}

func (ts *ThreadsScreen) goToPage(page int) {
	if page >= 0 && page < ts.totalPages {
		ts.currentPage = page
		ts.displayThreads()
	}
}
