# plugins/exchange/models.py

from datetime import datetime
from sqlalchemy import (
    Column, Integer, ForeignKey, Enum,
    DateTime, Numeric, Text, String, JSON, Boolean
)
from app.extensions import db  # adjust to your project’s extension import path

class Listing(db.Model):
    __tablename__ = 'exchange_listing'

    id               = Column(Integer, primary_key=True)
    plant_id         = Column(Integer, ForeignKey('plants.id'), nullable=False)

    # ownership actors (exactly one should be non-null)
    owner_user_id    = Column(Integer, ForeignKey('users.id'), nullable=True)
    owner_vendor_id  = Column(Integer, ForeignKey('vendor_vendor.id'), nullable=True)
    owner_group_id   = Column(Integer, ForeignKey('groups_group.id'), nullable=True)

    # listing types
    type             = Column(
        Enum(
            'sale','trade','auction','loan','donation',
            'request','consignment','swap',
            name='listing_type'
        ),
        nullable=False,
        default='sale'
    )

    # sale/trade core fields
    bin_price        = Column(Numeric, nullable=True)    # “Buy It Now” price
    allow_offers     = Column(Boolean, default=True)     # allow buyer offers

    # auction-specific
    auction_start    = Column(Numeric, nullable=True)    # e.g. 0.99
    auction_reserve  = Column(Numeric, nullable=True)    # e.g. 50.00
    auction_ends_at  = Column(DateTime, nullable=True)

    # trade-specific
    trade_items      = Column(JSON, nullable=True)       # list of {plant_id, qty, notes}

    # loan-specific
    loan_return_date = Column(DateTime, nullable=True)
    rental_rate      = Column(Numeric, nullable=True)

    # consignment-specific
    consignment_split= Column(Numeric, nullable=True)    # fraction taken as fee (e.g. 0.10)

    # swap/batch
    swap_batch_id    = Column(Integer, ForeignKey('exchange_swapbatch.id'),
                              nullable=True)

    status           = Column(
        Enum('active','inactive', name='listing_status'),
        default='active'
    )
    created_at       = Column(DateTime, default=datetime.utcnow)


class SwapBatch(db.Model):
    __tablename__ = 'exchange_swapbatch'

    id          = Column(Integer, primary_key=True)
    name        = Column(String(128), nullable=False)
    description = Column(Text, nullable=True)
    date        = Column(DateTime, nullable=False)
    created_at  = Column(DateTime, default=datetime.utcnow)


class Offer(db.Model):
    __tablename__ = 'exchange_offer'

    id              = Column(Integer, primary_key=True)
    listing_id      = Column(Integer, ForeignKey('exchange_listing.id'),
                              nullable=False)

    # actor making the offer
    offerer_user_id   = Column(Integer, ForeignKey('users.id'), nullable=True)
    offerer_vendor_id = Column(Integer, ForeignKey('vendor_vendor.id'),
                               nullable=True)
    offerer_group_id  = Column(Integer, ForeignKey('groups_group.id'),
                               nullable=True)

    amount          = Column(Numeric, nullable=False)
    notes           = Column(Text, nullable=True)
    status          = Column(
        Enum('pending','accepted','rejected', name='offer_status'),
        default='pending'
    )
    created_at      = Column(DateTime, default=datetime.utcnow)
    responded_at    = Column(DateTime, nullable=True)


class Ownership(db.Model):
    __tablename__ = 'exchange_ownership'

    id              = Column(Integer, primary_key=True)
    listing_id      = Column(Integer, ForeignKey('exchange_listing.id'),
                              nullable=False)

    # snapshot actor
    owner_user_id    = Column(Integer, ForeignKey('users.id'), nullable=True)
    owner_vendor_id  = Column(Integer, ForeignKey('vendor_vendor.id'),
                              nullable=True)
    owner_group_id   = Column(Integer, ForeignKey('groups_group.id'),
                              nullable=True)

    acquired_on     = Column(DateTime, nullable=False)
    price_paid      = Column(Numeric, nullable=False)
    source_notes    = Column(Text, nullable=True)


class OwnershipTransfer(db.Model):
    __tablename__ = 'exchange_ownership_transfer'

    id              = Column(Integer, primary_key=True)
    listing_id      = Column(Integer, ForeignKey('exchange_listing.id'),
                              nullable=False)

    # from actor
    from_user_id    = Column(Integer, ForeignKey('users.id'), nullable=True)
    from_vendor_id  = Column(Integer, ForeignKey('vendor_vendor.id'),
                              nullable=True)
    from_group_id   = Column(Integer, ForeignKey('groups_group.id'),
                              nullable=True)

    # to actor
    to_user_id      = Column(Integer, ForeignKey('users.id'), nullable=True)
    to_vendor_id    = Column(Integer, ForeignKey('vendor_vendor.id'),
                              nullable=True)
    to_group_id     = Column(Integer, ForeignKey('groups_group.id'),
                              nullable=True)

    status          = Column(
        Enum('pending','approved','rejected','returned', name='transfer_status'),
        default='pending'
    )
    requested_at    = Column(DateTime, default=datetime.utcnow)
    decided_at      = Column(DateTime, nullable=True)


class PriceSubmission(db.Model):
    __tablename__ = 'exchange_price_submission'

    id                  = Column(Integer, primary_key=True)
    taxon_id            = Column(Integer, ForeignKey('botanica_taxon.id'),
                                 nullable=False)
    listing_id          = Column(Integer, ForeignKey('exchange_listing.id'),
                                 nullable=True)

    submitter_user_id   = Column(Integer, ForeignKey('users.id'),
                                 nullable=False)
    source_platform     = Column(String(64), nullable=False)
    source_vendor_name  = Column(String(128), nullable=True)
    original_price      = Column(Numeric, nullable=True)
    paid_price          = Column(Numeric, nullable=False)
    shipping_price      = Column(Numeric, nullable=True)
    tax_amount          = Column(Numeric, nullable=True)
    notes               = Column(Text, nullable=True)
    submitted_at        = Column(DateTime, default=datetime.utcnow)


class UserRating(db.Model):
    __tablename__ = 'exchange_user_rating'

    id                 = Column(Integer, primary_key=True)
    rater_id           = Column(Integer, ForeignKey('users.id'),
                                 nullable=False)
    target_user_id     = Column(Integer, ForeignKey('users.id'),
                                 nullable=False)
    score              = Column(Integer, nullable=False)
    notes              = Column(Text, nullable=True)
    rated_at           = Column(DateTime, default=datetime.utcnow)
