package invoice

import (
	"archive/zip"
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"

	"dev.tandem.ws/tandem/camper/pkg/auth"
	"dev.tandem.ws/tandem/camper/pkg/database"
	"dev.tandem.ws/tandem/camper/pkg/template"
)

func mustWriteInvoicesPdf(r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, slugs []string) []byte {
	buf := new(bytes.Buffer)
	w := zip.NewWriter(buf)
	for _, slug := range slugs {
		inv := mustGetInvoice(r.Context(), conn, company, slug)
		if inv == nil {
			continue
		}
		f, err := w.Create(fmt.Sprintf("%s-%s.pdf", inv.Number, template.Slugify(inv.Invoicee.Name)))
		if err != nil {
			panic(err)
		}
		mustWriteInvoicePdf(f, r, user, company, inv)
	}
	mustClose(w)
	return buf.Bytes()
}

func mustWriteInvoicePdf(w io.Writer, r *http.Request, user *auth.User, company *auth.Company, inv *invoice) {
	cmd := exec.Command("weasyprint", "--stylesheet", "web/static/invoice.css", "-", "-")
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	stdin, err := cmd.StdinPipe()
	if err != nil {
		panic(err)
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		panic(err)
	}
	defer func() {
		err := stdout.Close()
		if !errors.Is(err, os.ErrClosed) {
			panic(err)
		}
	}()
	if err = cmd.Start(); err != nil {
		panic(err)
	}
	go func() {
		defer mustClose(stdin)
		template.MustRenderAdmin(stdin, r, user, company, "invoice/view.gohtml", inv)
	}()
	if _, err = io.Copy(w, stdout); err != nil {
		panic(err)
	}
	if err := cmd.Wait(); err != nil {
		log.Printf("ERR - %v\n", stderr.String())
		panic(err)
	}
}

func mustClose(closer io.Closer) {
	if err := closer.Close(); err != nil {
		panic(err)
	}
}
