package orch

import (
	"fmt"
	"strings"
	"time"

	"ai-workflow-skill/internal/protocol"
	"ai-workflow-skill/internal/store"

	"github.com/spf13/cobra"
)

type waitOptions struct {
	runID          string
	eventTypesRaw  string
	afterEventID   int64
	timeoutSeconds int
}

func newWaitCmd(root *rootOptions) *cobra.Command {
	opts := &waitOptions{}

	cmd := &cobra.Command{
		Use:   "wait",
		Short: "Block until matching run-scoped task events become available",
		RunE: func(cmd *cobra.Command, args []string) error {
			ctx := cmd.Context()

			sqlDB, err := openOrchDB(ctx, root.dbPath)
			if err != nil {
				return err
			}
			defer sqlDB.Close()

			result, err := store.NewOrchStore(sqlDB).WaitForEvents(ctx, store.WaitInput{
				RunID:        opts.runID,
				EventTypes:   splitCommaList(opts.eventTypesRaw),
				AfterEventID: opts.afterEventID,
				Timeout:      time.Duration(opts.timeoutSeconds) * time.Second,
			})
			if err != nil {
				return err
			}

			resp := protocol.Success{
				OK:      true,
				Command: "wait",
				Data: map[string]any{
					"run_id":        opts.runID,
					"woke":          result.Woke,
					"next_event_id": result.NextEventID,
					"events":        result.Events,
				},
			}
			if root.json {
				return protocol.WriteJSON(cmd.OutOrStdout(), resp)
			}

			if !result.Woke {
				_, err = fmt.Fprintf(cmd.OutOrStdout(), "wait timed out after event %d\n", result.NextEventID)
				return err
			}
			for _, event := range result.Events {
				if _, err := fmt.Fprintf(cmd.OutOrStdout(), "%d\t%s\t%s\t%s\n", event.EventID, event.Type, event.TaskID, event.Summary); err != nil {
					return err
				}
			}
			return nil
		},
	}

	cmd.Flags().StringVar(&opts.runID, "run", "", "Run ID")
	cmd.Flags().StringVar(&opts.eventTypesRaw, "for", "task_ready,task_blocked,task_done,task_failed", "Comma-separated event types to wait for")
	cmd.Flags().Int64Var(&opts.afterEventID, "after-event", 0, "Only wait for events after this event ID")
	cmd.Flags().IntVar(&opts.timeoutSeconds, "timeout-seconds", 0, "Maximum time to wait before timing out")
	_ = cmd.MarkFlagRequired("run")

	return cmd
}

func splitCommaList(value string) []string {
	if strings.TrimSpace(value) == "" {
		return nil
	}

	parts := strings.Split(value, ",")
	result := make([]string, 0, len(parts))
	for _, part := range parts {
		part = strings.TrimSpace(part)
		if part == "" {
			continue
		}
		result = append(result, part)
	}
	return result
}
