package cmd

import (
	"fmt"
	"log/slog"

	"github.com/spf13/cobra"

	"github.com/tidbcloud/AgentTeam/desktop/internal/daemon"
	"github.com/tidbcloud/AgentTeam/desktop/internal/doctor"
)

// doctorCmd runs diagnostic checks on the agentteam installation.
var doctorCmd = &cobra.Command{
	Use:   "doctor",
	Short: "Run diagnostics to verify installation",
	Long: `Run diagnostic checks on the agentteam installation to verify that
the system is correctly configured and ready to use.

Checks performed:
  - Configuration directory exists and is writable
  - Configuration file is valid
  - All configured runtimes have their binaries available in PATH
  - Daemon process is running (if installed as a service)

Examples:
  agentteam doctor               Run all diagnostic checks
  agentteam doctor --fix-runtime  Print runtime remediation guidance`,
	RunE: func(cmd *cobra.Command, args []string) error {
		fixRuntime, _ := cmd.Flags().GetBool("fix-runtime")
		return runDoctor(fixRuntime)
	},
}

func init() {
	doctorCmd.Flags().Bool("fix-runtime", false, "show runtime remediation guidance")
}

func runDoctor(fixRuntime bool) error {
	slog.Info("running agentteam diagnostics")

	results := doctor.RunChecks(checkDaemonStatus)
	printCheckResults(results)

	if fixRuntime {
		fmt.Println()
		slog.Info("runtime auto-install is no longer supported")
		slog.Info("AgentTeam Desktop includes builtin OpenCode; reinstall or update AgentTeam Desktop if builtin OpenCode is missing")
		slog.Info("external Claude Code, Codex, or OpenCode runtimes can still be used after manual installation or PATH/binary configuration")
	}

	return nil
}

// checkDaemonStatus returns a diagnostic check result for the daemon.
func checkDaemonStatus() doctor.CheckResult {
	d := daemon.NewStatus()
	if d.Running && d.Healthy {
		return doctor.CheckResult{
			Name:   "Daemon status",
			Status: doctor.StatusPass,
			Detail: fmt.Sprintf("running (PID: %d)", d.PID),
		}
	}
	if d.Running {
		return doctor.CheckResult{
			Name:   "Daemon status",
			Status: doctor.StatusWarn,
			Detail: fmt.Sprintf("process exists but local API is unhealthy (PID: %d)", d.PID),
		}
	}
	return doctor.CheckResult{
		Name:   "Daemon status",
		Status: doctor.StatusWarn,
		Detail: "not running",
	}
}

// printCheckResults formats and prints diagnostic check results.
func printCheckResults(results []doctor.CheckResult) {
	passCount, warnCount, failCount := 0, 0, 0
	for _, r := range results {
		switch r.Status {
		case doctor.StatusPass:
			passCount++
		case doctor.StatusWarn:
			warnCount++
		case doctor.StatusFail:
			failCount++
		}
		slog.Info("check result", "name", r.Name, "status", r.Status, "detail", r.Detail)
	}

	slog.Info("diagnostics summary", "passed", passCount, "warnings", warnCount, "failed", failCount)
}
