package bunmodel

import (
	"fmt"
	"time"

	"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
	"github.com/uptrace/bun"
)

type PlayerSnapshot struct {
	bun.BaseModel `bun:"table:player_snapshots,alias:ps"`

	ID          int       `bun:"id,pk,autoincrement,identity"`
	PlayerID    int       `bun:"player_id,nullzero"`
	TribeID     int       `bun:"tribe_id,nullzero"`
	ServerKey   string    `bun:"server_key,nullzero"`
	Tribe       Tribe     `bun:"tribe,rel:belongs-to,join:tribe_id=id,join:server_key=server_key"`
	Player      Player    `bun:"player,rel:belongs-to,join:player_id=id,join:server_key=server_key"`
	NumVillages int       `bun:"num_villages"`
	Points      int       `bun:"points"`
	Rank        int       `bun:"rank"`
	Date        time.Time `bun:"date,nullzero"`
	CreatedAt   time.Time `bun:"created_at,nullzero"`

	OpponentsDefeated
}

func (ps PlayerSnapshot) ToDomain() (domain.PlayerSnapshot, error) {
	od, err := ps.OpponentsDefeated.ToDomain()
	if err != nil {
		return domain.PlayerSnapshot{}, fmt.Errorf(
			"couldn't construct domain.PlayerSnapshot (id=%d): %w",
			ps.ID,
			err,
		)
	}

	converted, err := domain.UnmarshalPlayerSnapshotFromDatabase(
		ps.ID,
		ps.PlayerID,
		ps.ServerKey,
		ps.NumVillages,
		ps.Points,
		ps.Rank,
		ps.TribeID,
		od,
		ps.Date,
		ps.CreatedAt,
	)
	if err != nil {
		return domain.PlayerSnapshot{}, fmt.Errorf(
			"couldn't construct domain.PlayerSnapshot (id=%d): %w",
			ps.ID,
			err,
		)
	}

	return converted, nil
}

func (ps PlayerSnapshot) ToDomainWithRelations() (domain.PlayerSnapshotWithRelations, error) {
	converted, err := ps.ToDomain()
	if err != nil {
		return domain.PlayerSnapshotWithRelations{}, err
	}

	player, err := ps.Player.ToMeta()
	if err != nil {
		return domain.PlayerSnapshotWithRelations{}, err
	}

	var tribe domain.NullTribeMeta
	if ps.Tribe.ID > 0 {
		tribe.Valid = true
		tribe.V, err = ps.Tribe.ToMeta()
		if err != nil {
			return domain.PlayerSnapshotWithRelations{}, err
		}
	}

	return converted.WithRelations(player, tribe), nil
}

type PlayerSnapshots []PlayerSnapshot

func (pss PlayerSnapshots) ToDomain() (domain.PlayerSnapshots, error) {
	return sliceToDomain(pss)
}

func (pss PlayerSnapshots) ToDomainWithRelations() (domain.PlayerSnapshotsWithRelations, error) {
	return sliceToDomainWithRelations(pss)
}
