package data

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	"git.vdhsn.com/barretthousen/barretthousen/src/runner/internal/data/postgres"
	"git.vdhsn.com/barretthousen/barretthousen/src/runner/internal/domain"
)

type PGRunnerStorage struct {
	*postgres.Queries
}

func (db *PGRunnerStorage) CreateScrapeJob(ctx context.Context, target string) (sj domain.ScrapeJob, err error) {
	if target == "" {
		target = "ALL"
	}

	rsj, err := db.Queries.CreateScrapeJob(ctx, target)
	if err != nil {
		return domain.ScrapeJob{}, err
	}

	return domain.ScrapeJob{
		ID:         int(rsj.ID),
		Started:    rsj.Startedts,
		TargetSite: rsj.Targetsitename,
	}, nil
}

func (db *PGRunnerStorage) CompleteScrapeJob(ctx context.Context, ID int, status domain.CompleteScrapeJobStatus) (sj domain.ScrapeJob, err error) {
	completedTime := time.Now().UTC()
	if err = db.Queries.CompleteScrapeJob(ctx, postgres.CompleteScrapeJobParams{
		ID: int32(ID),
		Completedts: sql.NullTime{
			Time:  completedTime,
			Valid: true,
		},
		Auctionsfound: int32(status.AuctionCount),
		Errors:        status.Errors,
	}); err != nil {
		err = fmt.Errorf("could update scrape job in DB: %w", err)
		return
	}

	var rsj postgres.RunnerScrapejob
	if rsj, err = db.Queries.GetJobByID(ctx, int32(ID)); err != nil {
		err = fmt.Errorf("could not get job by ID: %w", err)
		return
	}

	sj = domain.ScrapeJob{
		ID:            ID,
		Started:       rsj.Startedts,
		Completed:     completedTime,
		TargetSite:    rsj.Targetsitename,
		AuctionsFound: status.AuctionCount,
		Errors:        status.Errors,
	}

	return
}

func (db *PGRunnerStorage) GetJobs(ctx context.Context) (results []domain.ScrapeJob, err error) {
	var jobs []postgres.RunnerScrapejob
	if jobs, err = db.Queries.GetJobs(ctx); err != nil {
		err = fmt.Errorf("Couldn't get jobs from DB: %w", err)
		return
	}

	for _, j := range jobs {
		results = append(results, domain.ScrapeJob{
			ID:            int(j.ID),
			Started:       j.Startedts,
			Completed:     j.Completedts.Time,
			TargetSite:    j.Targetsitename,
			AuctionsFound: int(j.Auctionsfound),
			Errors:        j.Errors,
		})
	}

	return
}
