// outlook.go presents convective outlook payloads.
// Layer: adapters/inbound/httpapi/presenter outlook payload mapping.
package presenter

import (
	"encoding/json"
	"time"

	"gitea.maximumdirect.net/ejr/weatherfeeder/model"
)

func OutlookRunPayload(run *model.WeatherOutlookRun, _ Units, tz *time.Location) any {
	if run == nil {
		return nil
	}

	out := model.WeatherOutlookRun{
		LocationID:   run.LocationID,
		LocationName: run.LocationName,
		Latitude:     copyFloat64Ptr(run.Latitude),
		Longitude:    copyFloat64Ptr(run.Longitude),
		AsOf:         inLocationTime(run.AsOf, tz),
		IssuedAt:     inLocationTimePtr(run.IssuedAt, tz),
		Outlooks:     make([]model.WeatherOutlook, 0, len(run.Outlooks)),
		Discussions:  make([]model.WeatherOutlookDiscussion, 0, len(run.Discussions)),
	}
	for _, outlook := range run.Outlooks {
		out.Outlooks = append(out.Outlooks, copyOutlook(outlook, tz))
	}
	for _, discussion := range run.Discussions {
		out.Discussions = append(out.Discussions, copyOutlookDiscussion(discussion, tz))
	}
	return &out
}

func copyOutlook(outlook model.WeatherOutlook, tz *time.Location) model.WeatherOutlook {
	out := model.WeatherOutlook{
		ID:               outlook.ID,
		Provider:         outlook.Provider,
		Product:          outlook.Product,
		Day:              outlook.Day,
		OutlookType:      outlook.OutlookType,
		Label:            outlook.Label,
		LabelText:        outlook.LabelText,
		SeverityRank:     copyIntPtr(outlook.SeverityRank),
		ValidFrom:        inLocationTime(outlook.ValidFrom, tz),
		ValidTo:          inLocationTime(outlook.ValidTo, tz),
		IssuedAt:         inLocationTime(outlook.IssuedAt, tz),
		ExpiresAt:        inLocationTime(outlook.ExpiresAt, tz),
		Forecaster:       outlook.Forecaster,
		SourceURL:        outlook.SourceURL,
		ImageURL:         outlook.ImageURL,
		ContainsLocation: outlook.ContainsLocation,
	}
	if outlook.Geometry != nil {
		out.Geometry = json.RawMessage(append([]byte(nil), outlook.Geometry...))
	}
	return out
}

func copyOutlookDiscussion(discussion model.WeatherOutlookDiscussion, tz *time.Location) model.WeatherOutlookDiscussion {
	return model.WeatherOutlookDiscussion{
		Day:        discussion.Day,
		Headline:   discussion.Headline,
		Summary:    discussion.Summary,
		Discussion: discussion.Discussion,
		UpdatedAt:  inLocationTimePtr(discussion.UpdatedAt, tz),
	}
}

func copyIntPtr(v *int) *int {
	if v == nil {
		return nil
	}
	out := *v
	return &out
}
