package controllers

import (
	"encoding/csv"
	"errors"
	"fmt"
	"log"
	"math"
	"os"
	"strconv"
	"time"
	"zatobay_api/database"
	"zatobay_api/models"
	"zatobay_api/utils/datatable"

	"github.com/gofiber/fiber/v2"
	strftime "github.com/itchyny/timefmt-go"
	"github.com/jung-kurt/gofpdf"
	"github.com/leekchan/accounting"
	"gorm.io/gorm"
)

type FilterAjaxOrderLoker struct {
	CategoryLoker string `json:"category_loker" url:"category_loker" query:"category_loker"`
	CodeLoker     string `json:"code_loker" url:"code_loker" query:"code_loker"`
	StartDate     string `json:"start_date" url:"start_date" query:"start_date"`
	EndDate       string `json:"end_date" url:"end_date" query:"end_date"`
	Page          string `json:"page" url:"page" query:"page"`
	PerPage       string `json:"length" url:"length" query:"length"`
	Sort          string `json:"column" url:"column" query:"column"`
	SortDir       string `json:"dir" url:"dir" query:"dir"`
	Draw          string `json:"draw" url:"draw" query:"draw"`
}

type FilterDateRangeOrderLoker struct {
	OrderCode string `json:"order_code" url:"order_code" query:"order_code"`
	StartDate string `json:"start_date" url:"start_date" query:"start_date"`
	EndDate   string `json:"end_date" url:"end_date" query:"end_date"`
}

func CreateOrderLoker(c *fiber.Ctx) error {
	var nama_kasir string

	if c.Get("Authorization") == "" {
		return c.JSON(fiber.Map{
			"message": "Auth Token must be set",
		})
	}

	err, id_kasir, nama_kasir := GetNamaKasir(c.Get("Authorization"))
	_, err_id_kasir := strconv.Atoi(id_kasir)

	if err_id_kasir != nil {
		return c.Status(400).JSON(fiber.Map{
			"status": "cannot convert cashier id",
		})
	}

	if err != nil {
		return c.Status(400).JSON(fiber.Map{
			"status": "Error get cashier name",
		})
	}

	if err_id_kasir != nil {
		return err_id_kasir
	}

	current_time := time.Now()
	curr_time := strftime.Format(current_time, "%Y%m%d%H%M%S")

	type IncomingData struct {
		OrderLoker []struct {
			Id int `json:"id"`
		} `json:"order_loker"`
		Penyewa string `json:"penyewa"`
	}

	data := IncomingData{}

	if err := c.BodyParser(&data); err != nil {
		return c.Status(400).JSON(err.Error())
	}

	var totalPrice int

	for _, x := range data.OrderLoker {
		loker := models.Loker{}
		result := database.DB.Preload("CategoryLoker").First(&loker, x.Id)
		if result.Error != nil {
			return c.Status(400).JSON(fiber.Map{
				"status": "Loker Tidak Ditemukan",
				"Error":  result.Error,
			})
		}
		totalPrice = totalPrice + loker.CategoryLoker.Price
	}

	orderLoker := models.OrderLoker{
		OrderCode:  "LOKER" + curr_time,
		Quantity:   len(data.OrderLoker),
		PriceTotal: totalPrice,
		Trxdate:    time.Now(),
		Penyewa:    data.Penyewa,
		NamaAdmin:  nama_kasir,
	}

	create_order := database.DB.Create(&orderLoker)
	if create_order.Error != nil {
		return c.Status(400).JSON(fiber.Map{
			"status": "Error",
			"Error":  create_order.Error,
		})
	}

	orderResponse := orderLoker.ToResponse()
	var detailResponse []models.ResponseOrderLokerDetail

	for _, y := range data.OrderLoker {
		loker := models.Loker{}
		result := database.DB.Preload("CategoryLoker").First(&loker, y.Id)
		if result.Error != nil {
			return c.Status(400).JSON(err.Error())
		}

		loker.Status = "0"

		resultUpdate := database.DB.Table("lokers").Where("id = ?", y.Id).Updates(&loker)

		if resultUpdate.RowsAffected == 0 {
			return c.Status(400).JSON(fiber.Map{
				"status": "Error Update Loker",
				"Error":  resultUpdate.Error,
			})
		}

		detailLoker := models.OrderLokerDetail{
			OrderLokerId: int(orderLoker.Id),
			LokerId:      y.Id,
			Loker:        loker,
		}
		results := database.DB.Create(&detailLoker)
		if results.Error != nil {
			return c.Status(400).JSON(err.Error())
		}

		orderLoker.OrderLokerDetails = append(orderLoker.OrderLokerDetails, detailLoker)
		detailResponse = append(detailResponse, *detailLoker.ToResponse())
	}

	return c.Status(200).JSON(fiber.Map{
		"status":  "successs",
		"data":    orderResponse,
		"details": detailResponse,
	})
}

func GetOrderLokerById(c *fiber.Ctx) error {

	var data models.OrderLoker

	paramsId := c.Params("id")

	id_int, err := strconv.Atoi(paramsId)

	if err != nil {
		return err
	}

	result := database.DB.Preload("OrderLokerDetails").Preload("OrderLokerDetails.Loker").Preload("OrderLokerDetails.Loker.CategoryLoker").First(&data, id_int)

	if result.RowsAffected == 0 {
		return c.SendStatus(404)
	}

	var dataDetails []models.OrderLokerDetail

	resultDetail := database.DB.Preload("Loker").Preload("Loker.CategoryLoker").Where("order_loker_id = ?", data.Id).Find(&dataDetails)
	if resultDetail.RowsAffected == 0 {
		return c.SendStatus(404)
	}

	detailResponse := models.ToResponses(dataDetails)

	return c.Status(200).JSON(fiber.Map{
		"message": "success",
		"data":    data.ToResponse(),
		"details": detailResponse,
	})
}

func OrderLokerAjaxList(c *fiber.Ctx) error {

	filterAjax := new(FilterAjaxOrderLoker)

	if err := c.QueryParser(filterAjax); err != nil {
		return c.Status(400).JSON(err.Error())
	}

	page, err := strconv.Atoi(filterAjax.Page)
	if err != nil {
		page = 1
	}
	perPage, err := strconv.Atoi(filterAjax.PerPage)
	if err != nil {
		perPage = 10
	}

	order_loker := models.OrderLoker{
		OrderCode: filterAjax.CodeLoker,
	}

	var sort map[string]string
	sort = make(map[string]string)
	if filterAjax.Sort != "" {
		if filterAjax.SortDir == "" {
			sort[filterAjax.Sort] = "desc"
		} else {
			sort[filterAjax.Sort] = filterAjax.SortDir
		}
	}
	limit := perPage
	offset := (page - 1) * limit

	var start, end string

	if filterAjax.StartDate != "" && filterAjax.EndDate != "" {
		start = filterAjax.StartDate + " 00:00:00"
		end = filterAjax.EndDate + " 23:59:59"
	}

	fmt.Println(start)
	fmt.Println(end)

	data, total, err := OrderLokerQueryAjaxList(order_loker, limit, offset, sort, start, end)
	fmt.Println(data)

	if err != nil {
		return c.Status(400).JSON(err.Error())
	}
	pages := math.Ceil(float64(*total) / float64(perPage))
	meta := datatable.MetaDataTable{
		CurrentPage: page,
		From:        offset + 1,
		LastPage:    int(pages),
		Path:        "",
		PerPage:     fmt.Sprintf("%v", limit),
		To:          offset + limit,
		Total:       int(*total),
	}

	datatableFormat := datatable.DataTable{
		Meta: datatable.MetaDataTable{
			CurrentPage: page,
			From:        0,
			LastPage:    1,
			Path:        *datatable.BuildUrlForLink(c.Request(), 0),
			PerPage:     strconv.Itoa(perPage),
			To:          0,
			Total:       0,
		},
		Data: nil,
		Links: datatable.LinkDatatable{
			First: *datatable.BuildUrlForLink(c.Request(), 1),
			Last:  nil,
			Next:  nil,
			Prev:  nil,
		},
		Payload: filterAjax,
	}

	if err == nil {
		var dataResponseOrderLoker []models.OrderLoker

		for _, data := range data {
			dataResponseOrderLoker = append(dataResponseOrderLoker, data)
		}

		datatableFormat.Data = dataResponseOrderLoker
		meta.Path = *datatable.BuildUrlForLink(c.Request(), 0)
		datatableFormat.Meta = meta
		datatableFormat.Links = datatable.BuildLinksData(c.Request(), meta)
	}

	type MetaInfo struct {
		TotalIncome int64 `json:"total_income"`
		TotalTrx    int64 `json:"total_trx"`
	}

	var results MetaInfo

	database.DB.Table("order_lokers").Select("sum(cast(price_total as int)) as total_income, count(*) as total_trx").Where(order_loker).Where("trxdate between ? and ?", start, end).Scan(&results)
	fmt.Print(results)

	return c.JSON(fiber.Map{
		"message": "success",
		"info":    results,
		"data":    datatableFormat,
	})
}

func OrderLokerQueryAjaxList(filter models.OrderLoker, limit, offset int, sort map[string]string, start string, end string) ([]models.OrderLoker, *int64, error) {
	var (
		result         []models.OrderLoker
		count          int64
		query, dbCount *gorm.DB
	)

	if start == "" {
		query = database.DB.Where(filter)
	} else {
		query = database.DB.Where(filter).Where("trxdate BETWEEN ? AND ?", start, end)
	}

	if sort == nil {
		query = query.Order("id")
	} else {
		for key, val := range sort {
			query = query.Order(fmt.Sprintf("%s %s", key, val))
		}
	}
	query = query.Offset(offset).Limit(limit).Find(&result)
	fmt.Println(query)
	if query.Error != nil {
		return nil, nil, query.Error
	}
	if start == "" {
		dbCount = database.DB.Table("order_lokers").Where(filter).Select("id").Count(&count)
	} else {
		dbCount = database.DB.Table("order_lokers").Where(filter).Where("trxdate BETWEEN ? AND ?", start, end).Select("id").Count(&count)
	}

	if dbCount.Error != nil {
		return nil, nil, dbCount.Error
	}
	return result, &count, nil

}

func OrderLokerDaily(c *fiber.Ctx) error {
	// var order models.Orders
	// var res_daily_order []models.DailyOrder
	t := time.Now()
	curr_time := strftime.Format(t, "%Y-%m-%d")
	start_time := curr_time + " 00:00:00"
	end_time := curr_time + " 23:59:59"
	fmt.Println(start_time, end_time)

	// Select `id`, `name` automatically when querying
	// .Where("category IN ?", [][]interface{}{{"UMUM", "SEKOLAH"}})
	// order_daily := database.DB.Model(&order).Where("trxdate between ? and ?", start_time, end_time).Group("ticket_name").Find(&res_daily_order)

	type MetaInfo struct {
		Price       int64 `json:"price"`
		TotalIncome int64 `json:"total_income"`
		TotalTrx    int64 `json:"total_trx"`
	}

	var data MetaInfo

	database.DB.Table("order_loker_details").Select(" loker_categories.price as price, sum(loker_categories.price) as total_income, count(*) as total_trx").Joins("left join lokers on lokers.id = loker_id").Joins("left join loker_categories on loker_categories.id = lokers.category_loker_id").Joins("left join order_lokers on order_lokers.id = order_loker_id").Where("trxdate between ? and ?", start_time, end_time).Scan(&data)

	return c.Status(200).JSON(fiber.Map{
		"data":   data,
		"status": "success",
		"time":   t,
	})
}

func OrderLokerAjaxListCashierDaily(c *fiber.Ctx) error {

	filterAjax := new(FilterAjaxOrderLoker)

	var start, end string

	t := time.Now()
	curr_time := strftime.Format(t, "%Y-%m-%d")
	start = curr_time + " 00:00:00"
	end = curr_time + " 23:59:59"

	if err := c.QueryParser(filterAjax); err != nil {
		return c.Status(400).JSON(err.Error())
	}

	page, err := strconv.Atoi(filterAjax.Page)
	if err != nil {
		page = 1
	}
	perPage, err := strconv.Atoi(filterAjax.PerPage)
	if err != nil {
		perPage = 9999
	}

	order_loker := models.OrderLoker{
		OrderCode: filterAjax.CodeLoker,
	}

	var sort map[string]string
	sort = make(map[string]string)
	if filterAjax.Sort != "" {
		if filterAjax.SortDir == "" {
			sort[filterAjax.Sort] = "desc"
		} else {
			sort[filterAjax.Sort] = filterAjax.SortDir
		}
	}
	limit := perPage
	offset := (page - 1) * limit

	data, total, err := OrderLokerQueryAjaxListCashierDaily(order_loker, limit, offset, sort, start, end)
	fmt.Println(data)

	if err != nil {
		return c.Status(400).JSON(err.Error())
	}
	pages := math.Ceil(float64(*total) / float64(perPage))
	meta := datatable.MetaDataTable{
		CurrentPage: page,
		From:        offset + 1,
		LastPage:    int(pages),
		Path:        "",
		PerPage:     fmt.Sprintf("%v", limit),
		To:          offset + limit,
		Total:       int(*total),
	}

	datatableFormat := datatable.DataTable{
		Meta: datatable.MetaDataTable{
			CurrentPage: page,
			From:        0,
			LastPage:    1,
			Path:        *datatable.BuildUrlForLink(c.Request(), 0),
			PerPage:     strconv.Itoa(perPage),
			To:          0,
			Total:       0,
		},
		Data: nil,
		Links: datatable.LinkDatatable{
			First: *datatable.BuildUrlForLink(c.Request(), 1),
			Last:  nil,
			Next:  nil,
			Prev:  nil,
		},
		Payload: filterAjax,
	}

	if err == nil {
		var dataResponseOrderLoker []models.OrderLoker

		for _, data := range data {
			dataResponseOrderLoker = append(dataResponseOrderLoker, data)
		}

		datatableFormat.Data = dataResponseOrderLoker
		meta.Path = *datatable.BuildUrlForLink(c.Request(), 0)
		datatableFormat.Meta = meta
		datatableFormat.Links = datatable.BuildLinksData(c.Request(), meta)
	}

	type MetaInfo struct {
		TotalIncome int64 `json:"total_income"`
		TotalTrx    int64 `json:"total_trx"`
	}

	var results MetaInfo

	database.DB.Table("order_lokers").Select("sum(cast(price_total as int)) as total_income, count(*) as total_trx").Where(order_loker).Where("trxdate between ? and ?", start, end).Scan(&results)

	return c.JSON(fiber.Map{
		"message": "success",
		"info":    results,
		"data":    datatableFormat,
	})
}

func OrderLokerQueryAjaxListCashierDaily(filter models.OrderLoker, limit, offset int, sort map[string]string, start string, end string) ([]models.OrderLoker, *int64, error) {
	var (
		result         []models.OrderLoker
		count          int64
		query, dbCount *gorm.DB
	)

	if start == "" {
		query = database.DB.Where(filter)
	} else {
		query = database.DB.Where(filter).Where("trxdate BETWEEN ? AND ?", start, end)
	}

	if sort == nil {
		query = query.Order("id")
	} else {
		for key, val := range sort {
			query = query.Order(fmt.Sprintf("%s %s", key, val))
		}
	}
	query = query.Offset(offset).Limit(limit).Order("trxdate desc").Find(&result)
	fmt.Println(query)
	if query.Error != nil {
		return nil, nil, query.Error
	}
	if start == "" {
		dbCount = database.DB.Table("order_lokers").Where(filter).Select("id").Count(&count)
	} else {
		dbCount = database.DB.Table("order_lokers").Where(filter).Where("trxdate BETWEEN ? AND ?", start, end).Select("id").Count(&count)
	}

	if dbCount.Error != nil {
		return nil, nil, dbCount.Error
	}
	return result, &count, nil

}

func ExportOrderLoker(c *fiber.Ctx) error {
	filter := new(FilterDateRangeOrderLoker)

	if err := c.QueryParser(filter); err != nil {
		return c.Status(400).JSON(err.Error())
	}

	type MetaInfo struct {
		TotalLoker  int64 `json:"total_loker"`
		TotalIncome int64 `json:"total_income"`
		TotalTrx    int64 `json:"total_trx"`
	}

	var info = new(MetaInfo)

	order := models.OrderLoker{
		OrderCode: filter.OrderCode,
	}

	start := filter.StartDate + " 00:00:00"
	end := filter.EndDate + " 23:59:59"
	fmt.Println(start)
	data, totalTrx, totalLoker, totalIncome, err := OrderLokerQueryExport(order, start, end)
	if err != nil {
		return c.Status(400).JSON(err.Error())
	}

	info.TotalTrx = totalTrx
	info.TotalLoker = totalLoker
	info.TotalIncome = totalIncome

	return c.Status(200).JSON(fiber.Map{
		"info":   info,
		"data":   data,
		"status": "success",
	})
}

func OrderLokerQueryExport(filter models.OrderLoker, start string, end string) ([]models.OrderLoker, int64, int64, int64, error) {
	var (
		result                                   []models.OrderLoker
		countTrx, countLoker, countIncome        int64
		query, totalTrx, totalLoker, totalIncome *gorm.DB
	)

	query = database.DB.Where(filter).Where("trxdate BETWEEN ? AND ?", start, end)

	query = query.Find(&result)
	if query.Error != nil {
		return nil, 0, 0, 0, query.Error
	}

	totalTrx = database.DB.Table("order_lokers").Where(filter).Where("trxdate BETWEEN ? AND ?", start, end).Count(&countTrx)

	if totalTrx.Error != nil {
		return nil, 0, 0, 0, query.Error
	}

	totalLoker = database.DB.Table("order_lokers").Select("sum(quantity) as total_loker").Where(filter).Where("trxdate BETWEEN ? AND ?", start, end).Scan(&countLoker)

	if totalLoker.Error != nil {
		return nil, 0, 0, 0, query.Error
	}

	totalIncome = database.DB.Table("order_lokers").Select("sum(cast(price_total as int)) as total_income").Where(filter).Where("trxdate BETWEEN ? AND ?", start, end).Scan(&countIncome)

	if totalIncome.Error != nil {
		return nil, 0, 0, 0, query.Error
	}

	return result, countTrx, countLoker, countIncome, nil

}

func DeleteOrderLoker(c *fiber.Ctx) error {

	id := c.Params("id")
	id_int, err := strconv.Atoi(id)

	if err != nil {
		id_int = -1
	}

	var data models.OrderLoker

	result := database.DB.Delete(&data, id_int)

	if result.RowsAffected == 0 {
		return c.SendStatus(404)
	}

	return c.Status(200).JSON(fiber.Map{
		"message": "success delete order loker, id :" + id,
		"status":  "success",
	})
}

func PrintPdfOrderLoker(c *fiber.Ctx) error {

	// filter := new(FilterDateRange)
	filter := new(FilterAjaxOrderLoker)

	if err := c.QueryParser(filter); err != nil {
		return c.Status(400).JSON(err.Error())
	}

	type MetaInfo struct {
		TotalLoker  int64 `json:"total_loker"`
		TotalIncome int64 `json:"total_income"`
		TotalTrx    int64 `json:"total_trx"`
	}

	var info = new(MetaInfo)

	order := models.OrderLoker{}

	start := filter.StartDate + " 00:00:00"
	end := filter.EndDate + " 23:59:59"
	fmt.Println(start)
	_, totalTrx, totalLoker, totalIncome, err := OrderLokerQueryExport(order, start, end)
	if err != nil {
		return c.Status(400).JSON(err.Error())
	}

	info.TotalTrx = totalTrx
	info.TotalLoker = totalLoker
	info.TotalIncome = totalIncome

	fmt.Println("TOTAL INCOME")
	fmt.Print(info.TotalIncome)

	// data group by ticket name

	type Result struct {
		CodeLoker  string `json:"code_loker"`
		PriceTotal string `json:"price_total"`
		Total      int64  `json:"total"`
	}

	var results []Result

	database.DB.Table("order_loker_details").Select("lokers.code as code_loker, loker_categories.price as price_total, count(*) as total").Joins("left join lokers on lokers.id = loker_id").Joins("left join loker_categories on loker_categories.id = lokers.category_loker_id").Where("order_loker_details.created_at between ? and ?", start, end).Where(order).Group("lokers.code").Group("loker_categories.price").Scan(&results)
	fmt.Print(results)

	// create csv file

	file, err := os.Create("./print/order_loker.csv")
	defer file.Close()
	if err != nil {
		log.Fatalln("failed to open file", err)
	}
	w := csv.NewWriter(file)
	defer w.Flush()

	// define column headers
	headers := []string{
		"Code Loker",
		"Price",
		" Terjual",
	}

	w.Write(headers)

	fmt.Println(headers)

	var data_csv [][]string
	for _, record := range results {
		row := []string{record.CodeLoker, record.PriceTotal, strconv.Itoa(int(record.Total))}
		data_csv = append(data_csv, row)
	}

	w.WriteAll(data_csv)

	// // load csv

	if _, err := os.Stat(path_order_loker()); errors.Is(err, os.ErrNotExist) {
		return c.SendStatus(404)
	}

	data_pdf := loadCSV(path_order_loker())

	pdf := gofpdf.New("P", "mm", "A4", "")

	pdf.AddPage()

	pdf.SetFont("Helvetica", "", 12)
	pdf.WriteAligned(0, 38, fmt.Sprintf("Dari Tanggal : %s", filter.StartDate), "R")
	pdf.Ln(5)
	pdf.WriteAligned(0, 38, fmt.Sprintf("Sampai Tanggal : %s", filter.EndDate), "R")
	pdf.SetFont("Arial", "B", 24)
	pdf.WriteAligned(0, 35, "Zatobay Report", "C")

	pdf = image(pdf)
	ac := accounting.Accounting{Symbol: "Rp.", Precision: 2, Thousand: ".", Decimal: ","}

	pdf.Ln(10)
	pdf.SetFont("Helvetica", "", 12)

	pdf.WriteAligned(0, 38, fmt.Sprintf("Total Pendapatan : %s", ac.FormatMoney(totalIncome)), "L")
	pdf.Ln(5)
	pdf.WriteAligned(0, 38, fmt.Sprintf("Total Transaksi	: %d", totalTrx), "L")
	pdf.Ln(5)
	pdf.WriteAligned(0, 38, fmt.Sprintf("Total Loker Terjual	: %d", totalLoker), "L")
	pdf.Ln(30)

	pdf = header(pdf, data_pdf[0])
	pdf = table(pdf, data_pdf[1:])

	if pdf.Err() {
		log.Fatalf("Failed creating PDF report: %s\n", pdf.Error())
	}

	pdf_path := "./print/order_loker.pdf"

	err_pdf := pdf.OutputFileAndClose(pdf_path)
	if err_pdf != nil {
		log.Println("ERROR", err.Error())
	}

	if _, err := os.Stat(pdf_path); errors.Is(err, os.ErrNotExist) {
		return c.SendStatus(404)
	}

	return c.Download(pdf_path)

}

func path_order_loker() string {
	if len(os.Args) < 2 {
		return "./print/order_loker.csv"
	}
	return os.Args[1]
}

// func loadCSVOrderBan(path string) [][]string {
// 	f, err := os.Open(path)
// 	if err != nil {
// 		log.Fatalf("Cannot open '%s': %s\n", path, err.Error())
// 	}
// 	defer f.Close()
// 	r := csv.NewReader(f)
// 	rows, err := r.ReadAll()
// 	if err != nil {
// 		log.Fatalln("Cannot read CSV data:", err.Error())
// 	}
// 	return rows
// }

// func header(pdf *gofpdf.Fpdf, hdr []string) *gofpdf.Fpdf {
// 	pdf.SetFont("Times", "B", 14)
// 	pdf.SetFillColor(240, 240, 240)
// 	for _, str := range hdr {
// 		// The `CellFormat()` method takes a couple of parameters to format
// 		// the cell. We make use of this to create a visible border around
// 		// the cell, and to enable the background fill.
// 		pdf.CellFormat(45, 7, str, "1", 0, "", true, 0, "")
// 	}

// 	// Passing `-1` to `Ln()` uses the height of the last printed cell as
// 	// the line height.
// 	pdf.Ln(-1)
// 	return pdf
// }

// ## The Table Body

// In the same fashion, we can create the table body.

// func table(pdf *gofpdf.Fpdf, tbl [][]string) *gofpdf.Fpdf {
// 	// Reset font and fill color.
// 	pdf.SetFont("Times", "", 10)
// 	pdf.SetFillColor(255, 255, 255)

// 	// Every column gets aligned according to its contents.
// 	align := []string{"L", "C", "L", "L", "R", "R"}
// 	for _, line := range tbl {
// 		for i, str := range line {
// 			// Again, we need the `CellFormat()` method to create a visible
// 			// border around the cell. We also use the `alignStr` parameter
// 			// here to print the cell content either left-aligned or
// 			// right-aligned.
// 			pdf.CellFormat(45, 7, str, "1", 0, align[i], false, 0, "")
// 		}
// 		pdf.SetFooterFunc(func() {
// 			// Position at 1.5 cm from bottom
// 			pdf.SetY(-15)
// 			// Arial italic 8
// 			pdf.SetFont("Arial", "I", 8)
// 			// Text color in gray
// 			pdf.SetTextColor(128, 128, 128)
// 			// Page number
// 			pdf.CellFormat(0, 10, fmt.Sprintf("Page %d", pdf.PageNo()),
// 				"", 0, "C", false, 0, "")
// 		})
// 		pdf.Ln(-1)
// 	}
// 	return pdf
// }

// // ## The Image

// // Next, let's not forget to impress our boss by adding a fancy image.
// func image(pdf *gofpdf.Fpdf) *gofpdf.Fpdf {
// 	// The `ImageOptions` method takes a file path, x, y, width, and height
// 	// parameters, and an `ImageOptions` struct to specify a couple of options.
// 	pdf.ImageOptions("./img/zatobay-print.jpg", 10, 10, 70, 22, false, gofpdf.ImageOptions{ImageType: "JPG", ReadDpi: true}, 0, "")
// 	return pdf
// }

// ## Saving The Document
//
// Finally, the convenience method `OutputFileAndClose()` lets us save the
// finished document.
func savePDFOrderLoker(pdf *gofpdf.Fpdf) error {
	return pdf.OutputFileAndClose("report_order_loker.pdf")
}
