package httpserver

import (
	"context"
	"errors"
	"net/http"

	contractevents "bit.admedia.com/scm/ad/adpilot-indexing-code-parser.com/internal/contracts/events"
	"bit.admedia.com/scm/ad/adpilot-indexing-code-parser.com/internal/service/parser"
	"bit.admedia.com/scm/ad/adpilot-indexing-code-parser.com/internal/store"
)

// ParseJobReader exposes parse job debug lookups.
type ParseJobReader interface {
	GetParseJob(jobID string) (parser.ParseJob, bool)
	GetJobDiagnostics(jobID string) ([]contractevents.ParserDiagnostic, bool)
}

// ArtifactMetadataReader exposes artifact metadata debug lookups.
type ArtifactMetadataReader interface {
	GetArtifactMetadata(ctx context.Context, artifactID string) (store.ArtifactMetadata, error)
}

// DebugAPI wires REST debug/control-plane dependencies.
type DebugAPI struct {
	Jobs      ParseJobReader
	Artifacts ArtifactMetadataReader
}

type errorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
}

type diagnosticsResponse struct {
	JobID       string                            `json:"job_id"`
	Diagnostics []contractevents.ParserDiagnostic `json:"diagnostics"`
}

func handleParseJob(jobs ParseJobReader) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		jobID := r.PathValue("job_id")
		if jobID == "" {
			writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "parse job not found"})
			return
		}

		job, ok := jobs.GetParseJob(jobID)
		if !ok {
			writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "parse job not found"})
			return
		}

		writeJSON(w, http.StatusOK, job)
	}
}

func handleDiagnostics(jobs ParseJobReader) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		jobID := r.PathValue("job_id")
		if jobID == "" {
			writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "parse job not found"})
			return
		}

		diagnostics, ok := jobs.GetJobDiagnostics(jobID)
		if !ok {
			writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "parse job not found"})
			return
		}

		writeJSON(w, http.StatusOK, diagnosticsResponse{
			JobID:       jobID,
			Diagnostics: diagnostics,
		})
	}
}

func handleArtifactMetadata(artifacts ArtifactMetadataReader) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		artifactID := r.PathValue("artifact_id")
		if artifactID == "" {
			writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "artifact not found"})
			return
		}

		metadata, err := artifacts.GetArtifactMetadata(r.Context(), artifactID)
		if err != nil {
			switch {
			case errors.Is(err, store.ErrInvalidArtifactID):
				writeJSON(w, http.StatusBadRequest, errorResponse{Error: "invalid_request", Message: "invalid artifact id"})
			case errors.Is(err, store.ErrArtifactNotFound):
				writeJSON(w, http.StatusNotFound, errorResponse{Error: "not_found", Message: "artifact not found"})
			default:
				writeJSON(w, http.StatusInternalServerError, errorResponse{Error: "internal_error", Message: "failed to load artifact metadata"})
			}
			return
		}

		writeJSON(w, http.StatusOK, metadata)
	}
}
