package report

import (
	"encoding/json"

	"github.com/google/uuid"
)

// BattleSummary identifies one battle relevant to the report recipient
// and carries the data needed to render a battle marker on the map
// without fetching the full BattleReport. Planet locates the marker;
// Shots scales the marker stroke with the battle length.
type BattleSummary struct {
	ID     uuid.UUID `json:"id"`
	Planet uint      `json:"planet"`
	Shots  uint      `json:"shots"`
}

type BattleReport struct {
	// Battle unique ID
	ID uuid.UUID `json:"id"`
	// Planet number
	Planet uint `json:"planet"`
	// Planet name at battle start
	PlanetName string `json:"planetName"`
	// Races participating map: <key:RaceID>
	Races map[int]uuid.UUID `json:"races"`
	// Ships Groups participating map: <key:BattleReportGroup>
	Ships map[int]BattleReportGroup `json:"ships"`
	// Battle's firing protocol
	Protocol []BattleActionReport `json:"protocol"`
}

type BattleReportGroup struct {
	// Name of the race
	Race string `json:"race"`
	// Name of the Ship Class.
	// By design, ship's info MUST be present in Game's Repors in 'LocalShipClass' or 'OtherShipClass'
	ClassName string `json:"className"`
	// Ship Group's technologies mapping <tech:level>
	Tech map[string]Float `json:"tech"`
	// Initial number of ships in this group
	Number uint `json:"num"`
	// Number of ships left after battle
	NumberLeft uint `json:"numLeft"`
	// Type of cargo loaded
	LoadType string `json:"loadType"`
	// Quantity of cargo loaded
	LoadQuantity Float `json:"loadQuantity"`
	// A Race with its ships can be in Peace state with all participants,
	// so no shots will be fired and no damage taken, participating only as viewer
	// when InBattle=false
	InBattle bool `json:"inBattle"`
}

type BattleActionReport struct {
	// `key` from BattleReport.Races map
	Attacker int `json:"a"`
	// `key` from BattleReport.Ships map
	AttackerShipClass int `json:"sa"`
	// `key` from BattleReport.Races map
	Defender int `json:"d"`
	// `key` from BattleReport.Ships map
	DefenderShipClass int `json:"sd"`
	// Was ship destroyed after attack or survived under shields
	Destroyed bool `json:"x"`
}

func (b BattleReport) MarshalBinary() (data []byte, err error) {
	return json.Marshal(&b)
}

func (b *BattleReport) UnmarshalBinary(data []byte) error {
	return json.Unmarshal(data, b)
}
