package main

import (
	"image/color"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

type uiParts struct {
	outKey     *widget.Entry
	msg        *widget.Entry
	peer       *widget.Entry
	cipherOut  *widget.Entry
	payload    *widget.Entry
	plainOut   *widget.Entry
	toastLabel *widget.Label
}

func buildEntries() *uiParts {
	p := &uiParts{
		outKey:     widget.NewMultiLineEntry(),
		msg:        widget.NewMultiLineEntry(),
		peer:       widget.NewMultiLineEntry(),
		cipherOut:  widget.NewMultiLineEntry(),
		payload:    widget.NewMultiLineEntry(),
		plainOut:   widget.NewMultiLineEntry(),
		toastLabel: widget.NewLabel(""),
	}
	p.outKey.SetPlaceHolder("Veřejný klíč / certifikát…")
	p.msg.SetPlaceHolder("Sem napiš zprávu…")
	p.peer.SetPlaceHolder("-----BEGIN PUBLIC KEY----- … nebo CERTIFICATE …")
	p.cipherOut.SetPlaceHolder(`{"ek":"…","n":"…","ct":"…"}`)
	p.payload.SetPlaceHolder(`{"ek":"…","n":"…","ct":"…"}`)
	p.plainOut.SetPlaceHolder("Dešifrovaná zpráva…")
	// Zvýšení výšky (více řádků viditelně)
	p.outKey.SetMinRowsVisible(10)
	p.peer.SetMinRowsVisible(6)
	p.msg.SetMinRowsVisible(8)
	p.cipherOut.SetMinRowsVisible(8)
	p.payload.SetMinRowsVisible(8)
	p.plainOut.SetMinRowsVisible(8)
	p.toastLabel.Hide()
	return p
}

func (p *uiParts) showToast(msg string) {
	fyne.Do(func() {
		p.toastLabel.SetText(msg)
		p.toastLabel.Show()
	})
	time.AfterFunc(1500*time.Millisecond, func() {
		fyne.Do(func() {
			if p.toastLabel.Text == msg { // avoid race if overwritten
				p.toastLabel.SetText("")
				p.toastLabel.Hide()
			}
		})
	})
}

// custom fixed dark theme
type simpleTheme struct{}

func (simpleTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
	base := theme.DefaultTheme().Color(n, v)
	if n == theme.ColorNameBackground || n == theme.ColorNameButton {
		return color.NRGBA{R: 30, G: 34, B: 39, A: 255}
	}
	return base
}
func (simpleTheme) Font(st fyne.TextStyle) fyne.Resource    { return theme.DefaultTheme().Font(st) }
func (simpleTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) }
func (simpleTheme) Size(n fyne.ThemeSizeName) float32       { return theme.DefaultTheme().Size(n) }

var forceDark = true

// Build key section
func buildIdentityTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
	btnCopyPub := widget.NewButton("Copy public.pem", func() { copyClip(svc.PublicPEM(), parts) })
	btnCopyCrt := widget.NewButton("Copy identity.crt", func() { copyClip(svc.PublicCert(), parts) })
	btnShowPub := widget.NewButton("Show pub", func() { parts.outKey.SetText(svc.PublicPEM()) })
	btnShowCrt := widget.NewButton("Show crt", func() { parts.outKey.SetText(svc.PublicCert()) })
	btnClear := widget.NewButton("Clear", func() { parts.outKey.SetText("") })
	btnPaste := widget.NewButton("Paste", func() { parts.outKey.SetText(fyne.CurrentApp().Clipboard().Content()) })

	tileIdentity := buttonTile(btnCopyPub, btnCopyCrt, btnPaste, btnShowPub, btnShowCrt, btnClear)
	group := container.NewVBox(
		widget.NewLabelWithStyle("Moje identita", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
		tileIdentity,
		parts.outKey,
	)
	return container.NewVScroll(group)
}

// Helper functions separated to avoid circular dependency with encrypt.Service
// We'll adapt by passing a small facade interface if needed.

type ServiceFacade interface {
	Encrypt(msg, peer string) (string, error)
	Decrypt(json string) (string, error)
	PublicPEM() string
	PublicCert() string
}

func copyClip(s string, parts *uiParts) {
	fyne.CurrentApp().Clipboard().SetContent(s)
	parts.showToast("Zkopírováno")
}

// (Removed legacy buildEncryptSection and buildDecryptSection)

// assembleResponsive builds split view that collapses for narrow widths
// Tab: Encrypt
func buildEncryptTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
	parts.cipherOut.Disable() // read only output
	peerBtns := buttonTile(
		widget.NewButton("Paste", func() { parts.peer.SetText(fyne.CurrentApp().Clipboard().Content()) }),
		widget.NewButton("Clear", func() { parts.peer.SetText("") }),
	)
	encAction := func() {
		m := parts.msg.Text
		p := parts.peer.Text
		if m == "" || p == "" {
			parts.showToast("Chybí data")
			return
		}
		go func(msg, peer string) {
			res, err := svc.Encrypt(msg, peer)
			if err != nil {
				fyne.Do(func() { parts.cipherOut.SetText(""); parts.showToast("Chyba") })
				return
			}
			fyne.Do(func() { parts.cipherOut.SetText(res); parts.showToast("OK") })
		}(m, p)
	}
	msgBtns := buttonTile(
		widget.NewButton("Clear+Paste", func() { parts.msg.SetText(""); parts.msg.SetText(fyne.CurrentApp().Clipboard().Content()) }),
		widget.NewButton("Encrypt", encAction),
		widget.NewButton("Copy encrypted", func() { copyClip(parts.cipherOut.Text, parts) }),
	)

	group := container.NewVBox(
		widget.NewLabelWithStyle("Šifrování", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
		widget.NewLabel("Veřejný klíč příjemce"), peerBtns, parts.peer,
		widget.NewLabel("Zpráva"), msgBtns, parts.msg,
		widget.NewLabel("Výsledek"), parts.cipherOut,
	)
	return container.NewVScroll(group)
}

// Tab: Decrypt
func buildDecryptTab(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
	parts.plainOut.Disable()
	decryptAction := func() {
		pl := parts.payload.Text
		if pl == "" {
			parts.showToast("Chybí payload")
			return
		}
		go func(js string) {
			res, err := svc.Decrypt(js)
			if err != nil {
				fyne.Do(func() { parts.plainOut.SetText(""); parts.showToast("Chyba") })
				return
			}
			fyne.Do(func() { parts.plainOut.SetText(res); parts.showToast("OK") })
		}(pl)
	}
	payloadBtns := buttonTile(
		widget.NewButton("Paste+Decrypt", func() {
			clip := fyne.CurrentApp().Clipboard().Content()
			parts.payload.SetText(clip)
			decryptAction()
		}),
		// widget.NewButton("Decrypt", decryptAction),
		widget.NewButton("Clear", func() { parts.payload.SetText(""); parts.plainOut.SetText("") }),
	)
	plainBtns := buttonTile(widget.NewButton("Copy", func() { copyClip(parts.plainOut.Text, parts) }))
	group := container.NewVBox(
		widget.NewLabelWithStyle("Dešifrování", fyne.TextAlignLeading, fyne.TextStyle{Bold: true}),
		widget.NewLabel("Payload"), payloadBtns, parts.payload,
		widget.NewLabel("Výsledek"), plainBtns, parts.plainOut,
	)
	return container.NewVScroll(group)
}

func buildTabbedUI(parts *uiParts, svc ServiceFacade) fyne.CanvasObject {
	idTab := container.NewTabItem("Identita", buildIdentityTab(parts, svc))
	encTab := container.NewTabItem("Šifrování", buildEncryptTab(parts, svc))
	decTab := container.NewTabItem("Dešifrování", buildDecryptTab(parts, svc))
	tabs := container.NewAppTabs(idTab, encTab, decTab)
	tabs.SetTabLocation(container.TabLocationTop)

	// apply fixed dark theme once
	fyne.CurrentApp().Settings().SetTheme(simpleTheme{})
	prefs := fyne.CurrentApp().Preferences()
	if prefs != nil {
		idx := prefs.IntWithFallback("lastTab", 0)
		if idx >= 0 && idx < len(tabs.Items) {
			tabs.SelectIndex(idx)
		}
		// only persist lastTab now
	}
	tabs.OnSelected = func(ti *container.TabItem) {
		if prefs != nil {
			prefs.SetInt("lastTab", tabs.SelectedIndex())
		}
	}
	return container.NewBorder(nil, parts.toastLabel, nil, nil, tabs)
}

// buttonTile renders buttons above a related entry with a colored background spanning full width
func buttonTile(btns ...fyne.CanvasObject) fyne.CanvasObject {
	if len(btns) == 0 {
		return widget.NewLabel("")
	}
	cols := len(btns)
	if cols > 3 {
		cols = 3
	} // wrap into multiple rows if many
	grid := container.NewGridWithColumns(cols, btns...)
	bgColor := color.NRGBA{R: 240, G: 240, B: 245, A: 255}
	if forceDark {
		bgColor = color.NRGBA{R: 50, G: 54, B: 60, A: 255}
	}
	rect := canvas.NewRectangle(bgColor)
	rect.SetMinSize(fyne.NewSize(100, 38))
	padded := container.NewPadded(grid)
	return container.NewStack(rect, padded)
}
