package handlers import ( "net/http" "git.linuxforward.com/byom/byom-trends/common" "git.linuxforward.com/byom/byom-trends/logger" "git.linuxforward.com/byom/byom-trends/services/google" "git.linuxforward.com/byom/byom-trends/store" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/sirupsen/logrus" ) type GoogleHandler struct { store *store.DataStore googleSvc *google.Client logger *logrus.Entry } type GoogleTrendsRequest struct { Keywords []string `json:"keywords" binding:"required,min=1,max=5"` TimeRange string `json:"time_range" binding:"required,oneof=daily weekly monthly yearly"` Region string `json:"region" binding:"omitempty"` } func NewGoogleHandler( store *store.DataStore, googleSvc *google.Client, ) *GoogleHandler { return &GoogleHandler{ store: store, googleSvc: googleSvc, logger: logger.NewLogger("google-handler"), } } // AnalyzeGoogleTrends analyzes Google Trends data for given keywords func (h *GoogleHandler) AnalyzeGoogleTrends(c *gin.Context) { var req GoogleTrendsRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) return } // Get trends data for each keyword results, err := h.googleSvc.CompareKeywords(req.Keywords, req.TimeRange) if err != nil { h.logger.WithError(err).Error("failed to get Google Trends data") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get trends data"}) return } // Get related topics for each keyword relatedTopics := make(map[string][]google.RelatedTopic) for _, keyword := range req.Keywords { topics, err := h.googleSvc.GetRelatedTopics(keyword) if err != nil { h.logger.WithError(err).Warnf("failed to get related topics for %s", keyword) continue } relatedTopics[keyword] = topics } // Get regional interest if region is specified var regionalInterest map[string]int if req.Region != "" { // Combine all keywords for regional analysis combinedKeywords := req.Keywords[0] for _, keyword := range req.Keywords[1:] { combinedKeywords += " " + keyword } regionalInterest, err = h.googleSvc.GetRegionalInterest(combinedKeywords, req.Region) if err != nil { h.logger.WithError(err).Warn("failed to get regional interest") } } // Create trend analysis record trend := &common.GoogleTrend{ ID: uuid.New(), Keywords: req.Keywords, TrendData: nil, // Will be set after marshaling } // Combine all data analysisData := map[string]interface{}{ "trends": results, "related_topics": relatedTopics, "regional_interest": regionalInterest, "time_range": req.TimeRange, "region": req.Region, } // Store the analysis if err := h.store.CreateGoogleTrend(c, trend); err != nil { h.logger.WithError(err).Error("failed to store Google Trends analysis") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to store analysis"}) return } c.JSON(http.StatusOK, analysisData) } // GetTrendAnalysis retrieves a specific Google Trends analysis func (h *GoogleHandler) GetTrendAnalysis(c *gin.Context) { id, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid analysis ID"}) return } trend, err := h.store.GetGoogleTrend(c, id) if err != nil { h.logger.WithError(err).Error("failed to get Google Trends analysis") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get analysis"}) return } if trend == nil { c.JSON(http.StatusNotFound, gin.H{"error": "Analysis not found"}) return } c.JSON(http.StatusOK, trend) } // GetRelatedTopics gets related topics for a keyword func (h *GoogleHandler) GetRelatedTopics(c *gin.Context) { keyword := c.Query("keyword") if keyword == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Keyword is required"}) return } topics, err := h.googleSvc.GetRelatedTopics(keyword) if err != nil { h.logger.WithError(err).Error("failed to get related topics") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get related topics"}) return } c.JSON(http.StatusOK, topics) } // GetRegionalInterest gets regional interest data for keywords func (h *GoogleHandler) GetRegionalInterest(c *gin.Context) { keyword := c.Query("keyword") region := c.Query("region") if keyword == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Keyword is required"}) return } interest, err := h.googleSvc.GetRegionalInterest(keyword, region) if err != nil { h.logger.WithError(err).Error("failed to get regional interest") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get regional interest"}) return } c.JSON(http.StatusOK, interest) }