package domain

import (
	"math"
	"net/url"
)

type BaseVillage struct {
	id         int
	name       string
	points     int
	x          int
	y          int
	continent  string
	bonus      int
	playerID   int
	profileURL *url.URL
}

const baseVillageModelName = "BaseVillage"

func NewBaseVillage(
	id int,
	name string,
	points int,
	x, y int,
	continent string,
	bonus int,
	playerID int,
	profileURL *url.URL,
) (BaseVillage, error) {
	if err := validateIntInRange(id, 1, math.MaxInt); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "id",
			Err:   err,
		}
	}

	if err := validateStringLen(name, villageNameMinLength, villageNameMaxLength); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "name",
			Err:   err,
		}
	}

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

	if err := validateIntInRange(x, 0, math.MaxInt); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "x",
			Err:   err,
		}
	}

	if err := validateIntInRange(y, 0, math.MaxInt); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "y",
			Err:   err,
		}
	}

	if err := validateStringLen(continent, villageContinentMinLength, villageContinentMaxLength); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "continent",
			Err:   err,
		}
	}

	if err := validateIntInRange(bonus, 0, math.MaxInt); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "bonus",
			Err:   err,
		}
	}

	if err := validateIntInRange(playerID, 0, math.MaxInt); err != nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "playerID",
			Err:   err,
		}
	}

	if profileURL == nil {
		return BaseVillage{}, ValidationError{
			Model: baseVillageModelName,
			Field: "profileURL",
			Err:   ErrNil,
		}
	}

	return BaseVillage{
		id:         id,
		name:       name,
		points:     points,
		x:          x,
		y:          y,
		continent:  continent,
		bonus:      bonus,
		playerID:   playerID,
		profileURL: profileURL,
	}, nil
}

func (v BaseVillage) ID() int {
	return v.id
}

func (v BaseVillage) Name() string {
	return v.name
}

func (v BaseVillage) Points() int {
	return v.points
}

func (v BaseVillage) X() int {
	return v.x
}

func (v BaseVillage) Y() int {
	return v.y
}

func (v BaseVillage) Continent() string {
	return v.continent
}

func (v BaseVillage) Bonus() int {
	return v.bonus
}

func (v BaseVillage) PlayerID() int {
	return v.playerID
}

func (v BaseVillage) ProfileURL() *url.URL {
	return v.profileURL
}

func (v BaseVillage) IsZero() bool {
	return v == BaseVillage{}
}

type BaseVillages []BaseVillage
