package message

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"local/truckstop/config"
	"local/truckstop/logtr"
	"mime/multipart"
	"net/http"
	"net/url"
	"time"
)

var ErrBadAuth = errors.New("auth has failed")

func UploadImage(b []byte) (string, error) {
	path, err := uploadImage(b)
	if err == ErrBadAuth {
		if err := refreshToken(); err != nil {
			return "", err
		}
		path, err = uploadImage(b)
	}
	return path, err
}

func refreshToken() error {
	return errors.New("not impl")
}

func uploadImage(b []byte) (string, error) {
	images := config.Get().Images
	buff := bytes.NewBuffer(nil)
	writer := multipart.NewWriter(buff)
	name := "name"
	if u, err := url.Parse(images.UploadURI); err != nil {
	} else if s, ok := u.Query()["name"]; !ok {
	} else {
		name = s[0]
		logtr.Debugf("found name in upload uri: %s", name)
	}
	part, err := writer.CreateFormFile("image", name)
	if err != nil {
		return "", err
	}
	if n, err := part.Write(b); err != nil {
		return "", err
	} else if n < len(b) {
		return "", errors.New("short write")
	}
	writer.Close()

	request, err := http.NewRequest(
		images.UploadMethod,
		images.UploadURI,
		buff,
	)
	if err != nil {
		return "", err
	}
	request.Header.Set("Authorization", "Bearer "+images.AccessToken)
	request.Header.Set("Content-Type", writer.FormDataContentType())

	c := &http.Client{Timeout: time.Minute}
	response, err := c.Do(request)
	if err != nil {
		return "", err
	}
	defer response.Body.Close()
	b, _ = ioutil.ReadAll(response.Body)
	switch response.StatusCode {
	case http.StatusOK:
	case 401, 403:
		return "", ErrBadAuth
	default:
		return "", fmt.Errorf("error uploading image: (%d) %s", response.StatusCode, b)
	}
	var result struct {
		Data struct {
			Link string `json:"link"`
		} `json:"data"`
	}
	if err := json.Unmarshal(b, &result); err != nil {
		return "", err
	}
	return result.Data.Link, nil
}
