package main

import (
	"flag"
	"fmt"
	"os/exec"
	"strings"
)

// runSeedJiraData provisions (or updates) the Jira module that pushes kanban
// changes to soporte-anjana.atlassian.net, project DATA, board 33.
//
// Credentials are read from `pass` so they never appear in argv or env. The
// API token, email, and domain are loaded from the canonical entries:
//
//	pass jira/anjana/api-token
//	pass jira/anjana/email
//	pass jira/anjana/domain
//
// Defaults can be overridden with flags (project, board, name, filter).
//
// Idempotent: if a module with the same name already exists, its config is
// rewritten (encrypted at rest by saveModule). The kanban module key
// (KANBAN_MODULE_KEY env var) must be set — the same value the running server
// uses, otherwise the server cannot decrypt the secrets we wrote.
func runSeedJiraData(args []string) error {
	fs := flag.NewFlagSet("kanban seed-jira-data", flag.ContinueOnError)
	dbPath := fs.String("db", "operations.db", "SQLite database path")
	name := fs.String("name", "Jira DATA", "Module display name (also used as upsert key)")
	project := fs.String("project", "DATA", "Jira project key (e.g. DATA)")
	board := fs.Int("board", 33, "Jira board id (Agile board; informational + validated at /test)")
	filter := fs.String("event-filter", "card.created,card.updated,card.moved,message.created",
		"Comma-separated event types this module subscribes to")
	enabled := fs.Bool("enabled", true, "Start with module enabled (true) or disabled (false)")
	passEntry := fs.String("pass-prefix", "jira/anjana", "pass entry prefix; reads ${prefix}/{email,api-token,domain}")
	if err := fs.Parse(args); err != nil {
		return err
	}

	email, err := passShow(*passEntry + "/email")
	if err != nil {
		return fmt.Errorf("read email from pass: %w", err)
	}
	token, err := passShow(*passEntry + "/api-token")
	if err != nil {
		return fmt.Errorf("read api-token from pass: %w", err)
	}
	domain, err := passShow(*passEntry + "/domain")
	if err != nil {
		return fmt.Errorf("read domain from pass: %w", err)
	}
	baseURL := "https://" + strings.TrimSpace(domain)

	db, err := openDB(*dbPath)
	if err != nil {
		return fmt.Errorf("open db: %w", err)
	}
	defer db.Close()

	// Default mapping for our setup: Kanban columns → Jira `Epicas en Data` board (33)
	// statuses. Operator can edit via the Modulos UI once the row exists.
	statusMap := map[string]string{
		"HACIENDO 🚧":       "In Progress",
		"PNDNT FEEDBACK ▶️": "IMPLEMENTADO",
		"HECHO ✅":          "Done",
		"IDEAS 💡":          "CREADO",
		"DEUDA TÉCNICA 🔄":  "To Do",
		"Bloqueadas":        "In Progress",
	}
	labelsMap := map[string][]string{
		"Bloqueadas": {"blocked"},
	}

	cfg := JSONValue{
		"base_url":    baseURL,
		"email":       email,
		"api_token":   token,
		"project_key": *project,
		"board_id":    *board,
		"issue_type":  "Tarea Técnica",
		"status_map":  statusMap,
		"labels_map":  labelsMap,
	}

	// Upsert by name. Module name is the human-friendly identifier; we treat
	// it as unique for the purposes of seeding so re-running this command does
	// not duplicate the row.
	mods, err := db.listModulesAll()
	if err != nil {
		return fmt.Errorf("list modules: %w", err)
	}
	var existing *Module
	for i := range mods {
		if mods[i].Name == *name {
			existing = &mods[i]
			break
		}
	}

	if existing != nil {
		existing.Kind = "jira"
		existing.Enabled = *enabled
		existing.EventFilter = splitCSV(*filter)
		existing.Config = cfg
		if err := db.saveModule(existing); err != nil {
			return fmt.Errorf("update module: %w", err)
		}
		fmt.Printf("updated module %q (id=%s)\n", existing.Name, existing.ID)
		return nil
	}

	m := &Module{
		Name:        *name,
		Kind:        "jira",
		Enabled:     *enabled,
		EventFilter: splitCSV(*filter),
		Config:      cfg,
	}
	if err := db.saveModule(m); err != nil {
		return fmt.Errorf("create module: %w", err)
	}
	fmt.Printf("created module %q (id=%s)\n", m.Name, m.ID)
	fmt.Printf("project: %s  board: %d  base_url: %s  email: %s\n",
		*project, *board, baseURL, email)
	fmt.Println("\nnext steps:")
	fmt.Println("  1. Edit status_map in the Modulos UI: map kanban column names to Jira statuses")
	fmt.Println("     (e.g. \"In Progress\" → \"In Progress\", \"Done\" → \"Done\")")
	fmt.Println("  2. Click \"Test\" in the UI to verify board 33 belongs to project DATA")
	fmt.Println("  3. Move a card in kanban — push should hit Jira REST API")
	return nil
}

// passShow shells out to pass(1) to read a secret. We do not cache or print
// the value; just trim trailing whitespace before returning.
func passShow(entry string) (string, error) {
	out, err := exec.Command("pass", "show", entry).Output()
	if err != nil {
		return "", fmt.Errorf("pass show %s: %w", entry, err)
	}
	return strings.TrimSpace(string(out)), nil
}
