use serde::{Deserialize, Serialize};

use crate::event::conditions::RuntimeCondition;
use crate::event::effects::RuntimeEffect;
use crate::event::metrics::{RuntimeCompanyConditionTestScope, RuntimePlayerConditionTestScope};
use crate::event::targets::RuntimeCompanyTarget;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventCollectionSummary {
    pub source_kind: String,
    pub mechanism_family: String,
    pub mechanism_confidence: String,
    #[serde(default)]
    pub container_profile_family: Option<String>,
    pub packed_state_version: u32,
    pub packed_state_version_hex: String,
    pub live_id_bound: u32,
    pub live_record_count: usize,
    pub live_entry_ids: Vec<u32>,
    #[serde(default)]
    pub decoded_record_count: usize,
    #[serde(default)]
    pub imported_runtime_record_count: usize,
    #[serde(default)]
    pub records: Vec<RuntimePackedEventRecordSummary>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventRecordSummary {
    pub record_index: usize,
    pub live_entry_id: u32,
    #[serde(default)]
    pub payload_offset: Option<usize>,
    #[serde(default)]
    pub payload_len: Option<usize>,
    pub decode_status: String,
    #[serde(default)]
    pub payload_family: String,
    #[serde(default)]
    pub trigger_kind: Option<u8>,
    #[serde(default)]
    pub active: Option<bool>,
    #[serde(default)]
    pub marks_collection_dirty: Option<bool>,
    #[serde(default)]
    pub one_shot: Option<bool>,
    #[serde(default)]
    pub compact_control: Option<RuntimePackedEventCompactControlSummary>,
    #[serde(default)]
    pub text_bands: Vec<RuntimePackedEventTextBandSummary>,
    #[serde(default)]
    pub standalone_condition_row_count: usize,
    #[serde(default)]
    pub standalone_condition_rows: Vec<RuntimePackedEventConditionRowSummary>,
    #[serde(default)]
    pub negative_sentinel_scope: Option<RuntimePackedEventNegativeSentinelScopeSummary>,
    #[serde(default)]
    pub grouped_effect_row_counts: Vec<usize>,
    #[serde(default)]
    pub grouped_effect_rows: Vec<RuntimePackedEventGroupedEffectRowSummary>,
    #[serde(default)]
    pub grouped_company_targets: Vec<Option<RuntimeCompanyTarget>>,
    #[serde(default)]
    pub decoded_conditions: Vec<RuntimeCondition>,
    #[serde(default)]
    pub decoded_actions: Vec<RuntimeEffect>,
    #[serde(default)]
    pub executable_import_ready: bool,
    #[serde(default)]
    pub import_outcome: Option<String>,
    #[serde(default)]
    pub notes: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventNegativeSentinelScopeSummary {
    pub company_test_scope: RuntimeCompanyConditionTestScope,
    pub player_test_scope: RuntimePlayerConditionTestScope,
    pub territory_scope_selector_is_0x63: bool,
    #[serde(default)]
    pub source_row_indexes: Vec<usize>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventCompactControlSummary {
    pub mode_byte_0x7ef: u8,
    pub primary_selector_0x7f0: u32,
    pub grouped_mode_0x7f4: u8,
    pub one_shot_header_0x7f5: u32,
    pub modifier_flag_0x7f9: u8,
    pub modifier_flag_0x7fa: u8,
    #[serde(default)]
    pub grouped_target_scope_ordinals_0x7fb: Vec<u8>,
    #[serde(default)]
    pub grouped_scope_checkboxes_0x7ff: Vec<u8>,
    pub summary_toggle_0x800: u8,
    #[serde(default)]
    pub grouped_territory_selectors_0x80f: Vec<i32>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventTextBandSummary {
    pub label: String,
    pub packed_len: usize,
    pub present: bool,
    pub preview: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventConditionRowSummary {
    pub row_index: usize,
    pub raw_condition_id: i32,
    pub subtype: u8,
    #[serde(default)]
    pub flag_bytes: Vec<u8>,
    #[serde(default)]
    pub candidate_name: Option<String>,
    #[serde(default)]
    pub comparator: Option<String>,
    #[serde(default)]
    pub metric: Option<String>,
    #[serde(default)]
    pub semantic_family: Option<String>,
    #[serde(default)]
    pub semantic_preview: Option<String>,
    #[serde(default)]
    pub requires_candidate_name_binding: bool,
    #[serde(default)]
    pub recovered_cargo_slot: Option<u32>,
    #[serde(default)]
    pub recovered_cargo_class: Option<String>,
    #[serde(default)]
    pub recovered_cargo_label: Option<String>,
    #[serde(default)]
    pub recovered_cargo_supplied_token_stem: Option<String>,
    #[serde(default)]
    pub recovered_cargo_demanded_token_stem: Option<String>,
    #[serde(default)]
    pub notes: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RuntimePackedEventGroupedEffectRowSummary {
    pub group_index: usize,
    pub row_index: usize,
    pub descriptor_id: u32,
    #[serde(default)]
    pub descriptor_label: Option<String>,
    #[serde(default)]
    pub target_mask_bits: Option<u8>,
    #[serde(default)]
    pub parameter_family: Option<String>,
    #[serde(default)]
    pub grouped_target_subject: Option<String>,
    #[serde(default)]
    pub grouped_target_scope: Option<String>,
    pub opcode: u8,
    pub raw_scalar_value: i32,
    pub value_byte_0x09: u8,
    pub value_dword_0x0d: u32,
    pub value_byte_0x11: u8,
    pub value_byte_0x12: u8,
    pub value_word_0x14: u16,
    pub value_word_0x16: u16,
    pub row_shape: String,
    #[serde(default)]
    pub semantic_family: Option<String>,
    #[serde(default)]
    pub semantic_preview: Option<String>,
    #[serde(default)]
    pub recovered_cargo_slot: Option<u32>,
    #[serde(default)]
    pub recovered_cargo_class: Option<String>,
    #[serde(default)]
    pub recovered_cargo_label: Option<String>,
    #[serde(default)]
    pub recovered_cargo_supplied_token_stem: Option<String>,
    #[serde(default)]
    pub recovered_cargo_demanded_token_stem: Option<String>,
    #[serde(default)]
    pub recovered_locomotive_id: Option<u32>,
    #[serde(default)]
    pub locomotive_name: Option<String>,
    #[serde(default)]
    pub notes: Vec<String>,
}
