# coding=UTF-8
import functools

from natcap.invest.ui import model, inputs
from natcap.invest.coastal_blue_carbon import coastal_blue_carbon
from natcap.invest.coastal_blue_carbon import preprocessor


class CoastalBlueCarbonPreprocessor(model.InVESTModel):
    def __init__(self):
        model.InVESTModel.__init__(
            self,
            label='Coastal Blue Carbon Preprocessor',
            target=preprocessor.execute,
            validator=preprocessor.validate,
            localdoc='../documentation/coastal_blue_carbon.html')

        self.lulc_lookup_uri = inputs.File(
            args_key='lulc_lookup_uri',
            helptext=(
                "A CSV table used to map lulc classes to their values "
                "in a raster, as well as to indicate whether or not "
                "the lulc class is a coastal blue carbon habitat."),
            label='LULC Lookup Table (CSV)',
            validator=self.validator)
        self.add_input(self.lulc_lookup_uri)
        self.lulc_snapshot_list = inputs.Multi(
            args_key='lulc_snapshot_list',
            callable_=functools.partial(inputs.File, label="Input"),
            label='Land Use/Land Cover Rasters (GDAL-supported)',
            link_text='Add Another')
        self.add_input(self.lulc_snapshot_list)

    def assemble_args(self):
        args = {
            self.workspace.args_key: self.workspace.value(),
            self.suffix.args_key: self.suffix.value(),
            self.lulc_lookup_uri.args_key: self.lulc_lookup_uri.value(),
            self.lulc_snapshot_list.args_key: self.lulc_snapshot_list.value(),
        }
        return args


class CoastalBlueCarbon(model.InVESTModel):
    def __init__(self):
        model.InVESTModel.__init__(
            self,
            label='Coastal Blue Carbon',
            target=coastal_blue_carbon.execute,
            validator=coastal_blue_carbon.validate,
            localdoc='../documentation/coastal_blue_carbon.html')

        self.lulc_lookup_uri = inputs.File(
            args_key='lulc_lookup_uri',
            helptext=(
                "A CSV table used to map lulc classes to their values "
                "in a raster and to indicate whether or not the lulc "
                "class is a coastal blue carbon habitat."),
            label='LULC Lookup Table (CSV)',
            validator=self.validator)
        self.add_input(self.lulc_lookup_uri)
        self.lulc_transition_matrix_uri = inputs.File(
            args_key='lulc_transition_matrix_uri',
            helptext=(
                "Generated by the preprocessor.  This file must be "
                "edited before it can be used by the main model.  The "
                "left-most column represents the source lulc class, "
                "and the top row represents the destination lulc "
                "class."),
            label='LULC Transition Effect of Carbon Table (CSV)',
            validator=self.validator)
        self.add_input(self.lulc_transition_matrix_uri)
        self.carbon_pool_initial_uri = inputs.File(
            args_key='carbon_pool_initial_uri',
            helptext=(
                "The provided CSV table contains information related "
                "to the initial conditions of the carbon stock within "
                "each of the three pools of a habitat.  Biomass "
                "includes carbon stored above and below ground.  All "
                "non-coastal blue carbon habitat lulc classes are "
                "assumed to contain no carbon.  The values for "
                "‘biomass’, ‘soil’, and ‘litter’ should be given in "
                "terms of Megatonnes CO2e/ha."),
            label='Carbon Pool Initial Variables Table (CSV)',
            validator=self.validator)
        self.add_input(self.carbon_pool_initial_uri)
        self.carbon_pool_transient_uri = inputs.File(
            args_key='carbon_pool_transient_uri',
            helptext=(
                "The provided CSV table contains information related "
                "to the transition of carbon into and out of coastal "
                "blue carbon pools.  All non-coastal blue carbon "
                "habitat lulc classes are assumed to neither sequester "
                "nor emit carbon as a result of change.  The "
                "‘yearly_accumulation’ values should be given in terms "
                "of Megatonnes of CO2e/ha-yr.  The ‘half-life’ values "
                "must be given in terms of years.  The ‘disturbance’ "
                "values must be given as a decimal percentage of stock "
                "distrubed given a transition occurs away from a lulc- "
                "class."),
            label='Carbon Pool Transient Variables Table (CSV)',
            validator=self.validator)
        self.add_input(self.carbon_pool_transient_uri)
        self.lulc_baseline_map_uri = inputs.File(
            args_key='lulc_baseline_map_uri',
            helptext=(
                "A GDAL-supported raster representing the baseline "
                "landscape/seascape."),
            label='Baseline LULC Raster (GDAL-supported)',
            validator=self.validator)
        self.add_input(self.lulc_baseline_map_uri)
        self.lulc_baseline_year = inputs.Text(
            args_key='lulc_baseline_year',
            label='Year of baseline LULC raster',
            validator=self.validator)
        self.add_input(self.lulc_baseline_year)
        self.lulc_transition_maps_list = inputs.Multi(
            args_key='lulc_transition_maps_list',
            callable_=functools.partial(inputs.File, label="Input"),
            label='Transition LULC Rasters (GDAL-supported)',
            link_text='Add Another')
        self.add_input(self.lulc_transition_maps_list)
        self.lulc_transition_years_list = inputs.Multi(
            args_key='lulc_transition_years_list',
            callable_=functools.partial(inputs.Text, label="Input"),
            label='Transition Years',
            link_text='Add Another')
        self.add_input(self.lulc_transition_years_list)
        self.analysis_year = inputs.Text(
            args_key='analysis_year',
            helptext=(
                "An analysis year extends the transient analysis "
                "beyond the transition years."),
            label='Analysis Year (Optional)',
            validator=self.validator)
        self.add_input(self.analysis_year)
        self.do_economic_analysis = inputs.Container(
            args_key='do_economic_analysis',
            expandable=True,
            expanded=True,
            label='Calculate Net Present Value of Sequestered Carbon')
        self.add_input(self.do_economic_analysis)
        self.do_price_table = inputs.Checkbox(
            args_key='do_price_table',
            helptext='',
            label='Use Price Table')
        self.do_economic_analysis.add_input(self.do_price_table)
        self.price = inputs.Text(
            args_key='price',
            helptext='The price per Megatonne CO2e at the base year.',
            label='Price',
            validator=self.validator)
        self.do_economic_analysis.add_input(self.price)
        self.interest_rate = inputs.Text(
            args_key='interest_rate',
            helptext=(
                "The interest rate on the price per Megatonne CO2e, "
                "compounded yearly."),
            label='Interest Rate (%)',
            validator=self.validator)
        self.do_economic_analysis.add_input(self.interest_rate)
        self.price_table_uri = inputs.File(
            args_key='price_table_uri',
            helptext=(
                "Can be used in place of price and interest rate "
                "inputs.  The provided CSV table contains the price "
                "per Megatonne CO2e sequestered for a given year, for "
                "all years from the original snapshot to the analysis "
                "year, if provided."),
            interactive=False,
            label='Price Table (CSV)',
            validator=self.validator)
        self.do_economic_analysis.add_input(self.price_table_uri)
        self.discount_rate = inputs.Text(
            args_key='discount_rate',
            helptext=(
                "The discount rate on future valuations of "
                "sequestered carbon, compounded yearly."),
            label='Discount Rate (%)',
            validator=self.validator)
        self.do_economic_analysis.add_input(self.discount_rate)

        # Set interactivity, requirement as input sufficiency changes
        self.do_price_table.sufficiency_changed.connect(
            self._price_table_sufficiency_changed)

    def _price_table_sufficiency_changed(self, new_sufficiency):
        self.price.set_interactive(not new_sufficiency)
        self.interest_rate.set_interactive(not new_sufficiency)
        self.price_table_uri.set_interactive(new_sufficiency)

    def assemble_args(self):
        args = {
            self.workspace.args_key: self.workspace.value(),
            self.suffix.args_key: self.suffix.value(),
            self.lulc_lookup_uri.args_key: self.lulc_lookup_uri.value(),
            self.lulc_transition_matrix_uri.args_key:
                self.lulc_transition_matrix_uri.value(),
            self.carbon_pool_initial_uri.args_key:
                self.carbon_pool_initial_uri.value(),
            self.carbon_pool_transient_uri.args_key:
                self.carbon_pool_transient_uri.value(),
            self.lulc_baseline_map_uri.args_key:
                self.lulc_baseline_map_uri.value(),
            self.lulc_baseline_year.args_key:
                self.lulc_baseline_year.value(),
            self.lulc_transition_maps_list.args_key:
                self.lulc_transition_maps_list.value(),
            self.lulc_transition_years_list.args_key:
                self.lulc_transition_years_list.value(),
            self.analysis_year.args_key: self.analysis_year.value(),
            self.do_economic_analysis.args_key:
                self.do_economic_analysis.value(),
        }

        if self.do_economic_analysis.value():
            args[self.price.args_key] = self.price.value()
            args[self.interest_rate.args_key] = self.interest_rate.value()
            args[self.discount_rate.args_key] = self.discount_rate.value()

            args[self.do_price_table.args_key] = self.do_price_table.value()
            if self.do_price_table.value() == True:
                args[self.price_table_uri.args_key] = self.price_table_uri.value()

        return args
