package handlers

import (
	"encoding/json"
	"io"
	"log"
	"net/http"
	"strconv"
	"streamService/internal/app/models"
	"streamService/internal/app/services"

	"github.com/gorilla/mux"
)

func RegisterStreamRoutes(router *mux.Router, svc services.StreamService) {
	router.HandleFunc("/streams", GetAllStreams(svc)).Methods("GET")
	router.HandleFunc("/streams/{id}", GetStream(svc)).Methods("GET")
	router.HandleFunc("/streams", CreateStream(svc)).Methods("POST")
	router.HandleFunc("/streams/{id}", UpdateStream(svc)).Methods("PUT")
	router.HandleFunc("/streams/{id}", DeleteStream(svc)).Methods("DELETE")
}

// GetAllStreams godoc
// @Summary Получить все стримы
// @Description Возвращает список всех стримов
// @Tags streams
// @Accept  json
// @Produce  json
// @Success 200 {array} models.Stream
// @Router /streams [get]
func GetAllStreams(svc services.StreamService) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		streams, err := svc.GetAllStreams()
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		err = json.NewEncoder(w).Encode(streams)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}

// GetStream godoc
// @Summary Получить стрим по ID
// @Description Возвращает стрим с указанным ID
// @Tags streams
// @Accept  json
// @Produce  json
// @Param id path int true "ID стрима"
// @Success 200 {object} models.Stream
// @Router /streams/{id} [get]
func GetStream(svc services.StreamService) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		body, _ := io.ReadAll(r.Body)
		log.Printf("Response Body: %s", body)
		idStr := mux.Vars(r)["id"]
		id, err := strconv.Atoi(idStr)
		if err != nil {
			http.Error(w, "Invalid ID", http.StatusBadRequest)
			return
		}

		stream, err := svc.GetStreamByID(uint(id))
		if err != nil {
			http.Error(w, "Stream not found", http.StatusNotFound)
			return
		}
		err = json.NewEncoder(w).Encode(stream)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}

// CreateStream godoc
// @Summary Создать стрим
// @Description Создает новый стрим
// @Tags streams
// @Accept  json
// @Produce  json
// @Param stream body models.Stream true "Данные стримы"
// @Success 200 {object} models.Stream
// @Router /streams [post]
func CreateStream(svc services.StreamService) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var stream models.Stream
		err := json.NewDecoder(r.Body).Decode(&stream)
		if err != nil {
			http.Error(w, "Failed to decode request body", http.StatusBadRequest)
			return
		}
		err = svc.CreateStream(&stream)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.WriteHeader(http.StatusCreated)
		err = json.NewEncoder(w).Encode(stream)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}

// UpdateStream godoc
// @Summary Обновить данные стрима
// @Description Обновляет данные стрима по ID
// @Tags streams
// @Accept  json
// @Produce  json
// @Param id path int true "ID стрима"
// @Param stream body models.Stream true "Обновленные данные стрима"
// @Success 200 {object} models.Stream
// @Router /streams/{id} [put]
func UpdateStream(svc services.StreamService) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var stream models.Stream
		idStr := mux.Vars(r)["id"]
		id, err := strconv.Atoi(idStr)
		if err != nil {
			http.Error(w, "Invalid ID", http.StatusBadRequest)
			return
		}

		if err := json.NewDecoder(r.Body).Decode(&stream); err != nil {
			http.Error(w, "Failed to decode request body", http.StatusBadRequest)
			return
		}
		stream.ID = uint(id)
		err = svc.UpdateStream(&stream)
		if err != nil {
			http.Error(w, "Stream not found", http.StatusNotFound)
			return
		}
		err = json.NewEncoder(w).Encode(stream)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}

// DeleteStream godoc
// @Summary Удалить стрим
// @Description Удаляет стрим по ID
// @Tags streams
// @Accept  json
// @Produce  json
// @Param id path int true "ID стрима"
// @Success 204 "No Content"
// @Router /streams/{id} [delete]
func DeleteStream(svc services.StreamService) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		idStr := mux.Vars(r)["id"]
		id, err := strconv.Atoi(idStr)
		if err != nil {
			http.Error(w, "Invalid ID", http.StatusBadRequest)
			return
		}
		err = svc.DeleteStream(uint(id))
		if err != nil {
			http.Error(w, "Stream not found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusNoContent)
	}
}
