// Omnipus - Ultra-lightweight personal AI agent
// License: MIT
//
// Copyright (c) 2026 Omnipus contributors

package ui

import (
	"fmt"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"

	tuicfg "github.com/dapicom-ai/omnipus/cmd/omnipus-launcher-tui/config"
)

func (a *App) newUsersPage(schemeName string) tview.Primitive {
	table := tview.NewTable().
		SetBorders(false).
		SetSelectable(true, false)
	table.SetBorder(true).
		SetTitle(fmt.Sprintf(" [#00f0ff::b] USERS · %s ", schemeName)).
		SetTitleColor(tcell.NewHexColor(0x00f0ff)).
		SetBorderColor(tcell.NewHexColor(0x00f0ff))
	table.SetSelectedStyle(
		tcell.StyleDefault.Background(tcell.NewHexColor(0xff00ff)).Foreground(tcell.NewHexColor(0xffffff)),
	)
	table.SetBackgroundColor(tcell.NewHexColor(0x050510))

	visibleUsers := func() []tuicfg.User {
		var out []tuicfg.User
		for _, u := range a.cfg.Provider.Users {
			if u.Scheme == schemeName {
				out = append(out, u)
			}
		}
		return out
	}

	findUserGlobalIdx := func(userName string) int {
		for i, u := range a.cfg.Provider.Users {
			if u.Scheme == schemeName && u.Name == userName {
				return i
			}
		}
		return -1
	}

	rowToVisIdx := func(row int) int { return row / 2 }

	selectedUserName := func() string {
		row, _ := table.GetSelection()
		users := visibleUsers()
		visIdx := rowToVisIdx(row)
		if visIdx >= 0 && visIdx < len(users) {
			return users[visIdx].Name
		}
		return ""
	}

	rebuild := func() {
		selName := selectedUserName()
		table.Clear()
		users := visibleUsers()
		for i, u := range users {
			nameRow := i * 2
			detailRow := nameRow + 1

			table.SetCell(nameRow, 0,
				tview.NewTableCell(" "+u.Name).
					SetTextColor(tcell.NewHexColor(0xe0e0e0)).
					SetExpansion(1).
					SetSelectable(true),
			)
			table.SetCell(nameRow, 1,
				tview.NewTableCell("").
					SetSelectable(false),
			)

			models := a.cachedModels(schemeName, u.Name)
			var detailText string
			if len(models) > 0 {
				detailText = fmt.Sprintf("  [#39ff14]%d models available[-]", len(models))
			} else {
				detailText = "  [#ff2a2a]Inactive / No Access[-]"
			}
			table.SetCell(detailRow, 0,
				tview.NewTableCell(detailText).
					SetTextColor(tcell.NewHexColor(0x808080)).
					SetExpansion(1).
					SetSelectable(false),
			)
			table.SetCell(detailRow, 1,
				tview.NewTableCell("[#00f0ff]"+u.Type+"  ").
					SetAlign(tview.AlignRight).
					SetSelectable(false),
			)
		}
		if selName != "" {
			for i, u := range users {
				if u.Name == selName {
					table.Select(i*2, 0)
					return
				}
			}
		}
		if table.GetRowCount() > 0 {
			table.Select(0, 0)
		}
	}
	rebuild()

	a.refreshModelCache(rebuild)
	a.pageRefreshFns["users"] = func() { a.refreshModelCache(rebuild) }

	table.SetSelectedFunc(func(row, _ int) {
		visIdx := rowToVisIdx(row)
		users := visibleUsers()
		if visIdx < 0 || visIdx >= len(users) {
			return
		}
		uName := users[visIdx].Name
		scheme := a.cfg.Provider.SchemeByName(schemeName)
		if scheme == nil {
			a.showError(fmt.Sprintf("Scheme %q not found", schemeName))
			return
		}
		a.navigateTo("models", a.newModelsPage(schemeName, uName, scheme.BaseURL))
	})

	table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		row, _ := table.GetSelection()
		visIdx := rowToVisIdx(row)
		users := visibleUsers()
		switch event.Rune() {
		case 'a':
			a.showUserForm(schemeName, nil, func(u tuicfg.User) {
				a.cfg.Provider.Users = append(a.cfg.Provider.Users, u)
				a.save()
				a.refreshModelCache(rebuild)
			})
			return nil
		case 'e':
			if visIdx < 0 || visIdx >= len(users) {
				return nil
			}
			origName := users[visIdx].Name
			orig := a.cfg.Provider.Users[findUserGlobalIdx(origName)]
			a.showUserForm(schemeName, &orig, func(u tuicfg.User) {
				cfgIdx := findUserGlobalIdx(origName)
				if cfgIdx < 0 {
					a.showError(fmt.Sprintf("User %q no longer exists", origName))
					return
				}
				a.cfg.Provider.Users[cfgIdx] = u
				a.save()
				a.refreshModelCache(func() {
					rebuild()
					for i, usr := range visibleUsers() {
						if usr.Name == u.Name {
							table.Select(i*2, 0)
							break
						}
					}
				})
			})
			return nil
		case 'd':
			if visIdx < 0 || visIdx >= len(users) {
				return nil
			}
			uName := users[visIdx].Name
			a.confirmDelete(fmt.Sprintf("user %q", uName), func() {
				cfgIdx := findUserGlobalIdx(uName)
				if cfgIdx < 0 {
					return
				}
				all := a.cfg.Provider.Users
				a.cfg.Provider.Users = append(all[:cfgIdx], all[cfgIdx+1:]...)
				a.save()
				a.refreshModelCache(rebuild)
			})
			return nil
		}
		return event
	})

	return a.buildShell(
		"users",
		table,
		" [#00f0ff]a:[-] add  [#00f0ff]e:[-] edit  [#ff2a2a]d:[-] delete  [#39ff14]Enter:[-] models  [#ff00ff]ESC:[-] back ",
	)
}

func (a *App) showUserForm(schemeName string, existing *tuicfg.User, onSave func(tuicfg.User)) {
	name := ""
	userType := "key"
	key := ""
	title := " ADD USER "

	if existing != nil {
		name = existing.Name
		userType = existing.Type
		key = existing.Key
		title = " EDIT USER "
	}

	typeOptions := []string{"key", "OAuth"}
	typeIdx := 0
	for i, t := range typeOptions {
		if t == userType {
			typeIdx = i
			break
		}
	}

	form := tview.NewForm()
	form.
		AddInputField("Name", name, 20, nil, func(text string) { name = text }).
		AddDropDown("Type", typeOptions, typeIdx, func(option string, _ int) { userType = option }).
		AddPasswordField("Key", key, 28, '*', func(text string) { key = text }).
		AddButton("SAVE", func() {
			if name == "" {
				a.showError("Name is required")
				return
			}
			if existing == nil {
				for _, u := range a.cfg.Provider.Users {
					if u.Scheme == schemeName && u.Name == name {
						a.showError(fmt.Sprintf("User name %q already exists for this scheme", name))
						return
					}
				}
			}
			a.hideModal("user-form")
			onSave(tuicfg.User{Name: name, Scheme: schemeName, Type: userType, Key: key})
		}).
		AddButton("CANCEL", func() {
			a.hideModal("user-form")
		})

	form.SetBorder(true).
		SetTitle(" [::b]" + title + " ").
		SetTitleColor(tcell.NewHexColor(0x39ff14)).
		SetBorderColor(tcell.NewHexColor(0x00f0ff))
	form.SetBackgroundColor(tcell.NewHexColor(0x1a1a2e))
	form.SetFieldBackgroundColor(tcell.NewHexColor(0x050510))
	form.SetFieldTextColor(tcell.NewHexColor(0x00f0ff))
	form.SetLabelColor(tcell.NewHexColor(0xe0e0e0))
	form.SetButtonBackgroundColor(tcell.NewHexColor(0xff00ff))
	form.SetButtonTextColor(tcell.NewHexColor(0xffffff))
	form.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		if event.Key() == tcell.KeyEscape {
			a.hideModal("user-form")
			return nil
		}
		return event
	})

	a.showModal("user-form", centeredForm(form, 4, 13))
}
