package data

import (
	"context"
	"crypto/sha512"
	"fmt"
	"time"

	"git.vdhsn.com/barretthousen/barretthousen/src/catalog/internal/data/postgres"
	"git.vdhsn.com/barretthousen/barretthousen/src/catalog/internal/domain"
	"git.vdhsn.com/barretthousen/barretthousen/src/lib/kernel"
)

type PGCatalogStorage struct {
	Queries *postgres.Queries
}

func (ps *PGCatalogStorage) GetUpcoming(ctx context.Context, q domain.UpcomingQuery) (results []domain.Auction, total int64, found int64, err error) {
	var pgResults []postgres.GetUpcomingRow

	if pgResults, err = ps.Queries.GetUpcoming(ctx, postgres.GetUpcomingParams{
		Searchterm: q.Term,
		Page:       int32(q.Page),
		Pagesize:   int32(q.Limit),
	}); err != nil {
		err = fmt.Errorf("could not get upcoming auctions from pg: %w", err)
		return
	}

	var totalsRow postgres.GetTotalsRow
	if totalsRow, err = ps.Queries.GetTotals(ctx, q.Term); err != nil {
		err = fmt.Errorf("could not get total auction count: %w", err)
		return
	}

	total = totalsRow.Total
	if q.Term == "" {
		found = total
	} else {
		found = totalsRow.Found
	}

	results = make([]domain.Auction, len(pgResults))
	for idx, row := range pgResults {
		results[idx] = domain.Auction{
			ID:             int(row.ID),
			Fingerprint:    row.Fingerprint,
			Title:          row.Title,
			Description:    row.Description,
			SourceSiteURL:  row.Sourcesiteurl,
			SourceSiteName: row.Sourcesitename,
			SourceURL:      row.Sourceurl,
			Country:        row.Country,
			Province:       row.Province,
			ItemCount:      int(row.Itemcount),
			Start:          row.Startts,
			End:            row.Startts.Add(time.Hour * 8),
		}

		if row.Endts.Valid {
			results[idx].End = row.Endts.Time
		}
	}

	return
}

func (ps *PGCatalogStorage) CreateUpcoming(ctx context.Context, a domain.Auction) (fingerprint string, err error) {
	var auctionID int32

	fingerprint = fmt.Sprintf("%x", sha512.Sum512(append([]byte(a.Title), []byte(a.Description)...)))
	kernel.TraceLog.Printf("%s: %s + %s", fingerprint, a.Title, a.Description)
	if auctionID, err = ps.Queries.ImportAuction(ctx, postgres.ImportAuctionParams{
		Fingerprint:    fingerprint,
		Title:          a.Title,
		Description:    a.Description,
		Sourcesiteurl:  a.SourceSiteURL,
		Sourcesitename: a.SourceSiteName,
		Sourceurl:      a.SourceURL,
		Country:        a.Country,
		Province:       a.Province,
		Startts:        a.Start,
		Endts:          a.End,
		Itemcount:      int32(a.ItemCount),
	}); err != nil {
		err = fmt.Errorf("could not save auction to DB: %w", err)
		return
	}

	if auctionID == 0 {
		err = domain.ErrDuplicateAuctionImported
		return
	}

	return
}
