# -*- 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/>.
#
################################################################################
"""
Base class for farmOS master views
"""

import datetime
import json

import colander
import markdown
from webhelpers2.html import tags

from wuttaweb.views import MasterView
from wuttaweb.forms.schema import WuttaDateTime
from wuttaweb.forms.widgets import WuttaDateTimeWidget

from wuttafarm.web.util import get_farmos_client_for_user, use_farmos_style_grid_links
from wuttafarm.web.grids import (
    ResourceData,
    StringFilter,
    NullableStringFilter,
    DateTimeFilter,
    SimpleSorter,
)


class FarmOSMasterView(MasterView):
    """
    Base class for farmOS master views
    """

    model_key = "uuid"

    creatable = False
    editable = False
    deletable = False

    filterable = False
    sort_on_backend = False
    paginate_on_backend = False

    farmos_refurl_path = None

    labels = {
        "drupal_id": "Drupal ID",
        "raw_image_url": "Raw Image URL",
        "large_image_url": "Large Image URL",
        "thumbnail_image_url": "Thumbnail Image URL",
    }

    def __init__(self, request, context=None):
        super().__init__(request, context=context)
        self.farmos_client = get_farmos_client_for_user(self.request)
        self.farmos_4x = self.app.is_farmos_4x(self.farmos_client)
        self.normal = self.app.get_normalizer(self.farmos_client)
        self.raw_json = None
        self.farmos_style_grid_links = use_farmos_style_grid_links(self.config)

    def get_fallback_templates(self, template):
        """ """
        templates = super().get_fallback_templates(template)

        if template == "view":
            templates.insert(0, "/farmos/master/view.mako")

        return templates

    def render_owners_for_grid(self, obj, field, value):
        owners = []
        for user in value:
            if self.farmos_style_grid_links:
                url = self.request.route_url("farmos_users.view", uuid=user["uuid"])
                owners.append(tags.link_to(user["name"], url))
            else:
                owners.append(user["name"])
        return ", ".join(owners)

    def get_template_context(self, context):

        if self.listing and self.farmos_refurl_path:
            context["farmos_refurl"] = self.app.get_farmos_url(self.farmos_refurl_path)

        if self.viewing and self.raw_json:
            context["raw_json"] = self.raw_json
            code = "```json\n" + json.dumps(self.raw_json, indent=2) + "\n```"
            # TODO: this does not seem to be adding syntax highlight
            context["rendered_json"] = markdown.markdown(
                code, extensions=["fenced_code", "codehilite"]
            )

        return context


class TaxonomyMasterView(FarmOSMasterView):
    """
    Base class for farmOS "taxonomy term" views
    """

    farmos_taxonomy_type = None
    creatable = True
    editable = True
    deletable = True
    filterable = True
    sort_on_backend = True

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

    sort_defaults = "name"

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

    form_fields = [
        "name",
        "description",
        "changed",
    ]

    def get_grid_data(self, columns=None, session=None):
        return ResourceData(
            self.config,
            self.farmos_client,
            f"taxonomy_term--{self.farmos_taxonomy_type}",
            normalizer=self.normalize_taxonomy_term,
        )

    def normalize_taxonomy_term(self, term, included):

        if changed := term["attributes"]["changed"]:
            changed = datetime.datetime.fromisoformat(changed)
            changed = self.app.localtime(changed)

        if description := term["attributes"]["description"]:
            description = description["value"]

        return {
            "uuid": term["id"],
            "drupal_id": term["attributes"]["drupal_internal__tid"],
            "name": term["attributes"]["name"],
            "description": description or colander.null,
            "changed": changed,
        }

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

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

        # description
        g.set_sorter("description", SimpleSorter("description.value"))
        g.set_filter("description", NullableStringFilter, path="description.value")

        # changed
        g.set_renderer("changed", "datetime")
        g.set_sorter("changed", SimpleSorter("changed"))
        g.set_filter("changed", DateTimeFilter)

    def get_instance(self):
        result = self.farmos_client.resource.get_id(
            "taxonomy_term", self.farmos_taxonomy_type, self.request.matchdict["uuid"]
        )
        self.raw_json = result
        return self.normalize_taxonomy_term(result["data"], {})

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

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

        # description
        f.set_widget("description", "notes")
        f.set_required("description", False)

        # changed
        if self.creating or self.editing:
            f.remove("changed")
        else:
            f.set_node("changed", WuttaDateTime())
            f.set_widget("changed", WuttaDateTimeWidget(self.request))

    def get_api_payload(self, term):

        attrs = {
            "name": term["name"],
        }

        if description := term["description"]:
            attrs["description"] = {"value": description}
        else:
            attrs["description"] = None

        return {"attributes": attrs}

    def persist(self, term, session=None):
        payload = self.get_api_payload(term)
        if self.editing:
            payload["id"] = term["uuid"]

        result = self.farmos_client.resource.send(
            "taxonomy_term", self.farmos_taxonomy_type, payload
        )

        if self.creating:
            term["uuid"] = result["data"]["id"]

    def delete_instance(self, term):
        self.farmos_client.resource.delete(
            "taxonomy_term", self.farmos_taxonomy_type, term["uuid"]
        )

    def get_xref_buttons(self, term):
        return [
            self.make_button(
                "View in farmOS",
                primary=True,
                url=self.app.get_farmos_url(f"/taxonomy/term/{term['drupal_id']}"),
                target="_blank",
                icon_left="external-link-alt",
            )
        ]
