package bunmodel

import (
	"fmt"
	"time"

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

type TribeSnapshot struct {
	bun.BaseModel `bun:"table:tribe_snapshots,alias:ts"`

	ID          int       `bun:"id,pk,autoincrement,identity"`
	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"`
	NumMembers  int       `bun:"num_members"`
	NumVillages int       `bun:"num_villages"`
	Points      int       `bun:"points"`
	AllPoints   int       `bun:"all_points"`
	Rank        int       `bun:"rank"`
	Dominance   float64   `bun:"dominance"`
	Date        time.Time `bun:"date,nullzero"`
	CreatedAt   time.Time `bun:"created_at,nullzero"`

	OpponentsDefeated
}

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

	converted, err := domain.UnmarshalTribeSnapshotFromDatabase(
		ts.ID,
		ts.TribeID,
		ts.ServerKey,
		ts.NumMembers,
		ts.NumVillages,
		ts.Points,
		ts.AllPoints,
		ts.Rank,
		od,
		ts.Dominance,
		ts.Date,
		ts.CreatedAt,
	)
	if err != nil {
		return domain.TribeSnapshot{}, fmt.Errorf(
			"couldn't construct domain.TribeSnapshot (id=%d): %w",
			ts.ID,
			err,
		)
	}

	return converted, nil
}

func (ts TribeSnapshot) ToDomainWithRelations() (domain.TribeSnapshotWithRelations, error) {
	converted, err := ts.ToDomain()
	if err != nil {
		return domain.TribeSnapshotWithRelations{}, err
	}

	tribe, err := ts.Tribe.ToMeta()
	if err != nil {
		return domain.TribeSnapshotWithRelations{}, err
	}

	return converted.WithRelations(tribe), nil
}

type TribeSnapshots []TribeSnapshot

func (tss TribeSnapshots) ToDomain() (domain.TribeSnapshots, error) {
	return sliceToDomain(tss)
}

func (tss TribeSnapshots) ToDomainWithRelations() (domain.TribeSnapshotsWithRelations, error) {
	return sliceToDomainWithRelations(tss)
}
