package handlers import ( "net/http" "git.linuxforward.com/byom/byom-trends/analysis" "git.linuxforward.com/byom/byom-trends/common" "git.linuxforward.com/byom/byom-trends/logger" "git.linuxforward.com/byom/byom-trends/services/instagram" "git.linuxforward.com/byom/byom-trends/services/tiktok" "git.linuxforward.com/byom/byom-trends/services/youtube" "git.linuxforward.com/byom/byom-trends/store" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/sirupsen/logrus" ) type SocialHandler struct { store *store.DataStore analyzer *analysis.TrendAnalyzer instagramSvc *instagram.Client tiktokSvc *tiktok.Client youtubeSvc *youtube.Client logger *logrus.Entry } type ConnectProfileRequest struct { Platform string `json:"platform" binding:"required,oneof=instagram tiktok youtube"` Username string `json:"username" binding:"required"` ProfileURL string `json:"profile_url" binding:"required,url"` } func NewSocialHandler( store *store.DataStore, instagramSvc *instagram.Client, tiktokSvc *tiktok.Client, youtubeSvc *youtube.Client, ) *SocialHandler { return &SocialHandler{ store: store, instagramSvc: instagramSvc, tiktokSvc: tiktokSvc, youtubeSvc: youtubeSvc, logger: logger.NewLogger("social-handler"), } } // ConnectProfile connects a new social media profile func (h *SocialHandler) ConnectProfile(c *gin.Context) { var req ConnectProfileRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) return } profile := &common.SocialProfile{ ID: uuid.New(), Platform: req.Platform, Username: req.Username, ProfileURL: req.ProfileURL, } // Verify profile exists and get initial stats //var err error switch req.Platform { case "instagram": stats, err := h.instagramSvc.GetProfileStats(req.Username) if err != nil { h.logger.WithError(err).Error("failed to get Instagram profile stats") c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify Instagram profile"}) return } profile.FollowerCount = stats.FollowerCount profile.Engagement = stats.Engagement case "tiktok": stats, err := h.tiktokSvc.GetProfileStats(req.Username) if err != nil { h.logger.WithError(err).Error("failed to get TikTok profile stats") c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify TikTok profile"}) return } profile.FollowerCount = stats.FollowerCount profile.Engagement = stats.Engagement case "youtube": stats, err := h.youtubeSvc.GetChannelStats(req.Username) if err != nil { h.logger.WithError(err).Error("failed to get YouTube channel stats") c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify YouTube channel"}) return } profile.FollowerCount = stats.SubscriberCount profile.Engagement = stats.Engagement } if err := h.store.CreateSocialProfile(c, profile); err != nil { h.logger.WithError(err).Error("failed to create social profile") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create social profile"}) return } c.JSON(http.StatusCreated, profile) } // GetProfileStats retrieves stats for a connected profile func (h *SocialHandler) GetProfileStats(c *gin.Context) { platform := c.Param("platform") username := c.Query("username") if username == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "Username is required"}) return } var stats interface{} var err error switch platform { case "instagram": stats, err = h.instagramSvc.GetProfileStats(username) case "tiktok": stats, err = h.tiktokSvc.GetProfileStats(username) case "youtube": stats, err = h.youtubeSvc.GetChannelStats(username) default: c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid platform"}) return } if err != nil { h.logger.WithError(err).Error("failed to get profile stats") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get profile stats"}) return } c.JSON(http.StatusOK, stats) } // GetProfileEngagement retrieves engagement metrics for a profile func (h *SocialHandler) GetProfileEngagement(c *gin.Context) { profileID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid profile ID"}) return } profile, err := h.store.GetSocialProfile(c, profileID) if err != nil { h.logger.WithError(err).Error("failed to get social profile") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get social profile"}) return } if profile == nil { c.JSON(http.StatusNotFound, gin.H{"error": "Profile not found"}) return } metrics, err := h.analyzer.AnalyzeEngagement(c, profile) if err != nil { h.logger.WithError(err).Error("failed to analyze engagement") c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to analyze engagement"}) return } c.JSON(http.StatusOK, metrics) }