# -*- coding: utf-8; -*-
################################################################################
#
#  WuttaFarm --Web app to integrate with and extend farmOS
#  Copyright © 2026 Lance Edgar
#
#  This file is part of WuttaFarm.
#
#  WuttaFarm is free software: you can redistribute it and/or modify it under
#  the terms of the GNU General Public License as published by the Free Software
#  Foundation, either version 3 of the License, or (at your option) any later
#  version.
#
#  WuttaFarm is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along with
#  WuttaFarm.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Master view for Quantities
"""

from collections import OrderedDict

from wuttaweb.db import Session

from wuttafarm.web.views import WuttaFarmMasterView
from wuttafarm.db.model import QuantityType, Quantity, StandardQuantity
from wuttafarm.web.forms.schema import UnitRef


def get_quantity_type_enum(config):
    app = config.get_app()
    model = app.model
    session = Session()
    quantity_types = OrderedDict()
    query = session.query(model.QuantityType).order_by(model.QuantityType.name)
    for quantity_type in query:
        quantity_types[quantity_type.drupal_id] = quantity_type.name
    return quantity_types


class QuantityTypeView(WuttaFarmMasterView):
    """
    Master view for Quantity Types
    """

    model_class = QuantityType
    route_prefix = "quantity_types"
    url_prefix = "/quantity-types"

    grid_columns = [
        "name",
        "description",
    ]

    sort_defaults = "name"

    filter_defaults = {
        "name": {"active": True, "verb": "contains"},
    }

    form_fields = [
        "name",
        "description",
        "farmos_uuid",
        "drupal_id",
    ]

    def configure_grid(self, grid):
        g = grid
        super().configure_grid(g)

        # name
        g.set_link("name")

    def get_xref_buttons(self, quantity_type):
        buttons = super().get_xref_buttons(quantity_type)

        if quantity_type.farmos_uuid:
            buttons.append(
                self.make_button(
                    "View farmOS record",
                    primary=True,
                    url=self.request.route_url(
                        "farmos_quantity_types.view", uuid=quantity_type.farmos_uuid
                    ),
                    icon_left="eye",
                )
            )

        return buttons


class QuantityMasterView(WuttaFarmMasterView):
    """
    Base class for Quantity master views
    """

    grid_columns = [
        "drupal_id",
        "as_text",
        "quantity_type",
        "measure",
        "value",
        "units",
        "label",
    ]

    sort_defaults = ("drupal_id", "desc")

    form_fields = [
        "quantity_type",
        "as_text",
        "measure",
        "value",
        "units",
        "label",
        "farmos_uuid",
        "drupal_id",
    ]

    def get_query(self, session=None):
        """ """
        model = self.app.model
        model_class = self.get_model_class()
        session = session or self.Session()
        query = session.query(model_class)
        if model_class is not model.Quantity:
            query = query.join(model.Quantity)
        query = query.join(model.Measure).join(model.Unit)
        return query

    def configure_grid(self, grid):
        g = grid
        super().configure_grid(g)
        model = self.app.model
        model_class = self.get_model_class()

        # drupal_id
        g.set_label("drupal_id", "ID", column_only=True)
        g.set_sorter("drupal_id", model.Quantity.drupal_id)

        # as_text
        g.set_renderer("as_text", self.render_as_text_for_grid)
        g.set_link("as_text")

        # quantity_type
        if model_class is not model.Quantity:
            g.remove("quantity_type")
        else:
            g.set_enum("quantity_type", get_quantity_type_enum(self.config))

        # measure
        g.set_sorter("measure", model.Measure.name)

        # value
        g.set_renderer("value", self.render_value_for_grid)

        # units
        g.set_sorter("units", model.Unit.name)

        # label
        g.set_sorter("label", model.Quantity.label)

        # view action links to final quantity record
        if model_class is model.Quantity:

            def quantity_url(quantity, i):
                return self.request.route_url(
                    f"quantities_{quantity.quantity_type_id}.view", uuid=quantity.uuid
                )

            g.add_action("view", icon="eye", url=quantity_url)

    def render_as_text_for_grid(self, quantity, field, value):
        return quantity.render_as_text(self.config)

    def render_value_for_grid(self, quantity, field, value):
        value = quantity.value_numerator / quantity.value_denominator
        return self.app.render_quantity(value)

    def get_instance_title(self, quantity):
        return quantity.render_as_text(self.config)

    def configure_form(self, form):
        f = form
        super().configure_form(f)
        quantity = form.model_instance

        # as_text
        if self.creating or self.editing:
            f.remove("as_text")
        else:
            f.set_default("as_text", quantity.render_as_text(self.config))

        # quantity_type
        if self.creating:
            f.remove("quantity_type")
        else:
            f.set_readonly("quantity_type")
            f.set_default("quantity_type", quantity.quantity_type.name)

        # measure
        if self.creating:
            f.remove("measure")
        else:
            f.set_readonly("measure")
            f.set_default("measure", quantity.measure.name)

        # value
        if self.creating:
            f.remove("value")
        else:
            value = quantity.value_numerator / quantity.value_denominator
            value = self.app.render_quantity(value)
            f.set_default(
                "value",
                f"{value} ({quantity.value_numerator} / {quantity.value_denominator})",
            )

        # units
        if self.creating:
            f.remove("units")
        else:
            f.set_readonly("units")
            f.set_node("units", UnitRef(self.request))
            # TODO: ugh
            f.set_default("units", quantity.quantity.units)

    def get_xref_buttons(self, quantity):
        buttons = super().get_xref_buttons(quantity)

        if quantity.farmos_uuid:
            url = self.request.route_url(
                f"farmos_quantities_{quantity.quantity_type_id}.view",
                uuid=quantity.farmos_uuid,
            )
            buttons.append(
                self.make_button(
                    "View farmOS record", primary=True, url=url, icon_left="eye"
                )
            )

        return buttons


class QuantityView(QuantityMasterView):
    """
    Master view for All Quantities
    """

    model_class = Quantity
    route_prefix = "quantities"
    url_prefix = "/quantities"

    viewable = False
    creatable = False
    editable = False
    deletable = False
    model_is_versioned = False


class StandardQuantityView(QuantityMasterView):
    """
    Master view for Standard Quantities
    """

    model_class = StandardQuantity
    route_prefix = "quantities_standard"
    url_prefix = "/quantities/standard"


def defaults(config, **kwargs):
    base = globals()

    QuantityTypeView = kwargs.get("QuantityTypeView", base["QuantityTypeView"])
    QuantityTypeView.defaults(config)

    QuantityView = kwargs.get("QuantityView", base["QuantityView"])
    QuantityView.defaults(config)

    StandardQuantityView = kwargs.get(
        "StandardQuantityView", base["StandardQuantityView"]
    )
    StandardQuantityView.defaults(config)


def includeme(config):
    defaults(config)
