package feishu

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"

	utils "feishu-messager/pkg/utils"
)

type FeishuWebhookMessageReq struct {
	MsgType string     `json:"msg_type"`
	Card    FeishuCard `json:"card"`
	Text    string     `json:"text"`
}

type FeishuWebhookMessageResp struct {
	StatusCode    uint64 `json:"StatusCode"`
	StatusMessage string `json:"StatusMessage"`
	Code          uint64 `json:"code"`
	Msg           string `json:"msg"`
}

type raw struct {
	httpClient *http.Client
}

var webhookCli = &raw{httpClient: &http.Client{
	Timeout:   10 * time.Second,
	Transport: http.DefaultTransport,
}}

func SendCardToWebhook(params FeishuCardParams, webhook string) error {
	url, err := url.Parse(webhook)
	if err != nil {
		return fmt.Errorf("invalid webhook: %s", webhook)
	}
	log.Println("parsed webhook is", url)

	card, err := generateCard(params)
	if err != nil {
		return fmt.Errorf("generate feishu card failed")
	}
	req := FeishuWebhookMessageReq{
		MsgType: "interactive",
		Card:    card,
	}

	resp := FeishuWebhookMessageResp{}

	err = webhookCli.do(context.Background(), "POST", url.String(), req, &resp)
	if err != nil {
		return fmt.Errorf("send message to webhook failed: %e", err)
	}

	return nil
}

func SendMessageToWebhook(text string, webhook string) error {
	url, err := url.Parse(webhook)
	if err != nil {
		return fmt.Errorf("invalid webhook: %s", webhook)
	}
	log.Println("parsed webhook is", url)

	req := FeishuWebhookMessageReq{
		MsgType: "text",
		Text:    text,
	}

	resp := FeishuWebhookMessageResp{}

	err = webhookCli.do(context.Background(), "POST", url.String(), req, &resp)
	if err != nil {
		return fmt.Errorf("send message to webhook failed: %e", err)
	}

	return nil
}

func (cli *raw) do(ctx context.Context, method, url string, req any, resp any) error {
	var bodyReader io.Reader
	if req != nil {
		jsonBytes, err := json.Marshal(req)
		if err != nil {
			return fmt.Errorf("marshal req failed: %w", err)
		}
		log.Println("jsonBytes is", string(jsonBytes))
		bodyReader = bytes.NewReader(jsonBytes)
	}

	httpReq, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("build req failed: %w", err)
	}

	httpReq.Header.Add("Content-Type", "application/json")
	httpReq.Header.Add("User-Agent", "curl/7.54.1")

	err = utils.DoSimply(cli.httpClient, httpReq, resp)
	if err != nil {
		return fmt.Errorf("request failed: %w", err)
	}

	log.Println("webhook resp is", resp)

	return nil
}
