package main

import (
	"fmt"

	"github.com/orchard9/rdev/internal/sdlc"
	"github.com/spf13/cobra"
)

var queryCmd = &cobra.Command{
	Use:   "query",
	Short: "Query SDLC state",
}

var queryBlockedCmd = &cobra.Command{
	Use:   "blocked",
	Short: "List all blocked items",
	RunE: func(_ *cobra.Command, _ []string) error {
		root := mustResolveRoot()

		features, err := sdlc.ListFeatures(root)
		if err != nil {
			return err
		}

		type blockedInfo struct {
			Slug     string   `json:"slug"`
			Phase    string   `json:"phase"`
			Blockers []string `json:"blockers"`
		}

		var blocked []blockedInfo
		for _, f := range features {
			if f.IsBlocked() {
				blocked = append(blocked, blockedInfo{
					Slug:     f.Slug,
					Phase:    string(f.Phase),
					Blockers: f.Blockers,
				})
			}
		}

		if jsonOutput {
			return printJSON(blocked)
		}

		if len(blocked) == 0 {
			fmt.Println("No blocked items.")
			return nil
		}

		fmt.Println("Blocked Items:")
		for _, b := range blocked {
			fmt.Printf("  %s [%s]:\n", b.Slug, b.Phase)
			for _, reason := range b.Blockers {
				fmt.Printf("    - %s\n", reason)
			}
		}
		return nil
	},
}

var queryReadyCmd = &cobra.Command{
	Use:   "ready",
	Short: "List items ready for work",
	RunE: func(_ *cobra.Command, _ []string) error {
		root := mustResolveRoot()

		state, err := sdlc.LoadState(root)
		if err != nil {
			return err
		}

		cfg, err := sdlc.LoadConfig(root)
		if err != nil {
			return err
		}

		features, err := sdlc.ListFeatures(root)
		if err != nil {
			return err
		}

		classifier := sdlc.NewClassifier()

		type readyInfo struct {
			Slug   string `json:"slug"`
			Phase  string `json:"phase"`
			Action string `json:"action"`
		}

		var ready []readyInfo
		for _, f := range features {
			if f.IsBlocked() {
				continue
			}
			cl := classifier.Classify(&sdlc.EvalContext{
				State:   state,
				Feature: f,
				Config:  cfg,
				Root:    root,
			})
			if cl.Action != sdlc.ActionIdle && cl.Action != sdlc.ActionBlocked && cl.Action != sdlc.ActionAwaitApproval {
				ready = append(ready, readyInfo{
					Slug:   f.Slug,
					Phase:  string(f.Phase),
					Action: string(cl.Action),
				})
			}
		}

		if jsonOutput {
			return printJSON(ready)
		}

		if len(ready) == 0 {
			fmt.Println("No items ready for work.")
			return nil
		}

		fmt.Println("Ready for Work:")
		for _, r := range ready {
			fmt.Printf("  %-20s [%-15s] -> %s\n", r.Slug, r.Phase, r.Action)
		}
		return nil
	},
}

var queryNeedsApprovalCmd = &cobra.Command{
	Use:   "needs-approval",
	Short: "List items awaiting approval",
	RunE: func(_ *cobra.Command, _ []string) error {
		root := mustResolveRoot()

		state, err := sdlc.LoadState(root)
		if err != nil {
			return err
		}

		cfg, err := sdlc.LoadConfig(root)
		if err != nil {
			return err
		}

		features, err := sdlc.ListFeatures(root)
		if err != nil {
			return err
		}

		classifier := sdlc.NewClassifier()

		type approvalInfo struct {
			Slug    string `json:"slug"`
			Phase   string `json:"phase"`
			Message string `json:"message"`
		}

		var pending []approvalInfo
		for _, f := range features {
			cl := classifier.Classify(&sdlc.EvalContext{
				State:   state,
				Feature: f,
				Config:  cfg,
				Root:    root,
			})
			if cl.Action == sdlc.ActionAwaitApproval {
				pending = append(pending, approvalInfo{
					Slug:    f.Slug,
					Phase:   string(f.Phase),
					Message: cl.Message,
				})
			}
		}

		if jsonOutput {
			return printJSON(pending)
		}

		if len(pending) == 0 {
			fmt.Println("No items awaiting approval.")
			return nil
		}

		fmt.Println("Awaiting Approval:")
		for _, p := range pending {
			fmt.Printf("  %-20s [%-15s] %s\n", p.Slug, p.Phase, p.Message)
		}
		return nil
	},
}

func init() {
	queryCmd.AddCommand(
		queryBlockedCmd,
		queryReadyCmd,
		queryNeedsApprovalCmd,
	)
	rootCmd.AddCommand(queryCmd)
}
