package server

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"

	rm "github.com/tidbcloud/aws-shared-provider/pkg/tidbworker/resourcemanager/types"
	"github.com/tidbcloud/aws-shared-provider/pkg/utils/tidb"
)

func (s *Server) registerDebug() {
	s.mux.HandleFunc("/debug/get-pools", s.getPools)
	s.mux.HandleFunc("/debug/get-standby-workers", s.getStandbyWorkers)
	s.mux.HandleFunc("/debug/activate-worker", s.activateWorker)
	s.mux.HandleFunc("/debug/recycle-worker", s.recycleWorker)
}

func (s *Server) getPools(w http.ResponseWriter, r *http.Request) {
	pools, err := s.manager.GetPools()
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to get pools: %v", err), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(pools); err != nil {
		http.Error(w, fmt.Sprintf("failed to encode response: %v", err), http.StatusInternalServerError)
		return
	}
}

func (s *Server) getStandbyWorkers(w http.ResponseWriter, r *http.Request) {
	pool := r.URL.Query().Get("pool")
	if pool == "" {
		http.Error(w, "pool is required", http.StatusBadRequest)
		return
	}
	workers, err := s.manager.GetStandbyWorkers(rm.WorkerPool(pool))
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to get standby workers: %v", err), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	if err := json.NewEncoder(w).Encode(workers); err != nil {
		http.Error(w, fmt.Sprintf("failed to encode response: %v", err), http.StatusInternalServerError)
		return
	}
}

func (s *Server) activateWorker(w http.ResponseWriter, r *http.Request) {
	pool := r.URL.Query().Get("pool")
	if pool == "" {
		http.Error(w, "pool is required", http.StatusBadRequest)
		return
	}
	worker := r.URL.Query().Get("worker")
	if worker == "" {
		http.Error(w, "worker is required", http.StatusBadRequest)
		return
	}
	var activateRequest tidb.ActivateRequest
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to read request body: %v", err), http.StatusInternalServerError)
		return
	}
	if err := json.Unmarshal(body, &activateRequest); err != nil {
		http.Error(w, fmt.Sprintf("failed to unmarshal request body: %v", err), http.StatusBadRequest)
		return
	}

	err = s.manager.ActivateWorker(s.ctx, rm.WorkerPool(pool), rm.Worker(worker), activateRequest)
	if err != nil {
		http.Error(w, fmt.Sprintf("failed to activate worker: %v", err), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
}

func (s *Server) recycleWorker(w http.ResponseWriter, r *http.Request) {
	pool := r.URL.Query().Get("pool")
	if pool == "" {
		http.Error(w, "pool is required", http.StatusBadRequest)
		return
	}
	worker := r.URL.Query().Get("worker")
	if worker == "" {
		http.Error(w, "worker is required", http.StatusBadRequest)
		return
	}
	keyspace := r.URL.Query().Get("keyspace")
	if err := s.manager.RecycleWorker(s.ctx, rm.WorkerPool(pool), rm.Worker(worker), keyspace); err != nil {
		http.Error(w, fmt.Sprintf("failed to recycle worker: %v", err), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
}
