package operations

import (
	"database/sql"
	"sevenkeys/scryfall/types"
	"time"
)

func InsertOrUpdateCacheTimestampByType(db *sql.DB, cacheType string, stamp time.Time) error {
	query := `INSERT INTO CacheTimestamp (CacheType, Stamp)
		VALUES (?, ?)
		ON DUPLICATE KEY
		UPDATE Stamp = ?;`

	insertOrUpdate, err := db.Prepare(query)
	defer insertOrUpdate.Close()
	if err != nil {
		return err
	}

	_, err = insertOrUpdate.Exec(cacheType, stamp, stamp)
	if err != nil {
		return err
	}

	return nil
}

// TODO: There's really no need for this to be an "upsert", we can just ignore sets that we already have
func InsertOrUpdateSet(db *sql.DB, set types.Set) error {
	query := `INSERT INTO ExpansionSet (SetCode, Name, CardCount, IconSvgUri)
		VALUES (?, ?, ?, ?)
		ON DUPLICATE KEY
		Update Name = ?, CardCount = ?, IconSvgUri = ?;`

	insertOrUpdate, err := db.Prepare(query)
	defer insertOrUpdate.Close()
	if err != nil {
		return err
	}

	_, err = insertOrUpdate.Exec(set.Code, set.Name, set.CardCount, set.IconSvgUri, set.Name, set.CardCount, set.IconSvgUri)
	if err != nil {
		return err
	}

	return nil
}

func InsertCard(db *sql.DB, card types.Card) error {
	query := `INSERT IGNORE INTO CardPrinting
		(Id, Name, SetCode, HasFoil, HasNonFoil, IsReserved, IsRacist, IsPromo, CollectorNumber, Language)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`

	insert, err := db.Prepare(query)
	defer insert.Close()
	if err != nil {
		return err
	}

	_, err = insert.Exec(card.Id, card.Name, card.Set, card.Foil, card.NonFoil, card.Reserved, card.ContentWarning, card.Promo, card.CollectorNumber, card.Language)
	if err != nil {
		return err
	}

	return nil
}

func InsertCardStorageLocation(db *sql.DB, cardPrintingId string, storageBox string, source string) error {
	var lastPosition int
	getLastPositionQuery := `SELECT Position FROM CardStorageLocation WHERE StorageBox = ? ORDER BY Position DESC LIMIT 1;`
	err := db.QueryRow(getLastPositionQuery, storageBox).Scan(&lastPosition)

	var nextPosition int
	if err == sql.ErrNoRows {
		nextPosition = 1
	} else {
		nextPosition = lastPosition + 1
	}

	insertQuery := `INSERT INTO CardStorageLocation
		(CardPrintingId, StorageBox, Source, Position)
		VALUES (?, ?, ?, ?);`
	insert, err := db.Prepare(insertQuery)
	if err != nil {
		return err
	}

	_, err = insert.Exec(cardPrintingId, storageBox, source, nextPosition)
	if err != nil {
		return err
	}

	return nil
}
