# -*- 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/>.
#
################################################################################
"""
Model definition for Plant Assets
"""

import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.associationproxy import association_proxy

from wuttjamaican.db import model

from wuttafarm.db.model.asset import AssetMixin, add_asset_proxies


class PlantType(model.Base):
    """
    Represents a "plant type" (taxonomy term) from farmOS
    """

    __tablename__ = "plant_type"
    __versioned__ = {}
    __wutta_hint__ = {
        "model_title": "Plant Type",
        "model_title_plural": "Plant Types",
    }

    uuid = model.uuid_column()

    name = sa.Column(
        sa.String(length=100),
        nullable=False,
        unique=True,
        doc="""
        Name of the plant type.
        """,
    )

    description = sa.Column(
        sa.String(length=255),
        nullable=True,
        doc="""
        Optional description for the plant type.
        """,
    )

    farmos_uuid = sa.Column(
        model.UUID(),
        nullable=True,
        unique=True,
        doc="""
        UUID for the plant type within farmOS.
        """,
    )

    drupal_id = sa.Column(
        sa.Integer(),
        nullable=True,
        unique=True,
        doc="""
        Drupal internal ID for the plant type.
        """,
    )

    _plant_assets = orm.relationship(
        "PlantAssetPlantType",
        cascade_backrefs=False,
        back_populates="plant_type",
    )

    def __str__(self):
        return self.name or ""


class Season(model.Base):
    """
    Represents a "season" (taxonomy term) from farmOS
    """

    __tablename__ = "season"
    __versioned__ = {}
    __wutta_hint__ = {
        "model_title": "Season",
        "model_title_plural": "Seasons",
    }

    uuid = model.uuid_column()

    name = sa.Column(
        sa.String(length=100),
        nullable=False,
        unique=True,
        doc="""
        Name of the season.
        """,
    )

    description = sa.Column(
        sa.String(length=255),
        nullable=True,
        doc="""
        Optional description for the season.
        """,
    )

    farmos_uuid = sa.Column(
        model.UUID(),
        nullable=True,
        unique=True,
        doc="""
        UUID for the season within farmOS.
        """,
    )

    drupal_id = sa.Column(
        sa.Integer(),
        nullable=True,
        unique=True,
        doc="""
        Drupal internal ID for the season.
        """,
    )

    _plant_assets = orm.relationship(
        "PlantAssetSeason",
        cascade_backrefs=False,
        back_populates="season",
    )

    def __str__(self):
        return self.name or ""


class PlantAsset(AssetMixin, model.Base):
    """
    Represents a plant asset from farmOS
    """

    __tablename__ = "asset_plant"
    __versioned__ = {}
    __wutta_hint__ = {
        "model_title": "Plant Asset",
        "model_title_plural": "Plant Assets",
        "farmos_asset_type": "plant",
    }

    _plant_types = orm.relationship(
        "PlantAssetPlantType",
        cascade="all, delete-orphan",
        cascade_backrefs=False,
        back_populates="plant_asset",
    )

    plant_types = association_proxy(
        "_plant_types",
        "plant_type",
        creator=lambda pt: PlantAssetPlantType(plant_type=pt),
    )

    _seasons = orm.relationship(
        "PlantAssetSeason",
        cascade="all, delete-orphan",
        cascade_backrefs=False,
        back_populates="plant_asset",
    )

    seasons = association_proxy(
        "_seasons",
        "season",
        creator=lambda s: PlantAssetSeason(season=s),
    )


add_asset_proxies(PlantAsset)


class PlantAssetPlantType(model.Base):
    """
    Associates one or more plant types with a plant asset.
    """

    __tablename__ = "asset_plant_plant_type"
    __versioned__ = {}

    uuid = model.uuid_column()

    plant_asset_uuid = model.uuid_fk_column("asset_plant.uuid", nullable=False)
    plant_asset = orm.relationship(
        PlantAsset,
        foreign_keys=plant_asset_uuid,
        back_populates="_plant_types",
    )

    plant_type_uuid = model.uuid_fk_column("plant_type.uuid", nullable=False)
    plant_type = orm.relationship(
        PlantType,
        doc="""
        Reference to the plant type.
        """,
        back_populates="_plant_assets",
    )


class PlantAssetSeason(model.Base):
    """
    Associates one or more seasons with a plant asset.
    """

    __tablename__ = "asset_plant_season"
    __versioned__ = {}

    uuid = model.uuid_column()

    plant_asset_uuid = model.uuid_fk_column("asset_plant.uuid", nullable=False)
    plant_asset = orm.relationship(
        PlantAsset,
        foreign_keys=plant_asset_uuid,
        back_populates="_seasons",
    )

    season_uuid = model.uuid_fk_column("season.uuid", nullable=False)
    season = orm.relationship(
        Season,
        doc="""
        Reference to the season.
        """,
        back_populates="_plant_assets",
    )
