package httpserver

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

	"github.com/toki/oto/services/core/internal/cicdstate"
)

func handleGetExecution(store *cicdstate.Store) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		execID := r.PathValue("id")
		if execID == "" {
			parts := strings.Split(r.URL.Path, "/")
			if len(parts) >= 5 {
				execID = parts[4]
			}
		}
		if execID == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing execution id"})
			return
		}
		exec, err := store.GetExecution(execID)
		if err != nil {
			writeResponse(w, http.StatusNotFound, map[string]string{"error": "execution not found"})
			return
		}
		writeResponse(w, http.StatusOK, execToJSON(exec))
	}
}

func handleAppendLog(store *cicdstate.Store) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			writeResponse(w, http.StatusMethodNotAllowed, map[string]string{"error": "method not allowed"})
			return
		}
		execID := r.PathValue("id")
		if execID == "" {
			parts := strings.Split(r.URL.Path, "/")
			if len(parts) >= 5 {
				execID = parts[4]
			}
		}
		if execID == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing execution id"})
			return
		}
		var req struct {
			Line string `json:"line"`
		}
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Line == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "line is required"})
			return
		}
		if err := store.AppendLog(execID, req.Line); err != nil {
			writeResponse(w, http.StatusNotFound, map[string]string{"error": "execution not found"})
			return
		}
		writeResponse(w, http.StatusCreated, map[string]string{"status": "accepted"})
	}
}

func handleGetLogs(store *cicdstate.Store) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		execID := r.PathValue("id")
		if execID == "" {
			parts := strings.Split(r.URL.Path, "/")
			if len(parts) >= 5 {
				execID = parts[4]
			}
		}
		if execID == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing execution id"})
			return
		}
		logs, err := store.GetLogs(execID)
		if err != nil {
			writeResponse(w, http.StatusNotFound, map[string]string{"error": "execution not found"})
			return
		}
		writeResponse(w, http.StatusOK, logsToJSON(logs))
	}
}

func handleAppendArtifact(store *cicdstate.Store) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			writeResponse(w, http.StatusMethodNotAllowed, map[string]string{"error": "method not allowed"})
			return
		}
		execID := r.PathValue("id")
		if execID == "" {
			parts := strings.Split(r.URL.Path, "/")
			if len(parts) >= 5 {
				execID = parts[4]
			}
		}
		if execID == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing execution id"})
			return
		}
		var req struct {
			Name string `json:"name"`
			Path string `json:"path"`
		}
		if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Name == "" || req.Path == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "name and path are required"})
			return
		}
		if err := store.AppendArtifact(execID, req.Name, req.Path); err != nil {
			writeResponse(w, http.StatusNotFound, map[string]string{"error": "execution not found"})
			return
		}
		writeResponse(w, http.StatusCreated, map[string]string{"status": "accepted"})
	}
}

func handleGetArtifacts(store *cicdstate.Store) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		execID := r.PathValue("id")
		if execID == "" {
			parts := strings.Split(r.URL.Path, "/")
			if len(parts) >= 5 {
				execID = parts[4]
			}
		}
		if execID == "" {
			writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing execution id"})
			return
		}
		artifacts, err := store.GetArtifacts(execID)
		if err != nil {
			writeResponse(w, http.StatusNotFound, map[string]string{"error": "execution not found"})
			return
		}
		writeResponse(w, http.StatusOK, artifactsToJSON(artifacts))
	}
}
