package handlers

import (
	"context"
	"github.com/goccy/go-json"
	dto "madsky.ru/go-finance/internal/issue"
	"madsky.ru/go-finance/internal/repository/issue"
	"madsky.ru/go-finance/internal/server/request"
	"madsky.ru/go-finance/internal/server/response"
	"net/http"
)

func FindIssues(ctx context.Context, repository issue.Repository) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		i, err := repository.Find(ctx)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		response.WriteJSON(w, nil, http.StatusOK, &i)
	}
}

func FindIssuesByID(ctx context.Context, repository issue.Repository) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")

		id, err := request.Param(r, "id")
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		i, err := repository.FindOne(ctx, id)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		response.WriteJSON(w, nil, http.StatusOK, &i)
	}
}

func CreateIssues(ctx context.Context, repository issue.Repository) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		dec := json.NewDecoder(r.Body)
		dec.DisallowUnknownFields()

		var issueDto dto.CreateIssueDTO

		err := dec.Decode(&issueDto)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		id, err := repository.Create(ctx, &issueDto)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		i, err := repository.FindOne(ctx, *id)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		response.WriteJSON(w, nil, http.StatusOK, &i)
	}
}

func UpdatePositions(ctx context.Context, repository issue.Repository) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		dec := json.NewDecoder(r.Body)
		dec.DisallowUnknownFields()

		var positionDto dto.PositionDTO

		err := dec.Decode(&positionDto)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		i := make([]*uint32, 0)

		for position, issueId := range positionDto.Positions {
			id, err := repository.UpdatePositions(ctx, position, positionDto.StatusId, issueId)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			i = append(i, id)
		}

		response.WriteJSON(w, nil, http.StatusOK, &i)
	}
}

func DeleteIssues(ctx context.Context, repository issue.Repository) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		id, err := request.Param(r, "id")
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		count, err := repository.Remove(ctx, id)
		if err != nil {
			response.Error(w, err, http.StatusBadRequest)
			return
		}

		response.WriteJSON(w, nil, http.StatusOK, count)
	}
}
