package repository

import (
	"context"

	dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
	"github.com/jackc/pgx/v5/pgtype"
)

func convertDBResult(result dbgen.Result) domain.Result {
	scores := make(map[string]domain.Score)
	return domain.Result{
		ID:            result.ID,
		BetOutcomeID:  result.BetOutcomeID,
		EventID:       result.EventID,
		OddID:         result.OddID,
		MarketID:      result.MarketID,
		Status:        domain.OutcomeStatus(result.Status),
		Score:         result.Score.String,
		FullTimeScore: result.FullTimeScore.String,
		HalfTimeScore: result.HalfTimeScore.String,
		SS:            result.Ss.String,
		Scores:        scores,
		CreatedAt:     result.CreatedAt.Time,
		UpdatedAt:     result.UpdatedAt.Time,
	}
}

func convertCreateResult(result domain.CreateResult) dbgen.CreateResultParams {
	return dbgen.CreateResultParams{
		BetOutcomeID: result.BetOutcomeID,
		EventID:      result.EventID,
		OddID:        result.OddID,
		MarketID:     result.MarketID,
		Status:       int32(result.Status),
		Score:        pgtype.Text{String: result.Score},
	}
}

func convertResult(result domain.Result) dbgen.InsertResultParams {
	return dbgen.InsertResultParams{
		BetOutcomeID:  result.BetOutcomeID,
		EventID:       result.EventID,
		OddID:         result.OddID,
		MarketID:      result.MarketID,
		Status:        int32(result.Status),
		Score:         pgtype.Text{String: result.Score},
		FullTimeScore: pgtype.Text{String: result.FullTimeScore},
		HalfTimeScore: pgtype.Text{String: result.HalfTimeScore},
		Ss:            pgtype.Text{String: result.SS},
	}
}

func (s *Store) CreateResult(ctx context.Context, result domain.CreateResult) (domain.Result, error) {
	dbResult, err := s.queries.CreateResult(ctx, convertCreateResult(result))
	if err != nil {
		return domain.Result{}, err
	}
	return convertDBResult(dbResult), nil
}

func (s *Store) InsertResult(ctx context.Context, result domain.Result) error {
	return s.queries.InsertResult(ctx, convertResult(result))
}

func (s *Store) GetResultByBetOutcomeID(ctx context.Context, betOutcomeID int64) (domain.Result, error) {
	dbResult, err := s.queries.GetResultByBetOutcomeID(ctx, betOutcomeID)
	if err != nil {
		return domain.Result{}, err
	}
	return convertDBResult(dbResult), nil
}

func (s *Store) GetPendingBetOutcomes(ctx context.Context) ([]domain.BetOutcome, error) {
	dbOutcomes, err := s.queries.GetPendingBetOutcomes(ctx)
	if err != nil {
		return nil, err
	}
	outcomes := make([]domain.BetOutcome, 0, len(dbOutcomes))
	for _, dbOutcome := range dbOutcomes {
		outcomes = append(outcomes, domain.BetOutcome{
			ID:           dbOutcome.ID,
			BetID:        dbOutcome.BetID,
			EventID:      dbOutcome.EventID,
			OddID:        dbOutcome.OddID,
			HomeTeamName: dbOutcome.HomeTeamName,
			AwayTeamName: dbOutcome.AwayTeamName,
			MarketID:     dbOutcome.MarketID,
			MarketName:   dbOutcome.MarketName,
			Odd:          dbOutcome.Odd,
			OddName:      dbOutcome.OddName,
			OddHeader:    dbOutcome.OddHeader,
			OddHandicap:  dbOutcome.OddHandicap,
			Status:       domain.OutcomeStatus(dbOutcome.Status),
			Expires:      dbOutcome.Expires.Time,
		})
	}
	return outcomes, nil
}
