use super::super::super::*;
use crate::inspect::smp::world::known_cargo_slot_definition_for_descriptor_id;
use std::collections::BTreeMap;
use std::sync::OnceLock;

pub(in crate::inspect::smp) const GROUNDED_NAMED_CARGO_PRODUCTION_LABELS: [(&str, &str); 50] = [
    ("Alcohol", "Alcohol Production"),
    ("Aluminum", "Aluminum Production"),
    ("Ammunition", "Ammunition Production"),
    ("Automobiles", "Automobiles Production"),
    ("Bauxite", "Bauxite Production"),
    ("Ceramics", "Ceramics Production"),
    ("Cheese", "Cheese Production"),
    ("Chemicals", "Chemicals Production"),
    ("Clothing", "Clothing Production"),
    ("Coal", "Coal Production"),
    ("Coffee", "Coffee Production"),
    ("Concrete", "Concrete Production"),
    ("Corn", "Corn Production"),
    ("Cotton", "Cotton Production"),
    ("Crystals", "Crystals Production"),
    ("Diesel", "Diesel Production"),
    ("Dye", "Dye Production"),
    ("Electronics", "Electronics Production"),
    ("Fertilizer", "Fertilizer Production"),
    ("Furniture", "Furniture Production"),
    ("Goods", "Goods Production"),
    ("Grain", "Grain Production"),
    ("Ingots", "Ingots Production"),
    ("Iron", "Iron Production"),
    ("Livestock", "Livestock Production"),
    ("Logs", "Logs Production"),
    ("Lumber", "Lumber Production"),
    ("Machinery", "Machinery Production"),
    ("Mail", "Mail Production"),
    ("Meat", "Meat Production"),
    ("Medicine", "Medicine Production"),
    ("Milk", "Milk Production"),
    ("Oil", "Oil Production"),
    ("Ore", "Ore Production"),
    ("Paper", "Paper Production"),
    ("Passengers", "Passengers Production"),
    ("Plastic", "Plastic Production"),
    ("Produce", "Produce Production"),
    ("Pulpwood", "Pulpwood Production"),
    ("Rice", "Rice Production"),
    ("Rubber", "Rubber Production"),
    ("Steel", "Steel Production"),
    ("Sugar", "Sugar Production"),
    ("Tires", "Tires Production"),
    ("Toys", "Toys Production"),
    ("Troops", "Troops Production"),
    ("Uranium", "Uranium Production"),
    ("Waste", "Waste Production"),
    ("Weapons", "Weapons Production"),
    ("Wool", "Wool Production"),
];

#[derive(Debug, Deserialize)]
pub(in crate::inspect::smp) struct CheckedInCargoBindingsArtifact {
    bindings: Vec<CheckedInCargoBindingRow>,
}

#[derive(Debug, Deserialize)]
pub(in crate::inspect::smp) struct CheckedInCargoBindingRow {
    descriptor_id: u32,
    band: String,
    cargo_name: String,
}

pub(in crate::inspect::smp) fn recovered_cargo_price_descriptor_metadata(
    descriptor_id: u32,
) -> Option<RealGroupedEffectDescriptorMetadata> {
    (descriptor_id == 105).then_some(RealGroupedEffectDescriptorMetadata {
        descriptor_id,
        label: "All Cargo Prices",
        target_mask_bits: 0x08,
        parameter_family: "cargo_price_scalar",
        runtime_key: None,
        runtime_status: RealGroupedEffectRuntimeStatus::Executable,
        executable_in_runtime: true,
    })
}

pub(in crate::inspect::smp) fn recovered_cargo_economics_descriptor_metadata(
    descriptor_id: u32,
) -> Option<RealGroupedEffectDescriptorMetadata> {
    match descriptor_id {
        177 => Some(RealGroupedEffectDescriptorMetadata {
            descriptor_id,
            label: "All Cargo Production",
            target_mask_bits: 0x08,
            parameter_family: "cargo_production_scalar",
            runtime_key: None,
            runtime_status: RealGroupedEffectRuntimeStatus::Executable,
            executable_in_runtime: true,
        }),
        178 => Some(RealGroupedEffectDescriptorMetadata {
            descriptor_id,
            label: "All Factory Production",
            target_mask_bits: 0x08,
            parameter_family: "cargo_production_scalar",
            runtime_key: None,
            runtime_status: RealGroupedEffectRuntimeStatus::Executable,
            executable_in_runtime: true,
        }),
        179 => Some(RealGroupedEffectDescriptorMetadata {
            descriptor_id,
            label: "All Farm/Mine Production",
            target_mask_bits: 0x08,
            parameter_family: "cargo_production_scalar",
            runtime_key: None,
            runtime_status: RealGroupedEffectRuntimeStatus::Executable,
            executable_in_runtime: true,
        }),
        _ => None,
    }
}

pub(in crate::inspect::smp) fn grounded_named_cargo_price_bindings()
-> &'static BTreeMap<u32, (&'static str, &'static str)> {
    static BINDINGS: OnceLock<BTreeMap<u32, (&'static str, &'static str)>> = OnceLock::new();
    BINDINGS.get_or_init(|| {
        let artifact: CheckedInCargoBindingsArtifact = serde_json::from_str(include_str!(
            "../../../../../../../artifacts/exports/rt3-1.06/event-effects-cargo-bindings.json"
        ))
        .expect("checked-in cargo bindings artifact should parse");
        artifact
            .bindings
            .into_iter()
            .filter(|binding| binding.band == "cargo_price_named")
            .map(|binding| {
                let cargo_name = Box::leak(binding.cargo_name.into_boxed_str()) as &'static str;
                let descriptor_label =
                    Box::leak(format!("{cargo_name} Price").into_boxed_str()) as &'static str;
                (binding.descriptor_id, (cargo_name, descriptor_label))
            })
            .collect()
    })
}

pub(crate) fn grounded_named_cargo_price_label(descriptor_id: u32) -> Option<&'static str> {
    grounded_named_cargo_price_bindings()
        .get(&descriptor_id)
        .map(|(cargo_label, _)| *cargo_label)
}

pub(in crate::inspect::smp) fn grounded_named_cargo_production_label(
    descriptor_id: u32,
) -> Option<&'static str> {
    let index = descriptor_id.checked_sub(180)? as usize;
    GROUNDED_NAMED_CARGO_PRODUCTION_LABELS
        .get(index)
        .map(|(cargo_label, _)| *cargo_label)
}

pub(in crate::inspect::smp) fn grounded_named_cargo_production_descriptor_label(
    descriptor_id: u32,
) -> Option<&'static str> {
    let index = descriptor_id.checked_sub(180)? as usize;
    GROUNDED_NAMED_CARGO_PRODUCTION_LABELS
        .get(index)
        .map(|(_, descriptor_label)| *descriptor_label)
}

pub(in crate::inspect::smp) fn recovered_cargo_production_descriptor_metadata(
    descriptor_id: u32,
) -> Option<RealGroupedEffectDescriptorMetadata> {
    if let Some(label) = grounded_named_cargo_production_descriptor_label(descriptor_id) {
        return Some(RealGroupedEffectDescriptorMetadata {
            descriptor_id,
            label,
            target_mask_bits: 0x08,
            parameter_family: "cargo_production_scalar",
            runtime_key: None,
            runtime_status: RealGroupedEffectRuntimeStatus::Executable,
            executable_in_runtime: true,
        });
    }
    recovered_cargo_production_label(descriptor_id).map(|label| {
        RealGroupedEffectDescriptorMetadata {
            descriptor_id,
            label,
            target_mask_bits: 0x08,
            parameter_family: "cargo_production_scalar",
            runtime_key: None,
            runtime_status: RealGroupedEffectRuntimeStatus::Executable,
            executable_in_runtime: true,
        }
    })
}

pub(in crate::inspect::smp) fn recovered_cargo_production_slot(descriptor_id: u32) -> Option<u32> {
    let slot = descriptor_id.checked_sub(229)?;
    (1..=11).contains(&slot).then_some(slot)
}

pub(in crate::inspect::smp) fn recovered_cargo_production_label(
    descriptor_id: u32,
) -> Option<&'static str> {
    known_cargo_slot_definition_for_descriptor_id(descriptor_id).map(|definition| definition.label)
}

pub(in crate::inspect::smp) fn recovered_cargo_production_slot_from_condition_name(
    name: &str,
) -> Option<u32> {
    KNOWN_CARGO_SLOT_DEFINITIONS
        .iter()
        .find(|definition| definition.label == name)
        .map(|definition| definition.slot_id)
}
