from datetime import date
import numpy as np
import math as math

import AvenirCommon.Util as acu

import SpectrumCommon.Const.GB as gbc
import SpectrumCommon.Const.PJ.PJNTags as pjmvt
import SpectrumCommon.Modvars.GB.GBUtil as gbu

import SpectrumCommon.Const.IC.ICConstLink as iccl
import SpectrumCommon.Const.IC.ICConst as icc
import SpectrumCommon.Const.IC.ICTags as icmvt
from SpectrumCommon.Const.IC.ICInterventionIDs import *
from SpectrumCommon.Const.IC.IC_TI_InterventionIDs import *
import SpectrumCommon.Modvars.IC.ICModVarUtil as icmvu
import SpectrumCommon.Modvars.IC.ICModVarDefs as icmvd
import SpectrumCommon.Modvars.IC.ICReadDatabases as icrd
import SpectrumCommon.Util.IC.ICUtilLink as icul
import SpectrumCommon.Util.IC.ICUtil as icu

def init_modvars(country_ID, first_year, final_year, extra):
    '''
        Initializes Intervention Costing MVs for new IHT projections.

            Parameters:
                countryID (string):  Ex: BEN for Benin.

                first_year (int): First year selected by user.

                final_year (int): Final year selected by user. 

                extra (dict): Any other fields.  
 
            Returns:
                mod_vars_rec (dict): MVs.
    '''

    # Extra data from required modules
    prog_area_records_mv = extra[iccl.IC_IH_PROG_AREA_RECORDS_TAG_V1]
    staff_type_records_mv = extra[iccl.IC_HW_STAFF_TYPE_RECORDS_TAG_V1]
    costing_sect_records_mv = extra[iccl.IC_PC_COSTING_SECT_RECORDS_TAG_V1]
    IHT_costing_on = extra[gbc.GB_IHT_ON] if gbc.GB_IHT_ON in extra else False
    TB_costing_on = extra[gbc.GB_TB_COSTING_ON] if gbc.GB_TB_COSTING_ON in extra else False
    LiST_costing_on = extra[gbc.GB_LIST_COSTING_ON] if gbc.GB_LIST_COSTING_ON in extra else False
    plan_type = extra[gbc.GB_Extra_plantype] if gbc.GB_Extra_plantype in extra else iccl.IC_IH_COMPREHENSIVE_PLAN

    costing_mode_mod_vars = {
        pjmvt.GB_IHTOnTag       : IHT_costing_on,
        pjmvt.GB_TBCostingOnTag : TB_costing_on,
        pjmvt.GB_LCOnTag        : LiST_costing_on,
    }
    
    # Extra data from optional modules
    active_modules = extra[gbc.GB_MODULES]
    active_methods_FP = None
    if gbc.GB_FP in active_modules:
        active_methods_FP = extra[iccl.IC_FP_ActiveMethodsTag]
    
    syph_among_WRA_mv = None
    selected_intervs_CS = None
    CS_IV_info = None
    # enter_BF_improve_data = None

    if gbc.GB_CS in active_modules:
        syph_among_WRA_mv = extra[iccl.IC_CS_SyphilisAmongWRATag]
        selected_intervs_CS = extra[iccl.IC_CS_SelectedIVSetTag]
        CS_IV_info = extra[iccl.IC_CS_IVInfoTag]
        # enter_BF_improve_data = extra[iccl.IC_CS_EnterBFImproveDataTag]

    # file_list = GB_file_list(environment, gbc.GB_IC_CONTAINER, '')
    # for i, file_name in enumerate(file_list):
    #     log(file_name)

    num_years_inputs = final_year - first_year + 1 
    num_years_outputs = final_year - first_year + 1

    num_prog_areas = icul.IC_get_IH_num_prog_areas(prog_area_records_mv)
    num_staff_types = icul.IC_get_HW_num_staff_types(staff_type_records_mv)

    costing_mode = gbu.get_costing_mode(costing_mode_mod_vars)

    num_costed_deliv_chans = 0
    if costing_mode == gbc.GB_LIST_COSTING_MODE:
        num_costed_deliv_chans = iccl.IC_IH_NUM_DEFAULT_DELIV_CHANS_COSTED_CS
    
    else:
        num_costed_deliv_chans = iccl.IC_IH_NUM_DEFAULT_DELIV_CHANS_COSTED

    num_deliv_chan_IC = num_costed_deliv_chans + icc.IC_NUM_DELIV_CHANS

    num_costing_sections_CS = 0
    if costing_mode == gbc.GB_LIST_COSTING_MODE:
        num_costing_sections_CS = icul.IC_get_PC_num_costing_sects(costing_sect_records_mv, iccl.IC_IH_MODULE_MST_ID, str(gbc.GB_CS))

    #######################################################################################################
    #                                                                                                     #
    #                                       Inputs                                                        #
    #                                                                                                     #
    #######################################################################################################

    drug_supply_DB = icrd.IC_load_drug_supply_DB()
    intervention_DB, intervention_DB_IHT_ID_info_only = icrd.IC_load_intervention_DB(costing_mode)
    PIN_DB = icrd.IC_load_PIN_DB(country_ID)
    PIN_by_year_DB = icrd.IC_load_PIN_by_year_DB(country_ID)
    non_impact_coverage_DB = icrd.IC_load_non_impact_coverage_DB(country_ID)
    #non_impact_coverage_by_year_DB = icrd.IC_load_non_impact_coverage_by_year_DB()
    targ_pop_direct_entry_DB = icrd.IC_load_targ_pop_direct_entry_DB(country_ID)
    targ_pop_DB = icrd.IC_load_targ_pop_DB()
    treatment_input_group_DB = icrd.IC_load_treatment_input_group_DB()
    treatment_input_DB = icrd.IC_load_treatment_input_DB()

    health_system_costs_DB_CS = None
    outpat_visit_inpat_day_costs_CS_DB = None

    if costing_mode == gbc.GB_LIST_COSTING_MODE:
        health_system_costs_DB_CS = icrd.IC_load_health_system_costs_CS_DB(country_ID)
        outpat_visit_inpat_day_costs_CS_DB = icrd.IC_load_outpat_visit_inpat_day_costs_CS_DB(country_ID)

    elif costing_mode == gbc.GB_TB_COSTING_MODE:
        outpat_visit_inpat_day_costs_TB_DB = icrd.IC_load_outpat_visit_inpat_day_costs_TB_DB(country_ID)

    #######################################################################################################
    #                                                                                                     #
    #               Pre-results / Calculated - These databases are made in ICProj                         #
    #                                                                                                     #
    #######################################################################################################

    drug_cost_per_avg_case_DB = icrd.IC_load_drug_cost_per_avg_case_DB(costing_mode)
    supply_cost_per_avg_case_DB = icrd.IC_load_supply_cost_per_avg_case_DB(costing_mode)
    med_personnel_min_per_avg_case_DB = icrd.IC_load_med_personnel_min_per_avg_case_DB(costing_mode)

    # IC_TREATMENT_INPUT_DB_NAME             = 'TreatmentInputDB'
    # IC_ADOLESCENT_HEALTH_PIN_DB_NAME       = 'AdolescentHealthPIN_DB'
    # IC_ADOLESCENT_HEALTH_COV_DB_NAME       = 'AdolescentHealthCov_DB'
    # IC_OTHER_COSTS_DB_NAME                 = 'OtherCostsDB'

    value_bool_False = False
    value_bool_True = True
    value_int = 0
    value_flt = 0.0
    value_date = date.today().strftime("%B %d, %Y"),   
    value_list = []

    #######################################################################################################
    #                                                                                                     #
    #                                       Inputs                                                        #
    #                                                                                                     #
    #######################################################################################################

    drug_supply_records = icrd.IC_init_drug_supply_records(drug_supply_DB, num_years_inputs, costing_mode, plan_type)
    targ_pop_records = icrd.IC_init_targ_pop_def_records(targ_pop_DB, costing_mode)

    interv_records = icrd.IC_init_interv_records(intervention_DB, targ_pop_records, active_modules, num_years_inputs, costing_mode)
    interv_records = icrd.IC_set_intervs_PIN(interv_records, PIN_DB, num_years_inputs)
    interv_records = icrd.IC_set_intervs_PIN_by_year(interv_records, PIN_by_year_DB, num_years_inputs)
    interv_records = icrd.IC_set_intervs_non_impact_coverage(interv_records, non_impact_coverage_DB, num_years_inputs, costing_mode)
    # There are currently no more interventions to be read in from non_impact_coverage_by_year_DB. Leave as placeholder in case this type comes back.
    #interv_records = icrd.IC_set_interv_non_impact_coverage_by_year(interv_records, non_impact_coverage_by_year_DB, num_years_inputs)
    interv_records = icrd.IC_set_intervs_targ_pop_direct_entry(interv_records, targ_pop_direct_entry_DB)
    
    # Turn off some interventions by default.
    if costing_mode == gbc.GB_IHT_COSTING_MODE:
        # These overlap with a version from 0-14 years.
        icmvu.set_IC_interv_active(icmvu.get_IC_interv_rec(interv_records, IC_IV_ScreenProvInitHHChildren0t4_MST_ID), False)
        icmvu.set_IC_interv_active(icmvu.get_IC_interv_rec(interv_records, IC_IV_ScreenProvInitHHChildren5t14_MST_ID), False)
        
    elif costing_mode == gbc.GB_TB_COSTING_MODE:
        # These overlap with a version from 0-14 years.
        icmvu.set_IC_interv_active(icmvu.get_IC_interv_rec(interv_records, IC_TI_IV_ScreenProvInitHHChildren0t4_MST_ID), False)
        icmvu.set_IC_interv_active(icmvu.get_IC_interv_rec(interv_records, IC_TI_IV_ScreenProvInitHHChildren5t14_MST_ID), False)

    # IHT now shows all LiST interventions except the FamPlan and HIV ones, so activate them.
    if costing_mode == gbc.GB_IHT_COSTING_MODE:
        if gbc.GB_CS in active_modules:
            required_mod_vars = {
                iccl.IC_CS_IVInfoTag             : CS_IV_info, 
                iccl.IC_CS_SelectedIVSetTag      : selected_intervs_CS,
            }

            interv_to_exclude = []

            for mstID in acu.GBRange(iccl.CS_FirstFPMstID, iccl.CS_LastFPMstID):
                interv_to_exclude.append(mstID)
            
            interv_to_exclude.append(iccl.CS_FirstAMMstID)  
            interv_to_exclude.append(iccl.CS_MstPercOnART)
            interv_to_exclude.append(int(iccl.CS_IV_PMTCT_MST_ID))
            interv_to_exclude.append(int(iccl.CS_IV_Cotrimoxazole_MST_ID))

            icul.IC_CS_set_interventions_active(required_mod_vars, interv_to_exclude)

    if costing_mode == gbc.GB_IHT_COSTING_MODE:
        if gbc.GB_FP in active_modules:
            icu.set_IC_method_intervention_active_status({
                icmvt.IC_INTERV_RECORDS_TAG : interv_records,
                iccl.IC_FP_ActiveMethodsTag    : active_methods_FP,
                pjmvt.GB_LCOnTag               : LiST_costing_on,
            })

    elif costing_mode == gbc.GB_LIST_COSTING_MODE:
        icu.set_IC_CS_intervention_active_status({
            icmvt.IC_INTERV_RECORDS_TAG    : interv_records,
            iccl.IC_CS_SelectedIVSetTag    : selected_intervs_CS,
            iccl.IC_FP_ActiveMethodsTag    : active_methods_FP,
            pjmvt.GB_LCOnTag               : LiST_costing_on,
            iccl.IC_CS_IVInfoTag           : CS_IV_info,
        })

    TIG_drug_supply_records, TIG_med_personnel_records, TIG_outpat_inpat_records = \
        icrd.IC_init_treatment_input_group_records(interv_records, treatment_input_group_DB)
    TI_drug_supply_records, TI_med_personnel_records, TI_outpat_inpat_records = \
        icrd.IC_init_treatment_input_records(interv_records, treatment_input_DB, num_years_inputs)
    
    # These PINs are kept outside of the intervention records where the other PINs are kept because they will only ever get used for
    # a couple of interventions out of hundreds and we don't want to bloat the intervention records with unnecessary fields
    alt_PIN_age_group_set_1_records = icrd.IC_init_alt_PIN_age_group_set_1_records(interv_records, num_years_inputs)
    alt_PIN_age_group_set_2_records = icrd.IC_init_alt_PIN_age_group_set_2_records(interv_records, num_years_inputs)

    # If TB costing is on, we'll need access to the IHT interventions well, because the user is allowed to move IHT interventions into TB. 
    outpat_visit_inpat_day_costs_TB = []
    interv_records_IHT_ID_info_only = []

    if costing_mode == gbc.GB_TB_COSTING_MODE:
        outpat_visit_inpat_day_costs_TB = icrd.IC_set_outpat_visit_inpat_day_costs_TB_MVs(outpat_visit_inpat_day_costs_TB_DB)
        interv_records_IHT_ID_info_only = icrd.IC_init_interv_records_ID_info_only(intervention_DB_IHT_ID_info_only, str(iccl.IH_TB_MST_ID))

    elif costing_mode == gbc.GB_LIST_COSTING_MODE:
        other_recurrent_costs, capital_costs = icrd.IC_set_outpat_visit_inpat_day_costs_CS_MVs(outpat_visit_inpat_day_costs_CS_DB)
        supply_chain_cost_perc_commodity_cost, infrastructure_investment, ratio_other_health_system_to_interv_costs, \
            income_level, supply_chain_status = icrd.IC_set_health_system_costs_MVs(health_system_costs_DB_CS, num_years_inputs) 
        
    required_mod_vars = {
        pjmvt.PJN_FirstYearTag                       : first_year, 
        pjmvt.PJN_FinalYearTag                       : final_year, 
        icmvt.IC_TREAT_INPUT_DRUG_SUPPLY_RECORDS_TAG : TI_drug_supply_records,
        iccl.IC_CS_SyphilisAmongWRATag               : syph_among_WRA_mv,
    }

    if gbc.GB_CS in active_modules:
        icu.IC_set_treatment_input_defaults_from_LiST(required_mod_vars)

    num_intervs = icmvu.get_IC_num_intervs(interv_records)
    num_drugs_supplies = icmvu.get_IC_num_drugs_supplies(drug_supply_records)

    #######################################################################################################
    #                                                                                                     #
    #                                       Pre-results / Calculated                                      #
    #                                                                                                     #
    #######################################################################################################

    # To create the database needed to set these up,
    #   1. Comment out the lines below that read from the databases and uncomment the lines that set the MVs to empty lists.
    #   2. Create a projection. Country and years are irrelevant. IH and IC are the only relevant IHT modules.
    #   3. In ICProj, go to finalize_mod_vars, and uncomment the relevant database code.
    #   4. Run calculations.
    #   5. Uncomment the lines below that read from the databases and comment out the lines that set the MVs to empty lists. (reverse of 1)
    #   6. In ICProj, go to finalize_mod_vars, and comment out the relevant database code. (reverse of 3)
    drug_cost_per_avg_case = icrd.IC_set_drug_cost_per_avg_case(interv_records, num_years_outputs, drug_cost_per_avg_case_DB)
    supply_cost_per_avg_case = icrd.IC_set_supply_cost_per_avg_case(interv_records, num_years_outputs, supply_cost_per_avg_case_DB)
    med_personnel_min_per_avg_case_def = icrd.IC_set_med_personnel_min_per_avg_case_def(interv_records, num_years_outputs, med_personnel_min_per_avg_case_DB)
    # drug_cost_per_avg_case = []
    # supply_cost_per_avg_case = []
    # med_personnel_min_per_avg_case_def = []

    #######################################################################################################
    #                                                                                                     #
    #                              ModVars for special modes                                              #
    #                                                                                                     #
    #######################################################################################################

    # Disease-specific costing / TB Costing

    outpat_visit_inpat_day_unit_costs_3d_list = np.full((icc.IC_NUM_VISIT_TYPES, num_costed_deliv_chans, num_prog_areas), 0.0).tolist()

    # Comprehensive vs specific plan (CVS)

    outpat_inpat_costs_2d_list_CVS = np.full((icc.IC_NUM_VISIT_TYPES, num_costed_deliv_chans), 0.0).tolist()

    ###################################################################################################################
    # 
    #                                             For testing calculations
    #
    ###################################################################################################################

    # t1 = gbu.getYearIdx(first_year, first_year)
    # t2 = gbu.getYearIdx(final_year, first_year)

    # for interv_rec in interv_records:
    #     impact_interv = icmvu.get_IC_impact_interv(interv_rec)

    #     for t in acu.GBRange(t1, t2):
    #         if math.isclose(icmvu.get_IC_interv_PIN(interv_rec, t), 0.0):
    #             icmvu.set_IC_interv_PIN(interv_rec, t, 100.0)

    #         if (not impact_interv) and math.isclose(icmvu.get_IC_interv_non_impact_cov(interv_rec, t), 0.0):
    #             icmvu.set_IC_interv_non_impact_cov(interv_rec, t, 100.0)

    # # To test number of services, change the targ pop of Management of opportunistic infections (an HIV non-impact intervention) to total population from DemProj
    # mgmt_opp_inf_interv_rec = icmvu.get_IC_interv_rec(interv_records, icii.IC_IV_MgmtOppInfHIV_AIDS_MST_ID)
    # icmvu.set_IC_interv_targ_pop_mst_ID(mgmt_opp_inf_interv_rec, icc.IC_TP_TOTAL_POPULATION_MST_ID)

    mod_vars_rec = {
        # Inputs / pre-result / calculated
		
        icmvt.IC_VERSION_TAG_V1                                   : 2,
        icmvt.IC_DATA_CHANGED_TAG_V1                              : value_bool_False, 
        icmvt.IC_PROJ_VALID_TAG_V1                                : value_bool_False, 
        icmvt.IC_PROJ_VALID_DATE_TAG_V1                           : value_date,  
        icmvt.IC_SHOW_ALL_YEARS_INTERV_COV_TAG_V1                 : value_bool_False, 
        icmvt.IC_SHOW_ALL_FP_METHODS_INTERV_COV_TAG_V1            : value_bool_False, 
        icmvt.IC_SHOW_ALL_YEARS_INTERV_PIN_TAG_V1                 : value_bool_False, 
        icmvt.IC_ENTER_DET_PMTCT_DATA_TAG_V1                      : value_bool_False, 
        icmvt.IC_ENTER_NET_AGE_DIST_PERC_TAG_V1                   : value_bool_False, 
        icmvt.IC_POST_TREAT_SURV_FOLLOW_UP_VIS_TAG_V1             : value_bool_False, 
        icmvt.IC_MAX_CUSTOM_DRUG_SUPP_MST_ID_TAG_V1               : value_int, 
        icmvt.IC_COV_YEAR_BEF_BASE_YEAR_ITN_TAG_V1                : value_flt,
        icmvt.IC_NET_LIFETIME_ITN_TAG_V1                          : value_flt,
        icmvt.IC_AVG_NET_AGE_ITN_TAG_V1                           : value_flt,
        #icmvt.IC_NUM_PERC_NETS_BY_AGE_TAG_V1                     : array [1..IC_MaxNetAge] of double;
        #icmvt.IC_DRUG_PRICE_ADJUST_TAG_V1                        : array [IC_Transport..IC_Wastage] of double;
        icmvt.IC_INTERV_RECORDS_TAG                               : interv_records,
        icmvt.IC_TREAT_INPUT_DRUG_SUPPLY_RECORDS_TAG              : TI_drug_supply_records,
        icmvt.IC_TREAT_INPUT_MED_PERSONNEL_RECORDS_TAG            : TI_med_personnel_records,
        icmvt.IC_TREAT_INPUT_OUTPAT_INPAT_RECORDS_TAG             : TI_outpat_inpat_records,
        icmvt.IC_TREAT_INPUT_GROUP_DRUG_SUPPLY_RECORDS_TAG        : TIG_drug_supply_records,
        icmvt.IC_TREAT_INPUT_GROUP_MED_PERSONNEL_RECORDS_TAG      : TIG_med_personnel_records,
        icmvt.IC_TREAT_INPUT_GROUP_OUTPAT_INPAT_RECORDS_TAG       : TIG_outpat_inpat_records,
        icmvt.IC_DRUG_SUPPLY_RECORDS_TAG                          : drug_supply_records,
        icmvt.IC_TARG_POP_RECORDS_TAG                          : targ_pop_records,
        #icmvt.IC_NEED_BRST_CNCR_TRT_FLLW_UP_TAG_V1               :
        #icmvt.IC_OWNER_USAGE_RATIO_ARRAY_ITN_TAG_V1              : TDoubleDynArray;
        #icmvt.IC_STRATA_INTERV_LIST_TAG_V1                       :
        #icmvt.IC_ALT_COV_LIST_TAG_V1                             :
		icmvt.IC_ALT_PIN_AGE_GROUP_SET_1_LIST_TAG_V1              : alt_PIN_age_group_set_1_records,
        icmvt.IC_ALT_PIN_AGE_GROUP_SET_2_LIST_TAG_V1              : alt_PIN_age_group_set_2_records,
        #icmvt.IC_STRATUM_RECORDS_TAG_V1                          : array of TObjectList; // mark0310
        #icmvt.IC_OUTP_VISIT_INP_DAY_UNIT_COST_TAG_V1             : GB_TDoubleDyn3DArray;
        #icmvt.IC_NON_DEF_TARG_POPS_TAG_V1                        : array of GB_TIntSet; // mark1207
        icmvt.IC_VARY_TREATMENT_INPUTS_BY_TIME_TAG_V1             : value_bool_True,
        # '<IC_DrugCostPerCase_T1>'                               : np.full((460, 5, 60), 0.0).tolist(),
        # '<IC_SupplyCostPerCase_T1>'                             : np.full((460, 5, 60), 0.0).tolist(),
        # '<IC_LaborCostPerCase_T1>'                              : np.full((460, 5, 60), 0.0).tolist(),
        # '<IC_MinPerAvgCaseCustomStaff_T1>'                      : np.full((460, 5, 40, 60), 0).tolist(),
        # '<IC_MinPerAvgCaseDefaultStaff_T1>'                     : np.full((460, 5, 40, 60), 0).tolist(),
        icmvt.IC_DRUG_COST_PER_CASE_TAG_V1                        : drug_cost_per_avg_case,
        icmvt.IC_SUPPLY_COST_PER_CASE_TAG_V1                      : supply_cost_per_avg_case,
        icmvt.IC_INPATIENT_DAYS_PER_CASE_TAG_V1                   : [],
        icmvt.IC_OUTPATIENT_VISITS_PER_CASE_TAG_V1                : [],
        icmvt.IC_MIN_PER_AVG_CASE_STATIC_STAFF_TAG_V1             : med_personnel_min_per_avg_case_def,
        icmvt.IC_MIN_PER_AVG_CASE_DYNAMIC_STAFF_TAG_V1            : value_list,
        # icmvt.IC_POP_IN_NEED_VISITED_TAG_V1                       : False,
        icmvt.IC_FAM_PLAN_GOAL_TAG_V1                             : icc.CPR_GOAL_MST_ID, #icc.UNMET_NEED_GOAL_MST_ID, 
        icmvt.IC_PERC_UNMET_NEED_COVERED_TAG_V1                   : icmvd.IC_init_year_arr(num_years_inputs, 0.0),

        # Outputs / results

        icmvt.IC_RES_NUM_SERVICES_BY_DELIV_CHAN_TAG_V1           : icmvd.IC_init_interv_deliv_chan_all_year_arr(num_intervs, num_deliv_chan_IC, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_TARG_POPS_TAG_V1                            : icmvd.IC_init_interv_year_arr(num_intervs, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_PEOPLE_NEEDING_SERVICES_TAG_V1              : icmvd.IC_init_interv_year_arr(num_intervs, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_NUM_SERVICES_TAG_V1                         : icmvd.IC_init_interv_year_arr(num_intervs, num_years_outputs, 0.0).tolist(), 
        #icmvt.IC_RES_ADDIT_NUM_SERVICES_BY_DELIV_CHAN_TAG_V1     : [],
        #icmvt.IC_RES_ADDIT_NUM_SERVICES_TAG_V1                   : [],
        icmvt.IC_RES_PERC_DELIV_THROUGH_CHAN_BY_YEAR_TAG_V1      : icmvd.IC_init_interv_deliv_chan_all_year_arr(num_intervs, num_deliv_chan_IC, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DRUG_COSTS_TAG_V1                           : icmvd.IC_init_interv_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        #icmvt.IC_RES_ADDIT_DRUG_COSTS_TAG_V1                     : [],
        icmvt.IC_RES_DRUG_COSTS_BY_YEAR_ONLY_TAG_V1              : icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_SUPPLY_COSTS_TAG_V1                         : icmvd.IC_init_interv_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        #icmvt.IC_RES_ADDIT_SUPPLY_COSTS_TAG_V1                   : [],
        icmvt.IC_RES_SUPPLY_COSTS_BY_YEAR_ONLY_TAG_V1            : icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist(),
        #icmvt.IC_RES_ADDIT_DRUG_SUPPLY_COSTS_TAG_V1              : [],
        icmvt.IC_RES_STATIC_STAFF_TIME_REQ_BY_DELIV_CHAN_TAG_V1  : icmvd.IC_init_static_staff_costed_deliv_chan_year_arr(num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_STATIC_STAFF_TIME_REQ_BY_INTERV_TAG_V1      : icmvd.IC_init_static_staff_interv_year_arr(num_intervs, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_STATIC_STAFF_TIME_REQ_BY_PROG_AREA_TAG_V1   : icmvd.IC_init_static_staff_prog_area_year_arr(num_prog_areas, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_STATIC_STAFF_TIME_REQ_BY_PROG_AREA_DELIV_CHAN_TAG_V1   : icmvd.IC_init_static_staff_prog_area_deliv_chan_year_arr(num_prog_areas, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DYNAMIC_STAFF_TIME_REQ_BY_DELIV_CHAN_TAG_V1 : icmvd.IC_init_dynamic_staff_costed_deliv_chan_year_arr(num_staff_types, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DYNAMIC_STAFF_TIME_REQ_BY_INTERV_TAG_V1     : icmvd.IC_init_dynamic_staff_interv_year_arr(num_staff_types, num_intervs, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DYNAMIC_STAFF_TIME_REQ_BY_PROG_AREA_TAG_V1  : icmvd.IC_init_dynamic_staff_prog_area_year_arr(num_staff_types, num_prog_areas, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DYNAMIC_STAFF_TIME_REQ_BY_PROG_AREA_DELIV_CHAN_TAG_V1  : icmvd.IC_init_dynamic_staff_prog_area_deliv_chan_year_arr(num_staff_types, num_prog_areas, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        # These two are too large and need to be converted to records.
        #icmvt.IC_RES_DRUG_UNITS_PER_AVG_CASE_TAG_V1              : icmvd.IC_init_drug_supply_interv_deliv_chan_year_arr(num_drugs_supplies, num_intervs, iccl.IC_IH_NUM_DEFAULT_DELIV_CHANS, num_years_outputs, 0.0).tolist(),
        #icmvt.IC_RES_SUPPLY_UNITS_PER_AVG_CASE_TAG_V1            : icmvd.IC_init_drug_supply_interv_deliv_chan_year_arr(num_drugs_supplies, num_intervs, iccl.IC_IH_NUM_DEFAULT_DELIV_CHANS, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_DRUGS_REQUIRED_BY_DELIV_CHAN_TAG            : icmvd.IC_init_drug_supply_costed_deliv_chan_year_arr(num_drugs_supplies, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_SUPPLIES_REQUIRED_BY_DELIV_CHAN_TAG         : icmvd.IC_init_drug_supply_costed_deliv_chan_year_arr(num_drugs_supplies, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
       
        icmvt.IC_RES_DRUGS_REQUIRED_BY_PROG_AREA_TAG            : icmvd.IC_init_drug_supply_prog_area_year_arr(num_drugs_supplies, num_prog_areas, num_years_outputs, 0.0).tolist(),
        icmvt.IC_RES_SUPPLIES_REQUIRED_BY_PROG_AREA_TAG         : icmvd.IC_init_drug_supply_prog_area_year_arr(num_drugs_supplies, num_prog_areas, num_years_outputs, 0.0).tolist(),
       
        icmvt.IC_RES_OUTPAT_VISITS_INPAT_DAYS_TAG_V1             : icmvd.IC_init_interv_visit_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist(),
		
		# Comprehensive vs specific plan (CVS)

        icmvt.IC_OUTPAT_INPAT_COSTS_CVS_TAG_V1                  : outpat_inpat_costs_2d_list_CVS # input
    }

    # Disease-specific costing (DSC), TB Costing

    # If TB costing is on, we'll need access to the IHT interventions well, because the user is allowed to move IHT interventions into TB. 
    if costing_mode == gbc.GB_TB_COSTING_MODE:
        
        #icmvt.IC_OUTPAT_VISIT_INPAT_DAY_UNIT_COSTS_DSC_TAG_V1   : outpat_visit_inpat_day_unit_costs_3d_list, # input
        mod_vars_rec[icmvt.IC_RES_OUTPAT_VISIT_INPAT_DAY_COSTS_DSC_TAG_V1] = icmvd.IC_init_interv_visit_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist()

        mod_vars_rec[icmvt.IC_RES_LOG_SUPPLY_CHAIN_COSTS_TB_TAG] = icmvd.IC_init_drug_supply_year_arr(num_drugs_supplies, num_years_outputs)
        mod_vars_rec[icmvt.IC_RES_WASTAGE_COSTS_TB_TAG] = icmvd.IC_init_drug_supply_year_arr(num_drugs_supplies, num_years_outputs)
        
        # If TB costing is on, we'll need access to the IHT interventions as well, because the user is allowed to move IHT interventions into TB. 
        mod_vars_rec[icmvt.IC_OUTPAT_INPAT_COSTS_CVS_TAG_V1] = outpat_visit_inpat_day_costs_TB
        mod_vars_rec[icmvt.IC_INTERV_RECORDS_IHT_ID_INFO_ONLY_TB_TAG_V1] = interv_records_IHT_ID_info_only

    # LiST Costing

    elif costing_mode == gbc.GB_LIST_COSTING_MODE:

        mod_vars_rec[icmvt.IC_OTHER_RECURRENT_COSTS_CS_TAG_V1] = other_recurrent_costs
        mod_vars_rec[icmvt.IC_CAPITAL_COSTS_CS_TAG_V1] = capital_costs
        mod_vars_rec[icmvt.IC_SUPPLY_CHAIN_COST_PERC_COMMODITY_COST_CS_TAG_V1] = supply_chain_cost_perc_commodity_cost
        mod_vars_rec[icmvt.IC_WASTAGE_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_inputs, 5).tolist()
        mod_vars_rec[icmvt.IC_INFRASTRUCTURE_INVESTMENT_CS_TAG_V1] = infrastructure_investment
        mod_vars_rec[icmvt.IC_INFRASTRUCTURE_ALLOC_PORTION_FOR_PROJ_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_inputs, 0.5).tolist()
        mod_vars_rec[icmvt.IC_RATIO_OTHER_HEALTH_SYSTEM_TO_INTERV_COSTS_CS_TAG_V1] = ratio_other_health_system_to_interv_costs
        mod_vars_rec[icmvt.IC_HEALTH_SYSTEM_PROG_COSTS_SUM_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_inputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_OTHER_HEALTH_SYSTEM_COSTS_VIS_CS_TAG_V1] = False
        mod_vars_rec[icmvt.IC_INCOME_LEVEL_CS_META_TAG_V1] = income_level
        mod_vars_rec[icmvt.IC_SUPPLY_CHAIN_STATUS_CS_META_TAG_V1] = supply_chain_status

        mod_vars_rec[icmvt.IC_RES_OTHER_RECURRENT_COSTS_CS_TAG_V1] = icmvd.IC_init_interv_visit_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_CAPITAL_COSTS_CS_TAG_V1] = icmvd.IC_init_interv_visit_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_PROGRAM_COSTS_CS_TAG_V1] = icmvd.IC_init_costing_sect_year_arr(num_costing_sections_CS, num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_LOGISTICS_COSTS_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_WASTAGE_COSTS_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_INFRASTRUCTURE_INVESTMENT_COSTS_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_RES_OTHER_HEALTH_SYSTEM_COSTS_CS_TAG_V1] = icmvd.IC_init_year_arr(num_years_outputs, 0.0).tolist()

        mod_vars_rec[icmvt.IC_COSTS_BY_INT_CS_TAG_V1] = icmvd.IC_init_interv_arr(num_intervs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_DISC_SOCIAL_BENEFITS_BY_INT_CS_TAG_V1] = icmvd.IC_init_interv_arr(num_intervs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_DISC_ECON_BENEFITS_BY_INT_CS_TAG_V1] = icmvd.IC_init_interv_arr(num_intervs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_DISC_INC_IN_EARN_REDUC_BY_INT_CS_TAG_V1] = icmvd.IC_init_interv_arr(num_intervs, 0.0).tolist()
        mod_vars_rec[icmvt.IC_BCR_BY_INT_CS_TAG_V1] = icmvd.IC_init_interv_arr(num_intervs, 0.0).tolist()
        
    if (
        ((costing_mode == gbc.GB_IHT_COSTING_MODE) and (plan_type == iccl.IC_IH_SPECIFIC_PLAN)) 
        or (costing_mode == gbc.GB_TB_COSTING_MODE) 
        or (costing_mode == gbc.GB_LIST_COSTING_MODE)
    ):
        mod_vars_rec[icmvt.IC_RES_LABOR_COSTS_DSC_TAG_V1] = icmvd.IC_init_interv_costed_deliv_chan_year_arr(num_intervs, num_costed_deliv_chans, num_years_outputs, 0.0).tolist()#icmvd.IC_init_interv_deliv_chan_all_year_arr(num_intervs, num_deliv_chan_IC, num_years_outputs, 0.0).tolist()

    #Debugging
    #with open('C:\Proj\ICSampleFile.JSON', 'w') as f:
    #    json.dump(mod_vars_dict, f)

    return mod_vars_rec