package handlers import ( "encoding/json" "log" "net/http" "github.com/patel-mann/poll-system/app/internal/models" ) // ValidatedAddress represents a validated address with coordinates type ValidatedAddress struct { AddressID int `json:"address_id"` Address string `json:"address"` Longitude float64 `json:"longitude"` Latitude float64 `json:"latitude"` HouseNumber string `json:"house_number"` StreetName string `json:"street_name"` StreetType string `json:"street_type"` Quadrant string `json:"street_quadrant"` UpdatedAt string `json:"updated_at"` } // GetValidatedAddressesHandler returns all validated addresses with their coordinates as JSON func GetValidatedAddressesHandler(w http.ResponseWriter, r *http.Request) { // Only allow GET requests if r.Method != http.MethodGet { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } // Optional: Check if user is authenticated (depending on your auth system) // _, authenticated := models.GetCurrentUserName(r) // if !authenticated { // http.Error(w, "Unauthorized", http.StatusUnauthorized) // return // } // Query validated addresses from database addresses, err := fetchValidatedAddresses() if err != nil { log.Printf("Error fetching validated addresses: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } // Set response headers for JSON w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") // Adjust based on your CORS policy // Encode and send JSON response if err := json.NewEncoder(w).Encode(addresses); err != nil { log.Printf("Error encoding JSON response: %v", err) http.Error(w, "Error encoding response", http.StatusInternalServerError) return } log.Printf("Successfully returned %d validated addresses", addresses) } // fetchValidatedAddresses retrieves all validated addresses from the database func fetchValidatedAddresses() ([]ValidatedAddress, error) { query := ` SELECT address_id, address, longitude, latitude, COALESCE(house_number, '') as house_number, COALESCE(street_name, '') as street_name, COALESCE(street_type, '') as street_type, COALESCE(street_quadrant, '') as street_quadrant, updated_at::text FROM address_database WHERE visited_validated = true AND longitude IS NOT NULL AND latitude IS NOT NULL AND longitude != 0 AND latitude != 0 ORDER BY updated_at DESC ` rows, err := models.DB.Query(query) if err != nil { return nil, err } defer rows.Close() var addresses []ValidatedAddress for rows.Next() { var addr ValidatedAddress err := rows.Scan( &addr.AddressID, &addr.Address, &addr.Longitude, &addr.Latitude, &addr.HouseNumber, &addr.StreetName, &addr.StreetType, &addr.Quadrant, &addr.UpdatedAt, ) if err != nil { log.Printf("Error scanning address row: %v", err) continue } addresses = append(addresses, addr) } if err = rows.Err(); err != nil { return nil, err } return addresses, nil } // GetValidatedAddressesStatsHandler returns statistics about validated addresses func GetValidatedAddressesStatsHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } stats, err := getValidatedAddressesStats() if err != nil { log.Printf("Error fetching address stats: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(stats) } // AddressStats represents statistics about addresses type AddressStats struct { TotalValidated int `json:"total_validated"` TotalAddresses int `json:"total_addresses"` ValidatedWithCoords int `json:"validated_with_coords"` RecentlyValidated int `json:"recently_validated_24h"` } // getValidatedAddressesStats gets statistics about validated addresses func getValidatedAddressesStats() (AddressStats, error) { var stats AddressStats // Get total validated count err := models.DB.QueryRow("SELECT COUNT(*) FROM address_database WHERE visited_validated = true"). Scan(&stats.TotalValidated) if err != nil { return stats, err } // Get total addresses count err = models.DB.QueryRow("SELECT COUNT(*) FROM address_database"). Scan(&stats.TotalAddresses) if err != nil { return stats, err } // Get validated with coordinates count err = models.DB.QueryRow(` SELECT COUNT(*) FROM address_database WHERE visited_validated = true AND longitude IS NOT NULL AND latitude IS NOT NULL AND longitude != 0 AND latitude != 0 `).Scan(&stats.ValidatedWithCoords) if err != nil { return stats, err } // Get recently validated (last 24 hours) err = models.DB.QueryRow(` SELECT COUNT(*) FROM address_database WHERE visited_validated = true AND updated_at > NOW() - INTERVAL '24 hours' `).Scan(&stats.RecentlyValidated) if err != nil { return stats, err } return stats, nil }