use std::fs;
use std::path::Path;

use crate::inspect::smp::bundle::{SmpInspectionReport, inspect_bundle_bytes};
use crate::inspect::smp::regions::*;
use crate::inspect::smp::structures::*;
use crate::inspect::smp::world::*;

pub fn inspect_save_company_and_chairman_analysis_file(
    path: &Path,
) -> Result<SmpSaveCompanyChairmanAnalysisReport, Box<dyn std::error::Error>> {
    let bytes = fs::read(path)?;
    let report = inspect_bundle_bytes(
        &bytes,
        path.extension()
            .and_then(|extension| extension.to_str())
            .map(|extension| extension.to_ascii_lowercase()),
    );
    inspect_save_company_and_chairman_analysis_bytes(&bytes, &report)
        .ok_or_else(|| "save inspection did not expose grounded company/chairman analysis".into())
}

pub fn inspect_save_company_and_chairman_analysis_bytes(
    bytes: &[u8],
    report: &SmpInspectionReport,
) -> Option<SmpSaveCompanyChairmanAnalysisReport> {
    let selection_probe = report.save_world_selection_context_probe.as_ref();
    let world_selection_context = selection_probe.map(build_save_world_selection_role_analysis);
    let world_issue_37 = report.save_world_issue_37_probe.clone();
    let world_economic_tuning = report.save_world_economic_tuning_probe.clone();
    let world_finance_neighborhood = report.save_world_finance_neighborhood_probe.clone();
    let train_collection_directory = report.save_train_collection_directory_probe.clone();
    let region_record_triplets = report.save_region_record_triplet_probe.clone();
    let region_queued_notice_records = report
        .save_region_queued_notice_record_probe
        .clone()
        .or_else(|| {
            parse_save_region_queued_notice_record_probe(
                bytes,
                report.file_extension_hint.as_deref(),
                report.container_profile.as_ref(),
                report.save_region_collection_header_probe.as_ref(),
            )
        });
    let region_fixed_row_run_candidates = report
        .save_region_fixed_row_run_candidate_probe
        .clone()
        .or_else(|| {
            parse_save_region_fixed_row_run_candidate_probe(
                bytes,
                report.file_extension_hint.as_deref(),
                report.container_profile.as_ref(),
                report.save_region_collection_header_probe.as_ref(),
            )
        });
    let placed_structure_record_triplets =
        report.save_placed_structure_record_triplet_probe.clone();
    let placed_structure_dynamic_side_buffer = report
        .save_placed_structure_dynamic_side_buffer_probe
        .clone()
        .or_else(|| {
            parse_save_placed_structure_dynamic_side_buffer_probe(
                bytes,
                report.file_extension_hint.as_deref(),
                report.container_profile.as_ref(),
            )
        });
    let placed_structure_dynamic_side_buffer_alignment = placed_structure_dynamic_side_buffer
        .as_ref()
        .zip(placed_structure_record_triplets.as_ref())
        .map(|(side_buffer, triplets)| {
            summarize_placed_structure_dynamic_side_buffer_alignment(side_buffer, triplets)
        });
    let unclassified_tagged_collection_headers = report
        .save_unclassified_tagged_collection_header_probes
        .clone();
    let company_header_probe = report.save_company_collection_header_probe.as_ref();
    let chairman_header_probe = report
        .save_chairman_profile_collection_header_probe
        .as_ref();

    let company_entries = build_save_company_record_analysis_entries(&bytes, company_header_probe)?;
    let company_share_prices = build_company_share_prices(&company_entries);
    let chairman_entries = build_save_chairman_record_analysis_entries(
        &bytes,
        chairman_header_probe,
        company_header_probe,
        &company_share_prices,
    )?;
    let notes =
        build_save_company_chairman_analysis_notes(SaveCompanyChairmanAnalysisNotesInputs {
            report,
            world_selection_context: world_selection_context.as_ref(),
            train_collection_directory: train_collection_directory.as_ref(),
            region_record_triplets: region_record_triplets.as_ref(),
            region_queued_notice_records: region_queued_notice_records.as_ref(),
            region_fixed_row_run_candidates: region_fixed_row_run_candidates.as_ref(),
            placed_structure_record_triplets: placed_structure_record_triplets.as_ref(),
            placed_structure_dynamic_side_buffer: placed_structure_dynamic_side_buffer.as_ref(),
            placed_structure_dynamic_side_buffer_alignment:
                placed_structure_dynamic_side_buffer_alignment.as_ref(),
            unclassified_tagged_collection_headers: &unclassified_tagged_collection_headers,
            company_entries: &company_entries,
            chairman_entries: &chairman_entries,
        });

    Some(SmpSaveCompanyChairmanAnalysisReport {
        profile_family: report
            .container_profile
            .as_ref()
            .map(|profile| profile.profile_family.clone())
            .unwrap_or_else(|| "unknown".to_string()),
        selected_company_id: selection_probe.map(|probe| probe.selected_company_id),
        selected_chairman_profile_id: selection_probe
            .map(|probe| probe.selected_chairman_profile_id),
        world_selection_context,
        world_issue_37,
        world_economic_tuning,
        world_finance_neighborhood,
        train_collection_header: report.save_train_collection_header_probe.clone(),
        train_collection_directory,
        region_collection_header: report.save_region_collection_header_probe.clone(),
        region_record_triplets,
        region_queued_notice_records,
        region_fixed_row_run_candidates,
        placed_structure_collection_header: report
            .save_placed_structure_collection_header_probe
            .clone(),
        placed_structure_record_triplets,
        placed_structure_dynamic_side_buffer,
        placed_structure_dynamic_side_buffer_alignment,
        unclassified_tagged_collection_headers,
        company_entries,
        chairman_entries,
        notes,
    })
}
