package api

import (
	"encoding/json"
	"net/http"
	"sync"

	"github.com/muyue/muyue/internal/installer"
	"github.com/muyue/muyue/internal/scanner"
	"github.com/muyue/muyue/internal/updater"
)

func (s *Server) handleUpdates(w http.ResponseWriter, r *http.Request) {
	result := scanner.ScanSystem()
	statuses := updater.CheckUpdates(result)
	type updateInfo struct {
		Tool        string `json:"tool"`
		Current     string `json:"current"`
		Latest      string `json:"latest"`
		NeedsUpdate bool   `json:"needsUpdate"`
		Error       string `json:"error,omitempty"`
	}
	updates := make([]updateInfo, len(statuses))
	for i, u := range statuses {
		updates[i] = updateInfo{
			Tool:        u.Tool,
			Current:     u.Current,
			Latest:      u.Latest,
			NeedsUpdate: u.NeedsUpdate,
			Error:       u.Error,
		}
	}
	writeJSON(w, map[string]interface{}{
		"updates": updates,
	})
}

func (s *Server) handleInstall(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		writeError(w, "POST only", http.StatusMethodNotAllowed)
		return
	}
	var body struct {
		Tools []string `json:"tools"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		writeError(w, err.Error(), http.StatusBadRequest)
		return
	}
	if len(body.Tools) == 0 {
		writeError(w, "no tools specified", http.StatusBadRequest)
		return
	}

	results := make([]installer.InstallResult, len(body.Tools))
	var wg sync.WaitGroup
	var mu sync.Mutex

	for i, tool := range body.Tools {
		wg.Add(1)
		go func(idx int, name string) {
			defer wg.Done()
			inst := installer.New(s.config)
			res := inst.InstallTool(name)
			mu.Lock()
			results[idx] = res
			mu.Unlock()
		}(i, tool)
	}

	wg.Wait()

	writeJSON(w, map[string]interface{}{
		"status":  "done",
		"tools":   body.Tools,
		"results": results,
	})
}

func (s *Server) handleRunUpdate(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		writeError(w, "POST only", http.StatusMethodNotAllowed)
		return
	}
	var body struct {
		Tool string `json:"tool"`
	}
	if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
		writeError(w, "invalid request body", http.StatusBadRequest)
		return
	}

	result := scanner.ScanSystem()
	statuses := updater.CheckUpdates(result)

	if body.Tool != "" {
		for _, u := range statuses {
			if u.Tool == body.Tool && u.NeedsUpdate {
				updater.RunAutoUpdate([]updater.UpdateStatus{u})
			}
		}
		writeJSON(w, map[string]string{"status": "ok", "tool": body.Tool})
		return
	}

	needsUpdate := make([]updater.UpdateStatus, 0)
	for _, u := range statuses {
		if u.NeedsUpdate {
			needsUpdate = append(needsUpdate, u)
		}
	}
	if len(needsUpdate) > 0 {
		updater.RunAutoUpdate(needsUpdate)
	}
	writeJSON(w, map[string]interface{}{
		"status":  "ok",
		"updated": len(needsUpdate),
	})
}
