package models

// BookPublisher struct to join books with publishers
type BookPublisher struct {
	Book      `xorm:"extends"`
	Publisher `xorm:"extends"`
}

// ListBooks returns a list with all books, filtered by an optional searchstring
func ListBooks(searchterm string) (books []*Book, err error) {

	if searchterm == "" {
		err = x.Table("books").
			Find(&books)
		if err != nil {
			return []*Book{}, err
		}
	} else {
		err = x.Where("title LIKE ?", "%"+searchterm+"%").Find(&books)
		if err != nil {
			return []*Book{}, err
		}
	}

	// Get all publishers and quantities to afterwards loop though them (less sql queries -> more performance)
	// Publishers
	pubs, err := ListPublishers("")
	if err != nil {
		return []*Book{}, err
	}

	// Quantites
	allq := []Quantity{}
	err = x.Table("quantities").
		Select("quantities.id, quantity_relations.book_id AS item_id, quantities.quantity, quantities.created").
		Join("INNER", "quantity_relations", "quantities.item_id = quantity_relations.id").
		Where("quantity_relations.book_id != 0").
		Desc("quantities.created").
		Find(&allq)

	// Link them
	for i, book := range books {

		// Set quantities
		for _, qy := range allq {
			if qy.ItemID == book.ID {
				books[i].Quantity = qy.Quantity
				break // Take the first quantity you find and exit
			}
		}

		// Get publisher
		for _, pub := range pubs {
			if pub.ID == book.PublisherID {
				books[i].Publisher = pub
				break // Take the first quantity you find and exit
			}
		}

		// Get all authors
		books[i].Authors, err = GetAuthorsByBook(*book)
		if err != nil {
			return []*Book{}, err
		}
	}

	return books, err
}
