package webhooks

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

	"github.com/operator/command-center/internal/eventbus"
)

// CrossseedHandler parses cross-seed's notify webhook body.
//
// cross-seed sends a JSON payload with an `event` field indicating the
// event type. The body shape varies slightly across cross-seed versions;
// this handler tolerates both the older `name`-keyed and newer
// `releaseName`-keyed forms.
type CrossseedHandler struct {
	Bus *eventbus.Bus
}

func (h *CrossseedHandler) HandlerType() string { return "crossseed" }

type crossseedPayload struct {
	Event           string `json:"event"`
	Name            string `json:"name"`
	ReleaseName     string `json:"releaseName"`
	InfoHash        string `json:"infoHash"`
	TorrentHash     string `json:"torrent_hash"`
	SourceTracker   string `json:"sourceTracker"`
	DestTracker     string `json:"destTracker"`
	Tracker         string `json:"tracker"`
	SourceInfoHash  string `json:"sourceInfoHash"`
	DecisionReason  string `json:"decision_reason"`
	DecisionString  string `json:"decision"`
}

func (h *CrossseedHandler) Handle(ctx context.Context, r *http.Request, body []byte, endpointID string) error {
	var p crossseedPayload
	if err := json.Unmarshal(body, &p); err != nil {
		return err
	}
	name := firstNonEmpty(p.ReleaseName, p.Name)
	hash := firstNonEmpty(p.InfoHash, p.TorrentHash)
	dest := firstNonEmpty(p.DestTracker, p.Tracker)
	reason := firstNonEmpty(p.DecisionReason, p.DecisionString)

	kind := "match_found"
	topic := eventbus.TopicCrossseedMatchFound
	switch p.Event {
	case "INJECTED", "MATCH_APPLIED", "injected":
		kind = "match_applied"
		topic = eventbus.TopicCrossseedMatchApplied
	}

	ev := CrossseedEvent{
		Kind:           kind,
		InfoHash:       hash,
		Name:           name,
		SourceTracker:  p.SourceTracker,
		DestTracker:    dest,
		SourceInfoHash: p.SourceInfoHash,
		DecisionReason: reason,
		ReceivedAt:     time.Now(),
		EndpointID:     endpointID,
	}
	if h.Bus != nil {
		h.Bus.Publish(eventbus.Event{Topic: topic, Payload: ev})
	}
	return nil
}
