// 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) newSchemesPage() tview.Primitive {
	table := tview.NewTable().
		SetBorders(false).
		SetSelectable(true, false)
	table.SetBorder(true).
		SetTitle(" [#00f0ff::b] PROVIDER SCHEMES ").
		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))

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

	selectedSchemeName := func() string {
		row, _ := table.GetSelection()
		idx := rowToIdx(row)
		schemes := a.cfg.Provider.Schemes
		if idx >= 0 && idx < len(schemes) {
			return schemes[idx].Name
		}
		return ""
	}

	rebuild := func() {
		selName := selectedSchemeName()
		table.Clear()
		schemes := a.cfg.Provider.Schemes
		for i, s := range schemes {
			nameRow := i * 2
			detailRow := nameRow + 1

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

			users := a.cfg.Provider.UsersForScheme(s.Name)
			n := len(users)
			m := 0
			for _, u := range users {
				if models := a.cachedModels(s.Name, u.Name); len(models) > 0 {
					m++
				}
			}
			table.SetCell(detailRow, 0,
				tview.NewTableCell(fmt.Sprintf("  [#808080](%d/%d) %s", m, n, s.BaseURL)).
					SetTextColor(tcell.NewHexColor(0x808080)).
					SetExpansion(1).
					SetSelectable(false),
			)
			table.SetCell(detailRow, 1,
				tview.NewTableCell("[#00f0ff]"+s.Type+"  ").
					SetAlign(tview.AlignRight).
					SetSelectable(false),
			)
		}
		if selName != "" {
			for i, s := range schemes {
				if s.Name == selName {
					table.Select(i*2, 0)
					return
				}
			}
		}
		if table.GetRowCount() > 0 {
			table.Select(0, 0)
		}
	}
	rebuild()

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

	table.SetSelectedFunc(func(row, _ int) {
		idx := rowToIdx(row)
		schemes := a.cfg.Provider.Schemes
		if idx < 0 || idx >= len(schemes) {
			return
		}
		name := schemes[idx].Name
		a.navigateTo("users", a.newUsersPage(name))
	})

	table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		row, _ := table.GetSelection()
		idx := rowToIdx(row)
		schemes := a.cfg.Provider.Schemes
		switch event.Rune() {
		case 'a':
			a.showSchemeForm(nil, func(s tuicfg.Scheme) {
				a.cfg.Provider.Schemes = append(a.cfg.Provider.Schemes, s)
				a.save()
				a.refreshModelCache(rebuild)
			})
			return nil
		case 'e':
			if idx < 0 || idx >= len(schemes) {
				return nil
			}
			origName := schemes[idx].Name
			orig := schemes[idx]
			a.showSchemeForm(&orig, func(s tuicfg.Scheme) {
				current := a.cfg.Provider.Schemes
				for i, sc := range current {
					if sc.Name == origName {
						a.cfg.Provider.Schemes[i] = s
						break
					}
				}
				a.save()
				a.refreshModelCache(func() {
					rebuild()
					for i, sc := range a.cfg.Provider.Schemes {
						if sc.Name == s.Name {
							table.Select(i*2, 0)
							break
						}
					}
				})
			})
			return nil
		case 'd':
			if idx < 0 || idx >= len(schemes) {
				return nil
			}
			name := schemes[idx].Name
			a.confirmDelete(fmt.Sprintf("scheme %q", name), func() {
				current := a.cfg.Provider.Schemes
				newSchemes := make([]tuicfg.Scheme, 0, len(current))
				for _, sc := range current {
					if sc.Name != name {
						newSchemes = append(newSchemes, sc)
					}
				}
				a.cfg.Provider.Schemes = newSchemes

				existing := a.cfg.Provider.Users
				filtered := make([]tuicfg.User, 0, len(existing))
				for _, u := range existing {
					if u.Scheme != name {
						filtered = append(filtered, u)
					}
				}
				a.cfg.Provider.Users = filtered

				a.save()
				a.refreshModelCache(rebuild)
			})
			return nil
		}
		return event
	})

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

func (a *App) showSchemeForm(existing *tuicfg.Scheme, onSave func(tuicfg.Scheme)) {
	name := ""
	baseURL := ""
	schemeType := "openai-compatible"
	title := " ADD SCHEME "

	if existing != nil {
		name = existing.Name
		baseURL = existing.BaseURL
		schemeType = existing.Type
		title = " EDIT SCHEME "
	}

	typeOptions := []string{"openai-compatible", "anthropic"}
	typeIdx := 0
	for i, t := range typeOptions {
		if t == schemeType {
			typeIdx = i
			break
		}
	}

	form := tview.NewForm()

	form.
		AddInputField("Name", name, 20, nil, func(text string) { name = text }).
		AddInputField("Base URL", baseURL, 28, nil, func(text string) { baseURL = text }).
		AddDropDown("Type", typeOptions, typeIdx, func(option string, _ int) { schemeType = option }).
		AddButton("SAVE", func() {
			if name == "" {
				a.showError("Name is required")
				return
			}
			if baseURL == "" {
				a.showError("Base URL is required")
				return
			}
			if existing == nil {
				for _, s := range a.cfg.Provider.Schemes {
					if s.Name == name {
						a.showError(fmt.Sprintf("Scheme name %q already exists", name))
						return
					}
				}
			}
			a.hideModal("scheme-form")
			onSave(tuicfg.Scheme{Name: name, BaseURL: baseURL, Type: schemeType})
		}).
		AddButton("CANCEL", func() {
			a.hideModal("scheme-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("scheme-form")
			return nil
		}
		return event
	})

	a.showModal("scheme-form", centeredForm(form, 4, 12))
}
