package cmd

import (
	"fmt"

	"code.gitea.io/sdk/gitea"
	"forgejo.zerova.net/public/fj/internal/api"
	"forgejo.zerova.net/public/fj/internal/config"
	"forgejo.zerova.net/public/fj/internal/iostreams"
	"github.com/spf13/cobra"
)

var prChecksCmd = &cobra.Command{
	Use:   "checks <number>",
	Short: "Show CI status checks for a pull request",
	Long:  "Show the status of CI checks for a pull request.",
	Example: `  # Show checks for PR #5
  fj pr checks 5

  # Output as JSON
  fj pr checks 5 --json`,
	Args: cobra.ExactArgs(1),
	RunE: runPRChecks,
}

func init() {
	prCmd.AddCommand(prChecksCmd)
	prChecksCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format")
	addJSONFlags(prChecksCmd, "Output checks as JSON")
}

func runPRChecks(cmd *cobra.Command, args []string) error {
	repo, _ := cmd.Flags().GetString("repo")
	prNumber, err := parseIssueArg(args[0])
	if err != nil {
		return fmt.Errorf("invalid pull request number: %w", err)
	}

	owner, name, err := parseRepo(repo)
	if err != nil {
		return err
	}

	cfg, err := config.Load()
	if err != nil {
		return err
	}

	client, err := api.NewClientFromConfig(cfg, "", getDetectedHost(), getCwd())
	if err != nil {
		return err
	}

	ios.StartSpinner("Fetching pull request...")
	pr, _, err := client.GetPullRequest(owner, name, prNumber)
	if err != nil {
		ios.StopSpinner()
		return fmt.Errorf("failed to get pull request: %w", err)
	}

	statuses, _, err := client.ListStatuses(owner, name, pr.Head.Sha, gitea.ListStatusesOption{})
	ios.StopSpinner()
	if err != nil {
		return fmt.Errorf("failed to get commit statuses: %w", err)
	}

	if wantJSON(cmd) {
		return outputJSON(cmd, statuses)
	}

	if len(statuses) == 0 {
		fmt.Fprintf(ios.Out, "No status checks found for PR #%d\n", prNumber)
		return nil
	}

	cs := ios.ColorScheme()
	tp := ios.NewTablePrinter()
	tp.AddHeader("STATUS", "CONTEXT", "DESCRIPTION")
	for _, s := range statuses {
		status := formatCheckStatus(s.State, cs)
		tp.AddRow(status, s.Context, s.Description)
	}
	return tp.Render()
}

func formatCheckStatus(state gitea.StatusState, cs *iostreams.ColorScheme) string {
	switch state {
	case gitea.StatusSuccess:
		return cs.Green("pass")
	case gitea.StatusFailure, gitea.StatusError:
		return cs.Red("fail")
	case gitea.StatusPending:
		return cs.Yellow("pending")
	case gitea.StatusWarning:
		return cs.Yellow("warn")
	default:
		return string(state)
	}
}
