# -*- 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 Farm Animals
"""

import datetime

import colander

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

from wuttafarm.web.views.farmos import FarmOSMasterView
from wuttafarm.web.forms.schema import UsersType, AnimalTypeType, StructureType
from wuttafarm.web.forms.widgets import ImageWidget


class AnimalView(FarmOSMasterView):
    """
    Master view for Farm Animals
    """

    model_name = "farmos_animal"
    model_title = "farmOS Animal"
    model_title_plural = "farmOS Animals"

    route_prefix = "farmos_animals"
    url_prefix = "/farmOS/animals"

    farmos_refurl_path = "/assets/animal"

    labels = {
        "animal_type": "Species / Breed",
        "location": "Current Location",
    }

    grid_columns = [
        "name",
        "birthdate",
        "sex",
        "is_sterile",
        "archived",
    ]

    sort_defaults = "name"

    form_fields = [
        "name",
        "animal_type",
        "birthdate",
        "sex",
        "is_sterile",
        "archived",
        "owners",
        "location",
        "notes",
        "raw_image_url",
        "large_image_url",
        "thumbnail_image_url",
        "image",
    ]

    def get_grid_data(self, columns=None, session=None):
        animals = self.farmos_client.resource.get("asset", "animal")
        return [self.normalize_animal(a) for a in animals["data"]]

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

        # name
        g.set_link("name")
        g.set_searchable("name")

        # birthdate
        g.set_renderer("birthdate", "date")

        # is_sterile
        g.set_renderer("is_sterile", "boolean")

        # archived
        g.set_renderer("archived", "boolean")

    def get_instance(self):

        animal = self.farmos_client.resource.get_id(
            "asset", "animal", self.request.matchdict["uuid"]
        )
        self.raw_json = animal

        # instance data
        data = self.normalize_animal(animal["data"])

        if relationships := animal["data"].get("relationships"):

            # add animal type
            if animal_type := relationships.get("animal_type"):
                if animal_type["data"]:
                    animal_type = self.farmos_client.resource.get_id(
                        "taxonomy_term", "animal_type", animal_type["data"]["id"]
                    )
                    data["animal_type"] = {
                        "uuid": animal_type["data"]["id"],
                        "name": animal_type["data"]["attributes"]["name"],
                    }

            # add location
            if location := relationships.get("location"):
                if location["data"]:
                    location = self.farmos_client.resource.get_id(
                        "asset", "structure", location["data"][0]["id"]
                    )
                    data["location"] = {
                        "uuid": location["data"]["id"],
                        "name": location["data"]["attributes"]["name"],
                    }

            # add owners
            if owner := relationships.get("owner"):
                data["owners"] = []
                for owner_data in owner["data"]:
                    owner = self.farmos_client.resource.get_id(
                        "user", "user", owner_data["id"]
                    )
                    data["owners"].append(
                        {
                            "uuid": owner["data"]["id"],
                            "display_name": owner["data"]["attributes"]["display_name"],
                        }
                    )

            # add image urls
            if image := relationships.get("image"):
                if image["data"]:
                    image = self.farmos_client.resource.get_id(
                        "file", "file", image["data"][0]["id"]
                    )
                    data["raw_image_url"] = self.app.get_farmos_url(
                        image["data"]["attributes"]["uri"]["url"]
                    )
                    # nb. other styles available:  medium, wide
                    data["large_image_url"] = image["data"]["attributes"][
                        "image_style_uri"
                    ]["large"]
                    data["thumbnail_image_url"] = image["data"]["attributes"][
                        "image_style_uri"
                    ]["thumbnail"]

        return data

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

    def normalize_animal(self, animal):

        birthdate = animal["attributes"]["birthdate"]
        if birthdate:
            birthdate = datetime.datetime.fromisoformat(birthdate)
            birthdate = self.app.localtime(birthdate)

        sterile = None
        if self.farmos_4x:
            sterile = animal["attributes"]["is_sterile"]
        else:
            sterile = animal["attributes"]["is_castrated"]

        if notes := animal["attributes"]["notes"]:
            notes = notes["value"]

        if self.farmos_4x:
            archived = animal["attributes"]["archived"]
        else:
            archived = animal["attributes"]["status"] == "archived"

        return {
            "uuid": animal["id"],
            "drupal_id": animal["attributes"]["drupal_internal__id"],
            "name": animal["attributes"]["name"],
            "birthdate": birthdate,
            "sex": animal["attributes"]["sex"] or colander.null,
            "is_sterile": sterile,
            "location": colander.null,  # TODO
            "archived": archived,
            "notes": notes or colander.null,
        }

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

        # animal_type
        f.set_node("animal_type", AnimalTypeType(self.request))

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

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

        # location
        f.set_node("location", StructureType(self.request))

        # owners
        f.set_node("owners", UsersType(self.request))

        # notes
        f.set_widget("notes", "notes")

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

        # image
        if url := animal.get("large_image_url"):
            f.set_widget("image", ImageWidget("animal image"))
            f.set_default("image", url)

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

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

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

        return buttons


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

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


def includeme(config):
    defaults(config)
