package push

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const wpushAPIURL = "https://api.wpush.cn/api/v1/send"

// WPushConfig 是 WPush 推送的配置。
type WPushConfig struct {
	APIKey string
}

// WPushProvider 实现了通过 WPush 发送推送。
// 支持微信公众号、飞书、钉钉、企业微信等多种渠道，取决于用户在 WPush 侧的配置。
type WPushProvider struct {
	apiKey string
	client *http.Client
}

// NewWPushProvider 创建 WPush 推送 Provider。
// APIKey 为空时返回 ErrProviderConfigInvalid。
func NewWPushProvider(cfg WPushConfig) (*WPushProvider, error) {
	if strings.TrimSpace(cfg.APIKey) == "" {
		return nil, ErrProviderConfigInvalid
	}
	return &WPushProvider{
		apiKey: strings.TrimSpace(cfg.APIKey),
		client: &http.Client{Timeout: 10 * time.Second},
	}, nil
}

func (p *WPushProvider) Name() string { return "wpush" }

func (p *WPushProvider) Send(ctx context.Context, msg Message) error {
	form := url.Values{}
	form.Set("apikey", p.apiKey)
	form.Set("title", msg.Title)
	form.Set("content", msg.Content)

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, wpushAPIURL, strings.NewReader(form.Encode()))
	if err != nil {
		return fmt.Errorf("wpush: create request: %w", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	resp, err := p.client.Do(req)
	if err != nil {
		return fmt.Errorf("wpush: send failed: %w", err)
	}
	defer resp.Body.Close()

	bodyBytes, _ := io.ReadAll(resp.Body)

	var result struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	if err := json.Unmarshal(bodyBytes, &result); err != nil {
		return fmt.Errorf("wpush: parse response: %w (body: %s)", err, string(bodyBytes))
	}
	if result.Code != 0 {
		return fmt.Errorf("wpush: api error code=%d: %s", result.Code, result.Message)
	}
	return nil
}
