use std::collections::BTreeMap;

use rrt_runtime::inspect::{
    building::BuildingTypeSourceReport,
    campaign::CampaignExeInspectionReport,
    cargo::{
        CargoEconomySourceReport, CargoSelectorReport, CargoSkinInspectionReport,
        CargoTypeInspectionReport,
    },
    pk4::{Pk4ExtractionReport, Pk4InspectionReport},
    smp::{
        bundle::SmpInspectionReport,
        map_title::SmpMapTitleHintProbe,
        services::{
            SmpInfrastructureAssetTraceReport, SmpPeriodicCompanyServiceTraceReport,
            SmpRegionServiceTraceReport,
        },
        world::SmpSaveCompanyChairmanAnalysisReport,
    },
    win::WinInspectionReport,
};
use serde::Serialize;
use serde_json::Value;

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeSmpInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: SmpInspectionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterOutput {
    pub(crate) root_path: String,
    pub(crate) report: RuntimeCompactEventDispatchClusterReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterCountsOutput {
    pub(crate) root_path: String,
    pub(crate) report: RuntimeCompactEventDispatchClusterCountsReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeMapTitleHintDirectoryOutput {
    pub(crate) root_path: String,
    pub(crate) report: RuntimeMapTitleHintDirectoryReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeMapTitleHintDirectoryReport {
    pub(crate) maps_scanned: usize,
    pub(crate) maps_with_probe: usize,
    pub(crate) maps_with_grounded_title_hits: usize,
    pub(crate) maps_with_adjacent_title_pairs: usize,
    pub(crate) maps_with_same_stem_adjacent_pairs: usize,
    pub(crate) maps: Vec<RuntimeMapTitleHintMapEntry>,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeMapTitleHintMapEntry {
    pub(crate) path: String,
    pub(crate) probe: SmpMapTitleHintProbe,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterReport {
    pub(crate) maps_scanned: usize,
    pub(crate) maps_with_event_runtime_collection: usize,
    pub(crate) maps_with_dispatch_strip_records: usize,
    pub(crate) dispatch_strip_record_count: usize,
    pub(crate) dispatch_strip_records_with_trigger_kind: usize,
    pub(crate) dispatch_strip_records_missing_trigger_kind: usize,
    pub(crate) dispatch_strip_payload_families: BTreeMap<String, usize>,
    pub(crate) dispatch_descriptor_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) dispatch_descriptor_map_counts: BTreeMap<String, usize>,
    pub(crate) dispatch_descriptor_occurrences:
        BTreeMap<String, Vec<RuntimeCompactEventDispatchClusterOccurrence>>,
    pub(crate) unknown_descriptor_ids: Vec<u32>,
    pub(crate) unknown_descriptor_special_condition_label_matches: Vec<String>,
    pub(crate) unknown_descriptor_occurrences:
        BTreeMap<u32, Vec<RuntimeCompactEventDispatchClusterOccurrence>>,
    pub(crate) add_building_dispatch_record_count: usize,
    pub(crate) add_building_dispatch_records_with_trigger_kind: usize,
    pub(crate) add_building_dispatch_records_missing_trigger_kind: usize,
    pub(crate) add_building_descriptor_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_descriptor_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_row_shape_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_row_shape_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_family_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_family_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_condition_tuple_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_condition_tuple_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_descriptor_keys:
        BTreeMap<String, Vec<String>>,
    pub(crate) add_building_signature_condition_cluster_non_add_building_descriptor_keys:
        BTreeMap<String, Vec<String>>,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterCountsReport {
    pub(crate) maps_scanned: usize,
    pub(crate) maps_with_event_runtime_collection: usize,
    pub(crate) maps_with_dispatch_strip_records: usize,
    pub(crate) dispatch_strip_record_count: usize,
    pub(crate) dispatch_strip_records_with_trigger_kind: usize,
    pub(crate) dispatch_strip_records_missing_trigger_kind: usize,
    pub(crate) dispatch_strip_payload_families: BTreeMap<String, usize>,
    pub(crate) dispatch_descriptor_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) dispatch_descriptor_map_counts: BTreeMap<String, usize>,
    pub(crate) unknown_descriptor_ids: Vec<u32>,
    pub(crate) unknown_descriptor_special_condition_label_matches: Vec<String>,
    pub(crate) add_building_dispatch_record_count: usize,
    pub(crate) add_building_dispatch_records_with_trigger_kind: usize,
    pub(crate) add_building_dispatch_records_missing_trigger_kind: usize,
    pub(crate) add_building_descriptor_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_descriptor_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_row_shape_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_row_shape_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_family_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_family_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_condition_tuple_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_condition_tuple_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_occurrence_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_map_counts: BTreeMap<String, usize>,
    pub(crate) add_building_signature_condition_cluster_descriptor_keys:
        BTreeMap<String, Vec<String>>,
    pub(crate) add_building_signature_condition_cluster_non_add_building_descriptor_keys:
        BTreeMap<String, Vec<String>>,
}

#[derive(Debug, Clone, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterOccurrence {
    pub(crate) path: String,
    pub(crate) record_index: usize,
    pub(crate) live_entry_id: u32,
    pub(crate) payload_family: String,
    pub(crate) trigger_kind: Option<u8>,
    pub(crate) signature_family: Option<String>,
    pub(crate) condition_tuples: Vec<RuntimeCompactEventDispatchClusterConditionTuple>,
    pub(crate) rows: Vec<RuntimeCompactEventDispatchClusterRow>,
}

#[derive(Debug, Clone, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterConditionTuple {
    pub(crate) raw_condition_id: i32,
    pub(crate) subtype: u8,
    pub(crate) metric: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
pub(crate) struct RuntimeCompactEventDispatchClusterRow {
    pub(crate) group_index: usize,
    pub(crate) descriptor_id: u32,
    pub(crate) descriptor_label: Option<String>,
    pub(crate) opcode: u8,
    pub(crate) raw_scalar_value: i32,
}

#[derive(Debug, Serialize)]

pub(crate) struct RuntimeSaveCompanyChairmanAnalysisOutput {
    pub(crate) path: String,
    pub(crate) analysis: SmpSaveCompanyChairmanAnalysisReport,
}

#[derive(Debug, Serialize)]

pub(crate) struct RuntimePeriodicCompanyServiceTraceOutput {
    pub(crate) path: String,
    pub(crate) trace: SmpPeriodicCompanyServiceTraceReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeRegionServiceTraceOutput {
    pub(crate) path: String,
    pub(crate) trace: SmpRegionServiceTraceReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeInfrastructureAssetTraceOutput {
    pub(crate) path: String,
    pub(crate) trace: SmpInfrastructureAssetTraceReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimePk4InspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: Pk4InspectionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCargoTypeInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: CargoTypeInspectionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeBuildingTypeInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: BuildingTypeSourceReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCargoSkinInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: CargoSkinInspectionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCargoEconomyInspectionOutput {
    pub(crate) cargo_types_dir: String,
    pub(crate) cargo_skin_pk4_path: String,
    pub(crate) inspection: CargoEconomySourceReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCargoSelectorInspectionOutput {
    pub(crate) cargo_types_dir: String,
    pub(crate) cargo_skin_pk4_path: String,
    pub(crate) selector: CargoSelectorReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeWinInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: WinInspectionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimePk4ExtractionOutput {
    pub(crate) path: String,
    pub(crate) output_path: String,
    pub(crate) extraction: Pk4ExtractionReport,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeCampaignExeInspectionOutput {
    pub(crate) path: String,
    pub(crate) inspection: CampaignExeInspectionReport,
}

#[derive(Debug, Clone, Serialize)]

pub(crate) struct RuntimeProfileBlockExportDocument {
    pub(crate) source_path: String,
    pub(crate) profile_kind: String,
    pub(crate) profile_family: String,
    pub(crate) payload: Value,
}

#[derive(Debug, Serialize)]
pub(crate) struct RuntimeProfileBlockExportReport {
    pub(crate) output_path: String,
    pub(crate) profile_kind: String,
    pub(crate) profile_family: String,
}
