package domain

import (
	"math"
	"net/url"
)

type BasePlayer struct {
	id          int
	name        string
	numVillages int
	points      int
	rank        int
	tribeID     int
	od          OpponentsDefeated
	profileURL  *url.URL
}

const basePlayerModelName = "BasePlayer"

func NewBasePlayer(
	id int,
	name string,
	numVillages int,
	points int,
	rank int,
	tribeID int,
	od OpponentsDefeated,
	profileURL *url.URL,
) (BasePlayer, error) {
	if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "id",
			Err:   err,
		}
	}

	if err := validateStringLen(name, playerNameMinLength, playerNameMaxLength); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "name",
			Err:   err,
		}
	}

	if err := validateIntInRange(numVillages, 0, math.MaxInt); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "numVillages",
			Err:   err,
		}
	}

	if err := validateIntInRange(points, 0, math.MaxInt); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "points",
			Err:   err,
		}
	}

	if err := validateIntInRange(rank, 0, math.MaxInt); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "rank",
			Err:   err,
		}
	}

	if err := validateIntInRange(tribeID, 0, math.MaxInt); err != nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "tribeID",
			Err:   err,
		}
	}

	if profileURL == nil {
		return BasePlayer{}, ValidationError{
			Model: basePlayerModelName,
			Field: "profileURL",
			Err:   ErrNil,
		}
	}

	return BasePlayer{
		id:          id,
		name:        name,
		numVillages: numVillages,
		points:      points,
		rank:        rank,
		tribeID:     tribeID,
		od:          od,
		profileURL:  profileURL,
	}, nil
}

func (p BasePlayer) ID() int {
	return p.id
}

func (p BasePlayer) Name() string {
	return p.name
}

func (p BasePlayer) NumVillages() int {
	return p.numVillages
}

func (p BasePlayer) Points() int {
	return p.points
}

func (p BasePlayer) Rank() int {
	return p.rank
}

func (p BasePlayer) TribeID() int {
	return p.tribeID
}

func (p BasePlayer) OD() OpponentsDefeated {
	return p.od
}

func (p BasePlayer) ProfileURL() *url.URL {
	return p.profileURL
}

func (p BasePlayer) IsZero() bool {
	return p == BasePlayer{}
}

type BasePlayers []BasePlayer
