package handler import ( "errors" "net/http" "strconv" "strings" "github.com/saveinmed/backend-go/internal/domain" "github.com/saveinmed/backend-go/internal/http/middleware" ) // CreateCompany godoc // @Summary Registro de empresas // @Description Cadastra farmácia, distribuidora ou administrador com CNPJ e licença sanitária. // @Tags Empresas // @Accept json // @Produce json // @Param company body registerCompanyRequest true "Dados da empresa" // @Success 201 {object} domain.Company // @Router /api/v1/companies [post] func (h *Handler) CreateCompany(w http.ResponseWriter, r *http.Request) { var req registerCompanyRequest if err := decodeJSON(r.Context(), r, &req); err != nil { writeError(w, http.StatusBadRequest, err) return } // Map Portuguese fields if English ones are empty if req.CorporateName == "" { req.CorporateName = req.RazaoSocial } if req.Category == "" { // Default category if not provided or map from Activity Code? // For now, use description or default if req.DescricaoAtividade != "" { req.Category = req.DescricaoAtividade } else { req.Category = "farmacia" // Default } } company := &domain.Company{ Category: req.Category, CNPJ: req.CNPJ, CorporateName: req.CorporateName, LicenseNumber: req.LicenseNumber, // Frontend might not send this yet? Latitude: req.Latitude, Longitude: req.Longitude, City: req.City, State: req.State, Phone: req.Telefone, } if err := h.svc.RegisterCompany(r.Context(), company); err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusCreated, company) } // ListCompanies godoc // @Summary Lista empresas // @Tags Empresas // @Produce json // @Success 200 {array} domain.Company // @Router /api/v1/companies [get] func (h *Handler) ListCompanies(w http.ResponseWriter, r *http.Request) { page, pageSize := parsePagination(r) filter := domain.CompanyFilter{ Category: r.URL.Query().Get("category"), Search: r.URL.Query().Get("search"), City: r.URL.Query().Get("city"), State: r.URL.Query().Get("state"), } if v := r.URL.Query().Get("is_verified"); v != "" { if b, err := strconv.ParseBool(v); err == nil { filter.IsVerified = &b } } result, err := h.svc.ListCompanies(r.Context(), filter, page, pageSize) if err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, result) } // GetCompany godoc // @Summary Obter empresa // @Tags Empresas // @Produce json // @Param id path string true "Company ID" // @Success 200 {object} domain.Company // @Failure 404 {object} map[string]string // @Router /api/v1/companies/{id} [get] func (h *Handler) GetCompany(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } company, err := h.svc.GetCompany(r.Context(), id) if err != nil { writeError(w, http.StatusNotFound, err) return } writeJSON(w, http.StatusOK, company) } // UpdateCompany godoc // @Summary Atualizar empresa // @Tags Empresas // @Accept json // @Produce json // @Param id path string true "Company ID" // @Param payload body updateCompanyRequest true "Campos para atualização" // @Success 200 {object} domain.Company // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Router /api/v1/companies/{id} [patch] func (h *Handler) UpdateCompany(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } var req updateCompanyRequest if err := decodeJSON(r.Context(), r, &req); err != nil { writeError(w, http.StatusBadRequest, err) return } company, err := h.svc.GetCompany(r.Context(), id) if err != nil { writeError(w, http.StatusNotFound, err) return } if req.Category != nil { company.Category = *req.Category } if req.CNPJ != nil { company.CNPJ = *req.CNPJ } if req.CorporateName != nil { company.CorporateName = *req.CorporateName } if req.LicenseNumber != nil { company.LicenseNumber = *req.LicenseNumber } if req.IsVerified != nil { company.IsVerified = *req.IsVerified } if req.Latitude != nil { company.Latitude = *req.Latitude } if req.Longitude != nil { company.Longitude = *req.Longitude } if req.City != nil { company.City = *req.City } if req.State != nil { company.State = *req.State } if err := h.svc.UpdateCompany(r.Context(), company); err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, company) } // DeleteCompany godoc // @Summary Remover empresa // @Tags Empresas // @Param id path string true "Company ID" // @Success 204 "" // @Failure 400 {object} map[string]string // @Failure 404 {object} map[string]string // @Router /api/v1/companies/{id} [delete] func (h *Handler) DeleteCompany(w http.ResponseWriter, r *http.Request) { id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } if err := h.svc.DeleteCompany(r.Context(), id); err != nil { writeError(w, http.StatusBadRequest, err) return } w.WriteHeader(http.StatusNoContent) } // VerifyCompany godoc // @Summary Verificar empresa // @Tags Empresas // @Security BearerAuth // @Param id path string true "Company ID" // @Success 200 {object} domain.Company // @Router /api/v1/companies/{id}/verify [patch] // VerifyCompany toggles the verification flag for a company (admin only). func (h *Handler) VerifyCompany(w http.ResponseWriter, r *http.Request) { if !strings.HasSuffix(r.URL.Path, "/verify") { http.NotFound(w, r) return } id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } company, err := h.svc.VerifyCompany(r.Context(), id) if err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, company) } // GetMyCompany godoc // @Summary Obter minha empresa // @Tags Empresas // @Security BearerAuth // @Produce json // @Success 200 {object} domain.Company // @Router /api/v1/companies/me [get] // GetMyCompany returns the company linked to the authenticated user. func (h *Handler) GetMyCompany(w http.ResponseWriter, r *http.Request) { claims, ok := middleware.GetClaims(r.Context()) if !ok || claims.CompanyID == nil { writeError(w, http.StatusBadRequest, errors.New("missing company context")) return } company, err := h.svc.GetCompany(r.Context(), *claims.CompanyID) if err != nil { writeError(w, http.StatusNotFound, err) return } writeJSON(w, http.StatusOK, company) } // GetCompanyRating godoc // @Summary Obter avaliação da empresa // @Tags Empresas // @Produce json // @Param id path string true "Company ID" // @Success 200 {object} domain.CompanyRating // @Router /api/v1/companies/{id}/rating [get] // GetCompanyRating exposes the average score for a company. func (h *Handler) GetCompanyRating(w http.ResponseWriter, r *http.Request) { if !strings.HasSuffix(r.URL.Path, "/rating") { http.NotFound(w, r) return } id, err := parseUUIDFromPath(r.URL.Path) if err != nil { writeError(w, http.StatusBadRequest, err) return } rating, err := h.svc.GetCompanyRating(r.Context(), id) if err != nil { writeError(w, http.StatusInternalServerError, err) return } writeJSON(w, http.StatusOK, rating) }