package tui

import (
	"fmt"
	"slices"
	"strings"

	"github.com/charmbracelet/bubbles/key"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/analyzers"
	"github.com/trufflesecurity/trufflehog/v3/pkg/analyzer/config"
	"github.com/trufflesecurity/trufflehog/v3/pkg/tui/common"
	"github.com/trufflesecurity/trufflehog/v3/pkg/tui/components/textinputs"
	"github.com/trufflesecurity/trufflehog/v3/pkg/tui/styles"
)

type FormPage struct {
	Common  *common.Common
	KeyType string
	form    textinputs.Model
}

func NewFormPage(c *common.Common, keyType string) FormPage {
	var inputs []textinputs.InputConfig
	switch strings.ToLower(keyType) {
	case "twilio":
		inputs = []textinputs.InputConfig{{
			Label:    "SID",
			Key:      "sid",
			Required: true,
		}, {
			Label:       "Token",
			Key:         "key",
			Required:    true,
			RedactInput: true,
		}}
	case "shopify":
		inputs = []textinputs.InputConfig{{
			Label:       "Secret",
			Key:         "key",
			Required:    true,
			RedactInput: true,
		}, {
			Label:    "Shopify URL",
			Key:      "url",
			Required: true,
		}}
	default:
		inputs = []textinputs.InputConfig{{
			Label:       "Secret",
			Key:         "key",
			Required:    true,
			RedactInput: true,
		}}
	}

	// Always append a log file option.
	inputs = append(inputs, textinputs.InputConfig{
		Label: "Log file",
		Help:  "Log HTTP requests that analysis performs to this file",
		Key:   "log_file",
	})

	form := textinputs.New(inputs).
		SetHeader(titleStyle.Render(fmt.Sprintf("Configuring %s analyzer", keyType))).
		SetFooter("⚠️  Running TruffleHog Analyze will send a lot of requests ⚠️\n\n🚧 Please confirm you have permission to run TruffleHog Analyze against this secret 🚧").
		SetSubmitMsg("Run TruffleHog Analyze")
	return FormPage{
		Common:  c,
		KeyType: keyType,
		form:    form,
	}
}

func (FormPage) Init() tea.Cmd {
	return nil
}

func (ui FormPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	// TODO: Check form focus.
	if msg, ok := msg.(tea.KeyMsg); ok {
		switch {
		case key.Matches(msg, ui.Common.KeyMap.Back):
			return ui.PrevPage()
		}
	}
	if _, ok := msg.(textinputs.SelectNextMsg); ok {
		values := make(map[string]string)
		for k, v := range ui.form.GetInputs() {
			values[k] = v.Value
		}
		secretInfoCmd := func() tea.Msg {
			// TODO: Set Config
			logFile := values["log_file"]
			cfg := config.Config{
				LogFile:        logFile,
				LoggingEnabled: logFile != "",
			}
			return SecretInfo{Cfg: &cfg, Parts: values}
		}
		return nil, secretInfoCmd
	}
	form, cmd := ui.form.Update(msg)
	ui.form = form.(textinputs.Model)
	return ui, cmd
}

func (ui FormPage) View() string {
	return styles.AppStyle.Render(ui.form.View())
}

func (ui FormPage) PrevPage() (tea.Model, tea.Cmd) {
	page := NewKeyTypePage(ui.Common)
	// Select what was previously selected.
	index, ok := slices.BinarySearch(analyzers.AvailableAnalyzers, ui.KeyType)
	if !ok {
		// Should be impossible.
		index = 0
	}
	page.list.Select(index)
	return page, nil
}
