package bunmodel

import (
	"fmt"
	"time"

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

type Tribe struct {
	bun.BaseModel `bun:"table:tribes,alias:tribe"`

	ID             int       `bun:"id,nullzero,pk"`
	ServerKey      string    `bun:"server_key,nullzero,pk"`
	Name           string    `bun:"name,nullzero"`
	Tag            string    `bun:"tag,nullzero"`
	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"`
	ProfileURL     string    `bun:"profile_url,nullzero"`
	BestRank       int       `bun:"best_rank,nullzero,default:999999"`
	BestRankAt     time.Time `bun:"best_rank_at,nullzero,default:CURRENT_TIMESTAMP"`
	MostPoints     int       `bun:"most_points"`
	MostPointsAt   time.Time `bun:"most_points_at,nullzero,default:CURRENT_TIMESTAMP"`
	MostVillages   int       `bun:"most_villages"`
	MostVillagesAt time.Time `bun:"most_villages_at,nullzero,default:CURRENT_TIMESTAMP"`
	CreatedAt      time.Time `bun:"created_at,nullzero,default:CURRENT_TIMESTAMP"`
	DeletedAt      time.Time `bun:"deleted_at,nullzero"`

	OpponentsDefeated
}

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

	converted, err := domain.UnmarshalTribeFromDatabase(
		t.ID,
		t.ServerKey,
		t.Name,
		t.Tag,
		t.NumMembers,
		t.NumVillages,
		t.Points,
		t.AllPoints,
		t.Rank,
		od,
		t.ProfileURL,
		t.Dominance,
		t.BestRank,
		t.BestRankAt,
		t.MostPoints,
		t.MostPointsAt,
		t.MostVillages,
		t.MostVillagesAt,
		t.CreatedAt,
		t.DeletedAt,
	)
	if err != nil {
		return domain.Tribe{}, fmt.Errorf("couldn't construct domain.Tribe (id=%d,serverKey=%s): %w", t.ID, t.ServerKey, err)
	}

	return converted, nil
}

type Tribes []Tribe

func (ts Tribes) ToDomain() (domain.Tribes, error) {
	res := make(domain.Tribes, 0, len(ts))

	for _, t := range ts {
		converted, err := t.ToDomain()
		if err != nil {
			return nil, err
		}

		res = append(res, converted)
	}

	return res, nil
}
