package apimodel

import (
	"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
)

func NewServer(s domain.Server) Server {
	converted := Server{
		Key:                  s.Key(),
		CreatedAt:            s.CreatedAt(),
		NumBarbarianVillages: s.NumBarbarianVillages(),
		NumBonusVillages:     s.NumBonusVillages(),
		NumPlayerVillages:    s.NumPlayerVillages(),
		NumPlayers:           s.NumPlayers(),
		NumTribes:            s.NumTribes(),
		NumVillages:          s.NumVillages(),
		Open:                 s.Open(),
		Url:                  s.URL().String(),
	}

	if v := s.PlayerDataSyncedAt(); !v.IsZero() {
		converted.PlayerDataSyncedAt = &v
	}

	if v := s.TribeDataSyncedAt(); !v.IsZero() {
		converted.TribeDataSyncedAt = &v
	}

	if v := s.VillageDataSyncedAt(); !v.IsZero() {
		converted.VillageDataSyncedAt = &v
	}

	if v := s.EnnoblementDataSyncedAt(); !v.IsZero() {
		converted.EnnoblementDataSyncedAt = &v
	}

	return converted
}

func NewServerMeta(s domain.ServerMeta) ServerMeta {
	return ServerMeta{
		Key:  s.Key(),
		Open: s.Open(),
		Url:  s.URL().String(),
	}
}

func NewListServersResponse(res domain.ListServersResult) ListServersResponse {
	servers := res.Servers()

	resp := ListServersResponse{
		Data: make([]Server, 0, len(servers)),
		Cursor: Cursor{
			Next: res.Next().Encode(),
			Self: res.Self().Encode(),
		},
	}

	for _, s := range servers {
		resp.Data = append(resp.Data, NewServer(s))
	}

	return resp
}

func NewGetServerResponse(s domain.Server) GetServerResponse {
	return GetServerResponse{
		Data: NewServer(s),
	}
}

func NewServerConfig(cfg domain.ServerConfig) ServerConfig {
	return ServerConfig{
		Speed:     cfg.Speed(),
		UnitSpeed: cfg.UnitSpeed(),
		Moral:     cfg.Moral(),
		Build:     ServerConfigBuild(cfg.Build()),
		Misc:      ServerConfigMisc(cfg.Misc()),
		Commands:  ServerConfigCommands(cfg.Commands()),
		Newbie:    ServerConfigNewbie(cfg.Newbie()),
		Game:      ServerConfigGame(cfg.Game()),
		Buildings: ServerConfigBuildings(cfg.Buildings()),
		Snob:      ServerConfigSnob(cfg.Snob()),
		Ally:      ServerConfigAlly(cfg.Ally()),
		Coord:     ServerConfigCoord(cfg.Coord()),
		Sitter:    ServerConfigSitter(cfg.Sitter()),
		Sleep:     ServerConfigSleep(cfg.Sleep()),
		Night:     ServerConfigNight(cfg.Night()),
		Win:       ServerConfigWin(cfg.Win()),
	}
}

func NewGetServerConfigResponse(cfg domain.ServerConfig) GetServerConfigResponse {
	return GetServerConfigResponse{
		Data: NewServerConfig(cfg),
	}
}

func NewBuildingInfo(info domain.BuildingInfo) BuildingInfo {
	return BuildingInfo{
		Main:       Building(info.Main()),
		Barracks:   Building(info.Barracks()),
		Stable:     Building(info.Stable()),
		Garage:     Building(info.Garage()),
		Watchtower: Building(info.Watchtower()),
		Snob:       Building(info.Snob()),
		Smith:      Building(info.Smith()),
		Place:      Building(info.Place()),
		Statue:     Building(info.Statue()),
		Market:     Building(info.Market()),
		Wood:       Building(info.Wood()),
		Stone:      Building(info.Stone()),
		Iron:       Building(info.Iron()),
		Farm:       Building(info.Farm()),
		Storage:    Building(info.Storage()),
		Hide:       Building(info.Hide()),
		Wall:       Building(info.Wall()),
	}
}

func NewGetBuildingInfoResponse(info domain.BuildingInfo) GetBuildingInfoResponse {
	return GetBuildingInfoResponse{
		Data: NewBuildingInfo(info),
	}
}

func NewUnitInfo(info domain.UnitInfo) UnitInfo {
	return UnitInfo{
		Spear:    Unit(info.Spear()),
		Sword:    Unit(info.Sword()),
		Axe:      Unit(info.Axe()),
		Archer:   Unit(info.Archer()),
		Spy:      Unit(info.Spy()),
		Light:    Unit(info.Light()),
		Marcher:  Unit(info.Marcher()),
		Heavy:    Unit(info.Heavy()),
		Ram:      Unit(info.Ram()),
		Catapult: Unit(info.Catapult()),
		Knight:   Unit(info.Knight()),
		Snob:     Unit(info.Snob()),
		Militia:  Unit(info.Militia()),
	}
}

func NewGetUnitInfoResponse(info domain.UnitInfo) GetUnitInfoResponse {
	return GetUnitInfoResponse{
		Data: NewUnitInfo(info),
	}
}
