package notifications

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"time"
)

// DiscordChannel POSTs to a Discord webhook URL. Per-rule cfg supplies the
// URL via the "webhook_url" key.
type DiscordChannel struct {
	HTTP *http.Client
}

func (c *DiscordChannel) Name() string { return "discord" }

func (c *DiscordChannel) Send(ctx context.Context, n Notification, cfg map[string]any) (int, error) {
	url, _ := cfg["webhook_url"].(string)
	if url == "" {
		return 0, errors.New("discord: webhook_url required in rule config")
	}
	hc := c.HTTP
	if hc == nil {
		hc = &http.Client{Timeout: 10 * time.Second}
	}
	body, _ := json.Marshal(map[string]any{
		"username": "Command Center",
		"embeds": []map[string]any{{
			"title":       n.Title,
			"description": n.Body,
			"color":       colorForSeverity(n.Severity),
			"url":         n.URL,
			"timestamp":   n.Timestamp.UTC().Format(time.RFC3339),
		}},
	})
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	if err != nil {
		return 0, err
	}
	req.Header.Set("Content-Type", "application/json")
	resp, err := hc.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 200 && resp.StatusCode < 300 {
		return 1, nil
	}
	b, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
	return 0, fmt.Errorf("discord: status %d: %s", resp.StatusCode, b)
}

func colorForSeverity(s Severity) int {
	switch s {
	case SeverityCritical:
		return 0xDC2626 // red-600
	case SeverityWarning:
		return 0xF59E0B // amber-500
	case SeverityDebug:
		return 0x6B7280 // gray-500
	default:
		return 0x10B981 // emerald-500
	}
}
