package backend

import (
	"encoding/json"
	"net/http"

	"github.com/libnovel/backend/internal/storage"
)

// handleDismissNotification handles DELETE /api/notifications/{id}.
func (s *Server) handleDismissNotification(w http.ResponseWriter, r *http.Request) {
	id := r.PathValue("id")
	if id == "" {
		jsonError(w, http.StatusBadRequest, "notification id required")
		return
	}
	store, ok := s.deps.Producer.(*storage.Store)
	if !ok {
		jsonError(w, http.StatusInternalServerError, "storage not available")
		return
	}
	if err := store.DeleteNotification(r.Context(), id); err != nil {
		jsonError(w, http.StatusInternalServerError, "dismiss notification: "+err.Error())
		return
	}
	writeJSON(w, 0, map[string]any{"success": true})
}

// handleClearAllNotifications handles DELETE /api/notifications?user_id=...
func (s *Server) handleClearAllNotifications(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		jsonError(w, http.StatusBadRequest, "user_id required")
		return
	}
	store, ok := s.deps.Producer.(*storage.Store)
	if !ok {
		jsonError(w, http.StatusInternalServerError, "storage not available")
		return
	}
	if err := store.ClearAllNotifications(r.Context(), userID); err != nil {
		jsonError(w, http.StatusInternalServerError, "clear notifications: "+err.Error())
		return
	}
	writeJSON(w, 0, map[string]any{"success": true})
}

// handleMarkAllNotificationsRead handles PATCH /api/notifications?user_id=...
func (s *Server) handleMarkAllNotificationsRead(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		jsonError(w, http.StatusBadRequest, "user_id required")
		return
	}
	store, ok := s.deps.Producer.(*storage.Store)
	if !ok {
		jsonError(w, http.StatusInternalServerError, "storage not available")
		return
	}
	if err := store.MarkAllNotificationsRead(r.Context(), userID); err != nil {
		jsonError(w, http.StatusInternalServerError, "mark all read: "+err.Error())
		return
	}
	writeJSON(w, 0, map[string]any{"success": true})
}

type notification struct {
	ID      string `json:"id"`
	UserID  string `json:"user_id"`
	Title   string `json:"title"`
	Message string `json:"message"`
	Link    string `json:"link"`
	Read    bool   `json:"read"`
}

func (s *Server) handleListNotifications(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		jsonError(w, http.StatusBadRequest, "user_id required")
		return
	}

	store, ok := s.deps.Producer.(*storage.Store)
	if !ok {
		jsonError(w, http.StatusInternalServerError, "storage not available")
		return
	}

	items, err := store.ListNotifications(r.Context(), userID, 50)
	if err != nil {
		jsonError(w, http.StatusInternalServerError, "list notifications: "+err.Error())
		return
	}

	// Parse each item as notification
	notifications := make([]notification, 0, len(items))
	for _, item := range items {
		b, _ := json.Marshal(item)
		var n notification
		json.Unmarshal(b, &n)
		notifications = append(notifications, n)
	}

	writeJSON(w, 0, map[string]any{"notifications": notifications})
}

func (s *Server) handleMarkNotificationRead(w http.ResponseWriter, r *http.Request) {
	id := r.PathValue("id")
	if id == "" {
		jsonError(w, http.StatusBadRequest, "notification id required")
		return
	}

	store, ok := s.deps.Producer.(*storage.Store)
	if !ok {
		jsonError(w, http.StatusInternalServerError, "storage not available")
		return
	}

	if err := store.MarkNotificationRead(r.Context(), id); err != nil {
		jsonError(w, http.StatusInternalServerError, "mark read: "+err.Error())
		return
	}

	writeJSON(w, 0, map[string]any{"success": true})
}