# -*- 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/>.
#
################################################################################
"""
View for farmOS Harvest Logs
"""

import colander
from webhelpers2.html import tags

from wuttaweb.forms.schema import WuttaDateTime, WuttaDictEnum
from wuttaweb.forms.widgets import WuttaDateTimeWidget

from wuttafarm.web.views.farmos import FarmOSMasterView
from wuttafarm.web.grids import (
    ResourceData,
    SimpleSorter,
    StringFilter,
    IntegerFilter,
    DateTimeFilter,
    NullableBooleanFilter,
)
from wuttafarm.web.forms.schema import (
    FarmOSQuantityRefs,
    FarmOSAssetRefs,
    FarmOSRefs,
    LogQuick,
    Notes,
)
from wuttafarm.web.util import render_quantity_objects, render_quantity_object


class LogMasterView(FarmOSMasterView):
    """
    Base class for farmOS Log master views
    """

    farmos_log_type = None
    filterable = True
    sort_on_backend = True

    labels = {
        "name": "Log Name",
        "log_type_name": "Log Type",
        "locations": "Location",
        "quantities": "Quantity",
    }

    grid_columns = [
        "status",
        "drupal_id",
        "timestamp",
        "name",
        "assets",
        "locations",
        "quantities",
        "is_group_assignment",
        "owners",
    ]

    sort_defaults = ("timestamp", "desc")

    filter_defaults = {
        "name": {"active": True, "verb": "contains"},
        "status": {"active": True, "verb": "not_equal", "value": "abandoned"},
    }

    form_fields = [
        "name",
        "timestamp",
        "assets",
        "groups",
        "locations",
        "quantities",
        "notes",
        "status",
        "log_type_name",
        "owners",
        "is_movement",
        "is_group_assignment",
        "quick",
        "drupal_id",
    ]

    def get_farmos_api_includes(self):
        return {"log_type", "quantity", "asset", "group", "location", "owner"}

    def get_grid_data(self, **kwargs):
        return ResourceData(
            self.config,
            self.farmos_client,
            f"log--{self.farmos_log_type}",
            include=",".join(self.get_farmos_api_includes()),
            normalizer=self.normalize_log,
        )

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

        # status
        g.set_enum("status", enum.LOG_STATUS)
        g.set_sorter("status", SimpleSorter("status"))
        g.set_filter(
            "status",
            StringFilter,
            choices=enum.LOG_STATUS,
            verbs=["equal", "not_equal"],
        )

        # drupal_id
        g.set_label("drupal_id", "ID", column_only=True)
        g.set_sorter("drupal_id", SimpleSorter("drupal_internal__id"))
        g.set_filter("drupal_id", IntegerFilter, path="drupal_internal__id")

        # timestamp
        g.set_renderer("timestamp", "date")
        g.set_link("timestamp")
        g.set_sorter("timestamp", SimpleSorter("timestamp"))
        g.set_filter("timestamp", DateTimeFilter)

        # name
        g.set_link("name")
        g.set_sorter("name", SimpleSorter("name"))
        g.set_filter("name", StringFilter)

        # assets
        g.set_renderer("assets", self.render_assets_for_grid)

        # groups
        g.set_renderer("groups", self.render_assets_for_grid)

        # locations
        g.set_renderer("locations", self.render_assets_for_grid)

        # quantities
        g.set_renderer("quantities", self.render_quantities_for_grid)

        # is_group_assignment
        g.set_renderer("is_group_assignment", "boolean")
        g.set_sorter("is_group_assignment", SimpleSorter("is_group_assignment"))
        g.set_filter("is_group_assignment", NullableBooleanFilter)

        # owners
        g.set_label("owners", "Owner")
        g.set_renderer("owners", self.render_owners_for_grid)

    def render_assets_for_grid(self, log, field, value):
        if not value:
            return ""

        assets = []
        for asset in value:
            if self.farmos_style_grid_links:
                url = self.request.route_url(
                    f"farmos_{asset['asset_type']}_assets.view", uuid=asset["uuid"]
                )
                assets.append(tags.link_to(asset["name"], url))
            else:
                assets.append(asset["name"])
        return ", ".join(assets)

    def render_quantities_for_grid(self, log, field, value):
        if not value:
            return None
        return render_quantity_objects(value)

    def grid_row_class(self, log, data, i):
        if log["status"] == "pending":
            return "has-background-warning"
        if log["status"] == "abandoned":
            return "has-background-danger"
        return None

    def get_instance(self):
        result = self.farmos_client.log.get_id(
            self.farmos_log_type,
            self.request.matchdict["uuid"],
            params={"include": ",".join(self.get_farmos_api_includes())},
        )
        self.raw_json = result
        included = {obj["id"]: obj for obj in result.get("included", [])}
        instance = self.normalize_log(result["data"], included)

        for qty in instance["quantities"]:

            if qty["quantity_type_id"] == "material":
                for mtype in qty["material_types"]:
                    result = self.farmos_client.resource.get_id(
                        "taxonomy_term", "material_type", mtype["uuid"]
                    )
                    mtype["name"] = result["data"]["attributes"]["name"]

            qty["as_text"] = render_quantity_object(qty)

        return instance

    def get_instance_title(self, log):
        return log["name"]

    def normalize_log(self, log, included):
        data = self.normal.normalize_farmos_log(log, included)
        data.update(
            {
                "log_type_name": data["log_type"].get("name"),
            }
        )
        return data

    def configure_form(self, form):
        f = form
        super().configure_form(f)
        enum = self.app.enum
        log = f.model_instance

        # timestamp
        f.set_node("timestamp", WuttaDateTime())
        f.set_widget("timestamp", WuttaDateTimeWidget(self.request))

        # assets
        f.set_node("assets", FarmOSAssetRefs(self.request))

        # groups
        f.set_node("groups", FarmOSAssetRefs(self.request))

        # locations
        f.set_node("locations", FarmOSAssetRefs(self.request))

        # quantities
        f.set_node("quantities", FarmOSQuantityRefs(self.request))

        # is_movement
        f.set_node("is_movement", colander.Boolean())

        # is_group_assignment
        f.set_node("is_group_assignment", colander.Boolean())

        # notes
        f.set_node("notes", Notes())

        # status
        f.set_node("status", WuttaDictEnum(self.request, enum.LOG_STATUS))

        # owners
        if self.creating or self.editing:
            f.remove("owners")  # TODO
        else:
            f.set_node("owners", FarmOSRefs(self.request, "farmos_users"))

        # quick
        f.set_node("quick", LogQuick(self.request))

    def get_xref_buttons(self, log):
        model = self.app.model
        session = self.Session()

        buttons = [
            self.make_button(
                "View in farmOS",
                primary=True,
                url=self.app.get_farmos_url(f"/log/{log['drupal_id']}"),
                target="_blank",
                icon_left="external-link-alt",
            ),
        ]

        if wf_log := (
            session.query(model.Log)
            .filter(model.Log.farmos_uuid == log["uuid"])
            .first()
        ):
            buttons.append(
                self.make_button(
                    f"View {self.app.get_title()} record",
                    primary=True,
                    url=self.request.route_url(
                        f"logs_{self.farmos_log_type}.view", uuid=wf_log.uuid
                    ),
                    icon_left="eye",
                )
            )

        return buttons
