package repositories

import (
	"strconv"

	"gorm.io/gorm"

	"git.dynamicdiscord.de/kalipso/zineshop/models"
)

type InvoiceRepository interface {
	Create(models.Invoice) (models.Invoice, error)
	GetAll() ([]models.Invoice, error)
	GetAllSorted(string) ([]models.Invoice, error)
	GetAllNewestFirst() ([]models.Invoice, error)
	GetAllNewestLast() ([]models.Invoice, error)
	GetById(string) (models.Invoice, error)
	//GetByInvoiceId(string) (models.Invoice, error)
	Update(models.Invoice) (models.Invoice, error)
	DeleteById(string) error
}

type GORMInvoiceRepository struct {
	DB *gorm.DB
}

func NewGORMInvoiceRepository(db *gorm.DB) InvoiceRepository {
	return &GORMInvoiceRepository{
		DB: db,
	}
}

func (t *GORMInvoiceRepository) Create(invoice models.Invoice) (models.Invoice, error) {
	result := t.DB.Create(&invoice)

	if result.Error != nil {
		return models.Invoice{}, result.Error
	}

	return invoice, nil
}

func (t *GORMInvoiceRepository) GetAll() ([]models.Invoice, error) {
	var invoice []models.Invoice
	result := t.DB.Preload("PrintJobs.ShopItem").Preload("PrintJobs.Variant").Preload("PrintJobs.PaperType").Preload("PrintJobs.CoverPaperType").Preload("PrintJobs").Find(&invoice)

	return invoice, result.Error
}

func (t *GORMInvoiceRepository) GetAllSorted(sortString string) ([]models.Invoice, error) {
	var invoices []models.Invoice
	result := t.DB.Preload("PrintJobs.ShopItem").Preload("PrintJobs.Variant").Preload("PrintJobs.PaperType").Preload("PrintJobs.CoverPaperType").Preload("PrintJobs").Order(sortString).Find(&invoices)

	return invoices, result.Error
}

func (r *GORMInvoiceRepository) GetAllNewestFirst() ([]models.Invoice, error) {
	return r.GetAllSorted("created_at desc")
}

func (r *GORMInvoiceRepository) GetAllNewestLast() ([]models.Invoice, error) {
	return r.GetAllSorted("created_at asc")
}

func (t *GORMInvoiceRepository) GetById(id string) (models.Invoice, error) {
	invoiceId, err := strconv.Atoi(id)

	if err != nil {
		return models.Invoice{}, err
	}

	var invoice models.Invoice
	result := t.DB.Preload("PrintJobs").First(&invoice, uint(invoiceId))

	if result.Error != nil {
		return models.Invoice{}, result.Error
	}

	return invoice, nil
}

func (t *GORMInvoiceRepository) Update(invoice models.Invoice) (models.Invoice, error) {
	result := t.DB.Save(&invoice)
	if result.Error != nil {
		return models.Invoice{}, result.Error
	}

	return invoice, nil
}

func (t *GORMInvoiceRepository) DeleteById(id string) error {
	invoiceId, err := strconv.Atoi(id)

	if err != nil {
		return err
	}

	result := t.DB.Delete(&models.Invoice{}, invoiceId)
	return result.Error
}
