package googleapi

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"gogs.mikescher.com/BlackForestBytes/goext"
	"gogs.mikescher.com/BlackForestBytes/goext/exerr"
	"gogs.mikescher.com/BlackForestBytes/goext/langext"
	"io"
	"net/http"
)

type MailRef struct {
	ID       string   `json:"id"`
	ThreadID string   `json:"threadId"`
	LabelIDs []string `json:"labelIds"`
}

func (c *client) SendMail(ctx context.Context, from string, recipients []string, cc []string, bcc []string, subject string, body MailBody, attachments []MailAttachment) (MailRef, error) {

	mm := encodeMimeMail(from, recipients, cc, bcc, subject, body, attachments)

	tok, err := c.oauth.AccessToken()
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Build()
	}

	url := fmt.Sprintf("https://gmail.googleapis.com/gmail/v1/users/%s/messages/send?alt=json&prettyPrint=false", "me")

	msgbody, err := json.Marshal(langext.H{"raw": base64.URLEncoding.EncodeToString([]byte(mm))})
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Build()
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(msgbody))
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Build()
	}

	req.Header.Add("Authorization", "Bearer "+tok)
	req.Header.Add("X-Goog-Api-Client", "blackforestbytes-goext/"+goext.GoextVersion)
	req.Header.Add("User-Agent", "blackforestbytes-goext/"+goext.GoextVersion)
	req.Header.Add("Content-Type", "application/json")

	resp, err := c.http.Do(req)
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Build()
	}

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Build()
	}

	if resp.StatusCode != 200 {
		return MailRef{}, exerr.New(exerr.TypeGoogleStatuscode, "gmail returned non-200 statuscode").Int("sc", resp.StatusCode).Str("body", string(respBody)).Build()
	}

	var respObj MailRef
	err = json.Unmarshal(respBody, &respObj)
	if err != nil {
		return MailRef{}, exerr.Wrap(err, "").Str("body", string(respBody)).Build()
	}

	return respObj, nil
}