//! Serde model of the real FIFA 17 Python profile (`fifa17_profile.json`).
//! Only the fields the importer reasons about are modelled; every field is
//! permissive (`Option`/`default`) because the source is external and unknown
//! fields are ignored. Nothing here is written back.

use anyhow::{Context, Result};
use serde::Deserialize;

#[derive(Debug, Clone, Deserialize)]
pub struct Profile {
    #[serde(rename = "personaId", default)]
    pub persona_id: i64,
    #[serde(rename = "personaName", default)]
    pub persona_name: String,
    #[serde(rename = "clubName", default)]
    pub club_name: String,
    #[serde(rename = "clubAbbr", default)]
    pub club_abbr: String,
    #[serde(default)]
    pub coins: i64,
    /// Next wire id to issue (issue-then-increment: `fut_store.py` assigns this
    /// value then increments). The allocation watermark to preserve.
    #[serde(rename = "nextItemId", default)]
    pub next_item_id: i64,
    #[serde(default)]
    pub items: Vec<Item>,
    #[serde(default)]
    pub squads: Vec<Squad>,
}

impl Profile {
    pub fn from_json_str(raw: &str) -> Result<Self> {
        serde_json::from_str(raw).context("parsing fifa17_profile.json")
    }
}

#[derive(Debug, Clone, Deserialize)]
pub struct Item {
    /// The per-INSTANCE wire id (preserved on import).
    pub id: i64,
    /// The per-DEFINITION versioned id: `resourceId = (version << 24) | assetId`.
    #[serde(rename = "resourceId", default)]
    pub resource_id: i64,
    #[serde(rename = "assetId", default)]
    pub asset_id: Option<i64>,
    #[serde(rename = "itemType", default)]
    pub item_type: String,
    #[serde(default)]
    pub rareflag: Option<i64>,
    #[serde(default)]
    pub rating: Option<i64>,
    #[serde(rename = "preferredPosition", default)]
    pub preferred_position: Option<String>,
    #[serde(default)]
    pub nation: Option<i64>,
    #[serde(default)]
    pub teamid: Option<i64>,
    #[serde(rename = "leagueId", default)]
    pub league_id: Option<i64>,
    #[serde(rename = "attributeList", default)]
    pub attribute_list: Option<Vec<Attr>>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Attr {
    pub index: i64,
    pub value: i64,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Squad {
    #[serde(default)]
    pub formation: String,
    #[serde(rename = "squadName", default)]
    pub squad_name: String,
    #[serde(default)]
    pub captain: Option<i64>,
    /// Opaque staff refs; each is `{ "id": <wire id>, ... }`.
    #[serde(default)]
    pub manager: Vec<serde_json::Value>,
    #[serde(default)]
    pub players: Vec<SquadSlot>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct SquadSlot {
    pub index: i64,
    #[serde(rename = "itemData", default)]
    pub item_data: SlotItem,
    #[serde(rename = "kitNumber", default)]
    pub kit_number: Option<i64>,
}

#[derive(Debug, Clone, Default, Deserialize)]
pub struct SlotItem {
    /// Wire id of the owned instance in this slot; `0` = empty slot.
    #[serde(default)]
    pub id: i64,
}
