package logic

import (
	"bytes"
	"errors"
	"fmt"
	"fonchain-fiee/pkg/model"
	"fonchain-fiee/pkg/service/bundle/common"
	"fonchain-fiee/pkg/service/upload"
	"github.com/signintech/gopdf"
	"go.uber.org/zap"
	"image"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)

func SignContract(customerNum string, contract string, signImgPath string) (outputUrl string, err error) {
	filePath := model.MediaPath + customerNum + time.Now().Format("20060102150405") + ".pdf"
	downloadFileErr := DownloadFile(filePath, contract)
	if downloadFileErr != nil {
		zap.L().Error("download file error: ", zap.Error(downloadFileErr))
		//service.Error(c, errors.New(common.ErrorDownloadFile))
		return outputUrl, errors.New(common.ErrorDownloadFile)
	}

	signFile := model.MediaPath + customerNum + "signed" + time.Now().Format("20060102150405") + ".pdf"

	signErr := InsertSignature(filePath, signFile, signImgPath)
	if signErr != nil {
		zap.L().Error("insert signature error: ", zap.Error(signErr))
		return outputUrl, errors.New(common.ErrorInsertSignature)
	}

	os.Remove(filePath)

	outputUrl, ossErr := upload.PutBos(signFile, upload.PdfType, true)
	if ossErr != nil {
		return "", errors.New(common.ErrorUploadFile)
	}
	return outputUrl, nil
}

// InsertSignature 把用户签字内容 填充到 合同模版里面
func InsertSignature(templatePath string, outputPath string, signImgPath string) error {
	pdf := gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})

	resp, imageErr := http.Get(signImgPath)
	if imageErr != nil {
		return errors.New("error downloading signature image")
	}
	defer resp.Body.Close()

	b, _err := io.ReadAll(resp.Body)
	if _err != nil {
		return errors.New("error reading signature image")
	}

	// Create a new reader from the bytes
	imgReader := bytes.NewReader(b)
	img, _, err := image.DecodeConfig(imgReader)
	if err != nil {
		return errors.New("error decoding signature image")
	}
	w := img.Width
	h := img.Height

	// 导入模板文件中的页面
	err = pdf.ImportPagesFromSource(templatePath, "/MediaBox")
	if err != nil {
		log.Fatalf("无法导入页面: %v", err)
	}

	// 获取模板文件的总页数
	totalPages := pdf.GetNumberOfPages()
	fmt.Printf("模板文件的总页数: %d\n", totalPages)

	targetPage := totalPages

	// 遍历所有页
	for i := 1; i <= totalPages; i++ {
		tpl := pdf.ImportPage(templatePath, i, "/MediaBox")
		pdf.AddPage()
		pdf.UseImportedTemplate(tpl, 0, 0, gopdf.PageSizeA4.W, gopdf.PageSizeA4.H)
		// 只在目标页插入签名
		if i == targetPage {

			imgH1, _err := gopdf.ImageHolderByBytes(b)
			if _err != nil {
				//zap.L().Error("SignContract err", zap.Error(err))
				return errors.New("error processing signature image")
			}
			newWidth := 80.0
			newHeight := (newWidth / float64(w)) * float64(h)
			err = pdf.ImageByHolder(imgH1, 380, 540, &gopdf.Rect{W: newWidth, H: newHeight})
			if err != nil {
				//zap.L().Error("SignContract err", zap.Error(err))
				return errors.New("error inserting signature")
			}
		}
	}

	// 生成新的 PDF
	if err = pdf.WritePdf(outputPath); err != nil {
		//zap.L().Error("WritePdf err", zap.Error(err))
		return errors.New("error writing final PDF")
	}

	return nil
}

func DownloadFile(filepath string, url string) error {
	resp, err := http.Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	out, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer out.Close()

	_, err = io.Copy(out, resp.Body)
	return err
}