package cmd

import (
	"fmt"
	"os"
	"text/tabwriter"
	"time"

	"github.com/spf13/cobra"
	"github.com/tidbcloud/investibook/cli/internal/api"
)

var sourcesCmd = &cobra.Command{
	Use:   "sources",
	Short: "Manage workspace sources",
}

var sourcesListCmd = &cobra.Command{
	Use:     "list",
	Short:   "List all sources",
	Aliases: []string{"ls"},
	Run: func(cmd *cobra.Command, args []string) {
		client, cfg := mustClient()
		wsID := mustWorkspace(cfg)
		sources, err := client.GetSources(wsID)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			os.Exit(1)
		}
		if len(sources) == 0 {
			fmt.Println("No sources in workspace.")
			return
		}
		w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
		fmt.Fprintln(w, "ID\tTYPE\tNAME\tSTATUS")
		for _, s := range sources {
			status := s.Status
			if status == "" {
				status = "ready"
			}
			fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", s.ID, s.Type, s.Name, status)
		}
		w.Flush()
	},
}

var sourcesAddCmd = &cobra.Command{
	Use:   "add",
	Short: "Add a source to the workspace",
}

var sourcesAddJiraIssueCmd = &cobra.Command{
	Use:   "jira-issues <issue-id>",
	Short: "Add a Jira issue source and prepare diagnostic data",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		client, cfg := mustClient()
		wsID := mustWorkspace(cfg)
		issueID := args[0]

		fmt.Printf("Preparing Jira issue source %s...\n", issueID)
		prepRes, err := client.PrepareSource(issueID, wsID)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			os.Exit(1)
		}

		for {
			status, err := client.GetPrepareStatus(prepRes.TaskID)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error polling status: %v\n", err)
				os.Exit(1)
			}
			switch status.Status {
			case "completed":
				fmt.Println("  Source ready.")
				if status.Message != "" {
					fmt.Printf("  %s\n", status.Message)
				}
				// Persist the source record so the UI can display it.
				existing, err := client.GetSources(wsID)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Warning: could not read sources: %v\n", err)
				} else {
					// Skip if already present (idempotent).
					alreadyAdded := false
					for _, s := range existing {
						if s.IssueID == issueID {
							alreadyAdded = true
							break
						}
					}
					if !alreadyAdded {
						issueDir := status.IssueDir
						if issueDir == "" {
							issueDir = "issues/" + issueID
						}
						newSource := api.Source{
							Type:     "jira_issue",
							Name:     issueID,
							IssueID:  issueID,
							IssueDir: issueDir,
							Status:   "ready",
						}
						if _, err := client.AddSource(wsID, newSource); err != nil {
							fmt.Fprintf(os.Stderr, "Warning: could not save source: %v\n", err)
						}
					}
				}
				fmt.Println("Report and Anomaly artifacts created in Studio.")
				return
			case "error":
				fmt.Fprintf(os.Stderr, "  Preparation failed: %s\n", status.Error)
				os.Exit(1)
			default:
				if status.Message != "" {
					fmt.Printf("  ... %s\n", status.Message)
				}
				time.Sleep(2 * time.Second)
			}
		}
	},
}

var sourcesRemoveCmd = &cobra.Command{
	Use:   "remove <source-id>",
	Short: "Remove a source from the workspace",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		client, cfg := mustClient()
		wsID := mustWorkspace(cfg)
		srcID := args[0]

		if err := client.DeleteSource(wsID, srcID); err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("Removed source %s\n", srcID)
	},
}

func init() {
	sourcesAddCmd.AddCommand(sourcesAddJiraIssueCmd)
	sourcesCmd.AddCommand(sourcesListCmd)
	sourcesCmd.AddCommand(sourcesAddCmd)
	sourcesCmd.AddCommand(sourcesRemoveCmd)
	rootCmd.AddCommand(sourcesCmd)
}
