package handlers import ( "aggios-app/backend/internal/domain" "aggios-app/backend/internal/repository" "aggios-app/backend/internal/api/middleware" "encoding/json" "log" "net/http" "github.com/google/uuid" "github.com/gorilla/mux" ) type SolutionHandler struct { repo *repository.SolutionRepository } func NewSolutionHandler(repo *repository.SolutionRepository) *SolutionHandler { return &SolutionHandler{repo: repo} } // ==================== CRUD SOLUTIONS (SUPERADMIN) ==================== func (h *SolutionHandler) CreateSolution(w http.ResponseWriter, r *http.Request) { var solution domain.Solution if err := json.NewDecoder(r.Body).Decode(&solution); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "Invalid request body", "message": err.Error(), }) return } solution.ID = uuid.New().String() if err := h.repo.CreateSolution(&solution); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to create solution", "message": err.Error(), }) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]interface{}{ "solution": solution, }) } func (h *SolutionHandler) GetAllSolutions(w http.ResponseWriter, r *http.Request) { solutions, err := h.repo.GetAllSolutions() if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to fetch solutions", "message": err.Error(), }) return } if solutions == nil { solutions = []domain.Solution{} } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "solutions": solutions, }) } func (h *SolutionHandler) GetSolution(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) solutionID := vars["id"] solution, err := h.repo.GetSolutionByID(solutionID) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) json.NewEncoder(w).Encode(map[string]string{ "error": "Solution not found", "message": err.Error(), }) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "solution": solution, }) } func (h *SolutionHandler) UpdateSolution(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) solutionID := vars["id"] var solution domain.Solution if err := json.NewDecoder(r.Body).Decode(&solution); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "Invalid request body", "message": err.Error(), }) return } solution.ID = solutionID if err := h.repo.UpdateSolution(&solution); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to update solution", "message": err.Error(), }) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{ "message": "Solution updated successfully", }) } func (h *SolutionHandler) DeleteSolution(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) solutionID := vars["id"] if err := h.repo.DeleteSolution(solutionID); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to delete solution", "message": err.Error(), }) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{ "message": "Solution deleted successfully", }) } // ==================== TENANT SOLUTIONS (AGENCY) ==================== func (h *SolutionHandler) GetTenantSolutions(w http.ResponseWriter, r *http.Request) { tenantID, _ := r.Context().Value(middleware.TenantIDKey).(string) log.Printf("🔍 GetTenantSolutions: tenantID=%s", tenantID) if tenantID == "" { log.Printf("❌ GetTenantSolutions: Missing tenant_id") w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "Missing tenant_id", }) return } solutions, err := h.repo.GetTenantSolutions(tenantID) if err != nil { log.Printf("❌ GetTenantSolutions: Error fetching solutions: %v", err) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to fetch solutions", "message": err.Error(), }) return } log.Printf("✅ GetTenantSolutions: Found %d solutions for tenant %s", len(solutions), tenantID) if solutions == nil { solutions = []domain.Solution{} } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "solutions": solutions, }) } // ==================== PLAN SOLUTIONS ==================== func (h *SolutionHandler) GetPlanSolutions(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) planID := vars["plan_id"] solutions, err := h.repo.GetPlanSolutions(planID) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to fetch plan solutions", "message": err.Error(), }) return } if solutions == nil { solutions = []domain.Solution{} } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "solutions": solutions, }) } func (h *SolutionHandler) SetPlanSolutions(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) planID := vars["plan_id"] var req struct { SolutionIDs []string `json:"solution_ids"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "error": "Invalid request body", "message": err.Error(), }) return } if err := h.repo.SetPlanSolutions(planID, req.SolutionIDs); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "error": "Failed to update plan solutions", "message": err.Error(), }) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{ "message": "Plan solutions updated successfully", }) }