package pdf

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"os"

	"github.com/labstack/gommon/log"
)

type PdfClient struct {
	path      string
	invoiceId string
	reportId  string
	url       string
	apiKey    string
}

func NewPdfClient(pid, rid, url, key string) (*PdfClient, error) {
	if pid == "" || rid == "" || url == "" || key == "" {
		return nil, errors.New("error building Pdf service. Verify your env variables")
	}
	return &PdfClient{
		path:      "index.html",
		invoiceId: pid,
		reportId:  rid,
		url:       url,
		apiKey:    key,
	}, nil
}

func (ps PdfClient) BuildInvoice(context map[string]any) error {
	data := struct {
		Context   map[string]any `json:"context"`
		Path      string         `json:"path"`
		ProjectId string         `json:"projectId"`
	}{
		Context:   context,
		Path:      ps.path,
		ProjectId: ps.invoiceId,
	}

	payload, err := json.Marshal(data)
	if err != nil {
		log.Warnf("Error marshalling JSON: %s", err)
		return err
	}

	return ps.sendData(payload)
}

func (ps PdfClient) BuildReport(context map[string]any, period string, month, year int) error {
	data := struct {
		Context   map[string]any `json:"context"`
		Path      string         `json:"path"`
		ProjectId string         `json:"projectId"`
	}{
		Context:   context,
		Path:      ps.path,
		ProjectId: ps.reportId,
	}

	payload, err := json.Marshal(data)
	if err != nil {
		log.Warnf("Error marshalling JSON: %s", err)
		return err
	}

	return ps.sendData(payload)
}

func (ps PdfClient) sendData(payload []byte) error {
	req, err := http.NewRequest("POST", ps.url, bytes.NewBuffer(payload))
	if err != nil {
		log.Warnf("Error creating request: %s", err)
		return err
	}

	req.Header.Set("Authorization", "Bearer "+ps.apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Warnf("Error sending request: %s", err)
		return err
	}
	defer resp.Body.Close()

	res := new(struct {
		Url   string `json:"url"`
		Error string `json:"error"`
	})
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	err = json.Unmarshal(body, res)
	if err != nil {
		log.Warnf("error decoding response: %s", err)
		return err
	}

	if res.Error != "" {
		log.Warnf("error building pdf file %s", err)
		return errors.New(res.Error)
	}

	resp, err = http.Get(res.Url)
	if err != nil {
		log.Warnf("Error retrieving file")
		return err
	}
	defer resp.Body.Close()

	file, err := os.Create("tmp.pdf")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	body, err = io.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	_, err = file.Write(body)
	if err != nil {
		log.Error("Error copying file content")
		return err
	}
	return nil
}
