// outlooks_endpoint.go defines convective outlook endpoint behavior.
// Layer: adapters/inbound/httpapi outlook routes.
package httpapi

import (
	"context"
	"net/http"
	"time"

	"gitea.maximumdirect.net/ejr/feedapi/endpoint"
	"gitea.maximumdirect.net/ejr/feedapi/render"
	"gitea.maximumdirect.net/ejr/feedapi/response"
	"gitea.maximumdirect.net/ejr/weatherapi/internal/adapters/inbound/httpapi/presenter"
)

type outlookFilterMode int

const (
	outlookFilterUser outlookFilterMode = iota
	outlookFilterActive
	outlookFilterLocation
)

var outlookNow = time.Now

func outlookDefinitions(svc Service) []endpoint.Definition {
	return []endpoint.Definition{
		outlookDefinition("/outlooks/convective", outlookFilterUser, bindOutlookQuery, svc),
		outlookDefinition("/outlooks/convective/active", outlookFilterActive, bindOutlookQuery, svc),
		outlookDefinition("/outlooks/convective/location", outlookFilterLocation, bindOutlookLocationQuery, svc),
	}
}

func outlookDefinition(
	path string,
	mode outlookFilterMode,
	binder func(*http.Request) (outlookQueryRequest, error),
	svc Service,
) endpoint.Definition {
	return endpoint.GET(
		path,
		binder,
		func(ctx context.Context, req outlookQueryRequest) (any, error) {
			filter := req.Filter
			if mode == outlookFilterActive || mode == outlookFilterLocation {
				activeAt := outlookNow().UTC()
				filter.ActiveAt = &activeAt
			}
			if mode == outlookFilterLocation {
				containsLocation := true
				filter.ContainsLocation = &containsLocation
			}

			run, err := svc.LatestConvectiveOutlook(ctx, filter)
			if err != nil {
				return nil, err
			}
			return response.Envelope{Data: presenter.OutlookRunPayload(run, req.Units, req.Timezone)}, nil
		},
		endpoint.WithProduces(render.FormatJSON, render.FormatXML, render.FormatText),
		endpoint.WithTemplate("outlooks_convective.txt.tmpl"),
	)
}
