package commands

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/urfave/cli/v2"

	"github.com/photoprism/photoprism/internal/config"
	"github.com/photoprism/photoprism/internal/photoprism/get"
)

// AuthJWTKeysCommand groups JWT key management helpers.
var AuthJWTKeysCommand = &cli.Command{
	Name:  "keys",
	Usage: "JWT signing key helpers",
	Subcommands: []*cli.Command{
		AuthJWTKeysListCommand,
	},
}

// AuthJWTKeysListCommand lists JWT signing keys.
var AuthJWTKeysListCommand = &cli.Command{
	Name:      "ls",
	Usage:     "Lists JWT signing keys",
	Aliases:   []string{"list"},
	ArgsUsage: "",
	Flags: []cli.Flag{
		JsonFlag(),
	},
	Action: authJWTKeysListAction,
}

// authJWTKeysListAction lists portal signing keys with metadata.
func authJWTKeysListAction(ctx *cli.Context) error {
	return CallWithDependencies(ctx, func(conf *config.Config) error {
		if err := requirePortal(conf); err != nil {
			return err
		}

		manager := get.JWTManager()
		if manager == nil {
			return cli.Exit(errors.New("jwt manager not available"), 1)
		}

		keys := manager.AllKeys()
		active, _ := manager.ActiveKey()
		activeKid := ""
		if active != nil {
			activeKid = active.Kid
		}

		type keyInfo struct {
			Kid       string `json:"kid"`
			CreatedAt string `json:"createdAt"`
			NotAfter  string `json:"notAfter,omitempty"`
			Active    bool   `json:"active"`
		}

		rows := make([]keyInfo, 0, len(keys))
		for _, k := range keys {
			info := keyInfo{Kid: k.Kid, Active: k.Kid == activeKid}
			if k.CreatedAt > 0 {
				info.CreatedAt = time.Unix(k.CreatedAt, 0).UTC().Format(time.RFC3339)
			}
			if k.NotAfter > 0 {
				info.NotAfter = time.Unix(k.NotAfter, 0).UTC().Format(time.RFC3339)
			}
			rows = append(rows, info)
		}

		if ctx.Bool("json") {
			payload := map[string]any{
				"keys": rows,
			}
			return printJSON(payload)
		}

		if len(rows) == 0 {
			fmt.Println()
			fmt.Println("No signing keys found.")
			fmt.Println()
			return nil
		}

		fmt.Println()
		fmt.Println("JWT signing keys:")
		for _, row := range rows {
			stat := ""
			if row.Active {
				stat = " (active)"
			}
			parts := []string{fmt.Sprintf("KID: %s%s", row.Kid, stat)}
			if row.CreatedAt != "" {
				parts = append(parts, fmt.Sprintf("created %s", row.CreatedAt))
			}
			if row.NotAfter != "" {
				parts = append(parts, fmt.Sprintf("expires %s", row.NotAfter))
			}
			fmt.Printf("- %s\n", strings.Join(parts, ", "))
		}
		fmt.Println()
		return nil
	})
}
