// internal/handlers/lottery/syndicate/syndicate.go package handlers import ( "fmt" "log" "net/http" templateHandlers "synlotto-website/internal/handlers/template" securityHelpers "synlotto-website/internal/helpers/security" templateHelpers "synlotto-website/internal/helpers/template" syndicateStorage "synlotto-website/internal/storage/syndicate" ticketStorage "synlotto-website/internal/storage/tickets" "synlotto-website/internal/helpers" "synlotto-website/internal/models" "synlotto-website/internal/platform/bootstrap" ) func CreateSyndicateHandler(app *bootstrap.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: data := templateHandlers.BuildTemplateData(app, w, r) ctx := templateHelpers.TemplateContext(w, r, data) tmpl := templateHelpers.LoadTemplateFiles("create-syndicate.html", "web/templates/syndicate/create.html") _ = tmpl.ExecuteTemplate(w, "layout", ctx) case http.MethodPost: name := r.FormValue("name") description := r.FormValue("description") userId, ok := securityHelpers.GetCurrentUserID(app.SessionManager, r) if !ok || name == "" { templateHelpers.SetFlash(r, "Invalid data submitted") http.Redirect(w, r, "/syndicate/create", http.StatusSeeOther) return } if _, err := syndicateStorage.CreateSyndicate(app.DB, userId, name, description); err != nil { log.Printf("❌ CreateSyndicate failed: %v", err) templateHelpers.SetFlash(r, "Failed to create syndicate") } else { templateHelpers.SetFlash(r, "Syndicate created successfully") } http.Redirect(w, r, "/syndicate", http.StatusSeeOther) default: templateHelpers.RenderError(w, r, http.StatusMethodNotAllowed) } } } func ListSyndicatesHandler(app *bootstrap.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, ok := securityHelpers.GetCurrentUserID(app.SessionManager, r) if !ok { templateHelpers.RenderError(w, r, http.StatusForbidden) return } managed := syndicateStorage.GetSyndicatesByOwner(app.DB, userID) member := syndicateStorage.GetSyndicatesByMember(app.DB, userID) managedMap := make(map[int]bool, len(managed)) for _, s := range managed { managedMap[s.ID] = true } var filteredJoined []models.Syndicate for _, s := range member { if !managedMap[s.ID] { filteredJoined = append(filteredJoined, s) } } data := templateHandlers.BuildTemplateData(app, w, r) ctx := templateHelpers.TemplateContext(w, r, data) ctx["ManagedSyndicates"] = managed ctx["JoinedSyndicates"] = filteredJoined tmpl := templateHelpers.LoadTemplateFiles("syndicates.html", "web/templates/syndicate/index.html") _ = tmpl.ExecuteTemplate(w, "layout", ctx) } } func ViewSyndicateHandler(app *bootstrap.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, ok := securityHelpers.GetCurrentUserID(app.SessionManager, r) if !ok { templateHelpers.RenderError(w, r, http.StatusForbidden) return } syndicateID := helpers.Atoi(r.URL.Query().Get("id")) syndicate, err := syndicateStorage.GetSyndicateByID(app.DB, syndicateID) if err != nil || syndicate == nil { templateHelpers.RenderError(w, r, http.StatusNotFound) return } isManager := userID == syndicate.OwnerID isMember := syndicateStorage.IsSyndicateMember(app.DB, syndicateID, userID) if !isManager && !isMember { templateHelpers.RenderError(w, r, http.StatusForbidden) return } members := syndicateStorage.GetSyndicateMembers(app.DB, syndicateID) data := templateHandlers.BuildTemplateData(app, w, r) ctx := templateHelpers.TemplateContext(w, r, data) ctx["Syndicate"] = syndicate ctx["Members"] = members ctx["IsManager"] = isManager tmpl := templateHelpers.LoadTemplateFiles("syndicate-view.html", "web/templates/syndicate/view.html") _ = tmpl.ExecuteTemplate(w, "layout", ctx) } } func SyndicateLogTicketHandler(app *bootstrap.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, ok := securityHelpers.GetCurrentUserID(app.SessionManager, r) if !ok { templateHelpers.RenderError(w, r, http.StatusForbidden) return } syndicateId := helpers.Atoi(r.URL.Query().Get("id")) syndicate, err := syndicateStorage.GetSyndicateByID(app.DB, syndicateId) if err != nil || syndicate.OwnerID != userID { templateHelpers.RenderError(w, r, http.StatusForbidden) return } switch r.Method { case http.MethodGet: data := templateHandlers.BuildTemplateData(app, w, r) ctx := templateHelpers.TemplateContext(w, r, data) ctx["Syndicate"] = syndicate tmpl := templateHelpers.LoadTemplateFiles("syndicate-log-ticket.html", "web/templates/syndicate/log_ticket.html") _ = tmpl.ExecuteTemplate(w, "layout", ctx) case http.MethodPost: gameType := r.FormValue("game_type") drawDateStr := r.FormValue("draw_date") method := r.FormValue("purchase_method") dt, err := helpers.ParseDrawDate(drawDateStr) if err != nil { templateHelpers.SetFlash(r, "Invalid draw date") http.Redirect(w, r, fmt.Sprintf("/syndicate/view?id=%d", syndicateId), http.StatusSeeOther) return } err = ticketStorage.InsertTicket(app.DB, models.Ticket{ UserId: userID, GameType: gameType, DrawDate: dt, PurchaseMethod: method, SyndicateId: &syndicateId, }) if err != nil { templateHelpers.SetFlash(r, "Failed to add ticket.") } else { templateHelpers.SetFlash(r, "Ticket added for syndicate.") } http.Redirect(w, r, fmt.Sprintf("/syndicate/view?id=%d", syndicateId), http.StatusSeeOther) default: templateHelpers.RenderError(w, r, http.StatusMethodNotAllowed) } } } func SyndicateTicketsHandler(app *bootstrap.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { userID, ok := securityHelpers.GetCurrentUserID(app.SessionManager, r) if !ok { templateHelpers.RenderError(w, r, http.StatusForbidden) return } syndicateID := helpers.Atoi(r.URL.Query().Get("id")) if syndicateID == 0 { templateHelpers.RenderError(w, r, http.StatusBadRequest) return } if !syndicateStorage.IsSyndicateMember(app.DB, syndicateID, userID) { templateHelpers.RenderError(w, r, http.StatusForbidden) return } // You said GetSyndicateTickets lives in storage/syndicate: tickets := syndicateStorage.GetSyndicateTickets(app.DB, syndicateID) // If you later move it into tickets storage, switch to: // tickets := ticketStorage.GetSyndicateTickets(app.DB, syndicateID) data := templateHandlers.BuildTemplateData(app, w, r) ctx := templateHelpers.TemplateContext(w, r, data) ctx["SyndicateID"] = syndicateID ctx["Tickets"] = tickets tmpl := templateHelpers.LoadTemplateFiles("syndicate-tickets.html", "web/templates/syndicate/tickets.html") _ = tmpl.ExecuteTemplate(w, "layout", ctx) } }