import datetime

from sqlalchemy import Column, String, Integer, Float, Date, DateTime, Boolean, ForeignKey, JSON
from sqlalchemy.orm import relationship, DeclarativeBase, Mapped, mapped_column
from sqlalchemy.sql import func


class Base(DeclarativeBase):
    pass

class TrayWebhook(Base):
    __tablename__ = 'tray_webhook'
    id = Column(Integer, primary_key=True, autoincrement=True)
    #create_date: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())
    body = Column(String(255))

    
    def __init__(self, body):
        self.body = body



class ApiToken(Base):
    __tablename__ = 'api_token'

    id = Column(Integer, primary_key=True, autoincrement=True)
    message = Column(String(255))
    code = Column(Integer)
    access_token = Column(String(255))
    refresh_token = Column(String(255))
    date_expiration_access_token = Column(DateTime)
    date_expiration_refresh_token = Column(DateTime)
    date_activated = Column(DateTime)
    api_host = Column(String(255))
    store_id = Column(String(255))

    def __init__(self, message, code, access_token, refresh_token, date_expiration_access_token,
                 date_expiration_refresh_token, date_activated, api_host, store_id):
        self.message = message
        self.code = code
        self.access_token = access_token
        self.refresh_token = refresh_token
        self.date_expiration_access_token = datetime.datetime.strptime(date_expiration_access_token,
                                                                       "%Y-%m-%d %H:%M:%S")
        self.date_expiration_refresh_token = datetime.datetime.strptime(date_expiration_refresh_token,
                                                                        "%Y-%m-%d %H:%M:%S")
        self.date_activated = datetime.datetime.strptime(date_activated, "%Y-%m-%d %H:%M:%S")
        self.api_host = api_host
        self.store_id = store_id


class Order(Base):
    __tablename__ = 'order'

    id: Mapped[int] = mapped_column(primary_key=True)
    status: Mapped[str] = mapped_column(String(255))
    date: Mapped[datetime] = mapped_column(Date)
    customer_id: Mapped[int] = mapped_column(Integer)
    partial_total: Mapped[float] = mapped_column(Float)
    taxes: Mapped[float] = mapped_column(Float)
    discount: Mapped[float] = mapped_column(Float)
    point_sale: Mapped[str] = mapped_column(String(100))
    shipment: Mapped[str] = mapped_column(String)
    shipment_value: Mapped[float] = mapped_column(Float)
    shipment_date: Mapped[datetime] = mapped_column(Date, nullable=True)
    store_note: Mapped[str] = mapped_column(String)
    discount_coupon: Mapped[str] = mapped_column(String(255))
    payment_method_rate: Mapped[float] = mapped_column(Float)
    value_1: Mapped[float] = mapped_column(Float)
    payment_form: Mapped[str] = mapped_column(String(255))
    sending_code: Mapped[str] = mapped_column(String(255))
    session_id: Mapped[str] = mapped_column(String(255))
    total: Mapped[float] = mapped_column(Float)
    payment_date: Mapped[datetime] = mapped_column(Date, nullable=True)
    access_code: Mapped[str] = mapped_column(String(255), nullable=True)
    progressive_discount: Mapped[float] = mapped_column(Float, nullable=True)
    shipping_progressive_discount: Mapped[float] = mapped_column(Float, nullable=True)
    shipment_integrator: Mapped[str] = mapped_column(String(255))
    modified: Mapped[datetime] = mapped_column(DateTime)
    printed: Mapped[bool] = mapped_column(Boolean, default=False)
    interest: Mapped[float] = mapped_column(Float)
    cart_additional_values_discount: Mapped[float] = mapped_column(Float)
    cart_additional_values_increase: Mapped[float] = mapped_column(Float)
    id_quotation: Mapped[str] = mapped_column(String(255))
    estimated_delivery_date: Mapped[datetime] = mapped_column(Date, nullable=True)
    external_code: Mapped[str] = mapped_column(String(255))
    tracking_url: Mapped[str] = mapped_column(String(255))
    has_payment: Mapped[bool] = mapped_column(Boolean, default=False)
    has_shipment: Mapped[bool] = mapped_column(Boolean, default=False)
    has_invoice: Mapped[bool] = mapped_column(Boolean, default=False)
    total_comission_user: Mapped[float] = mapped_column(Float)
    total_comission: Mapped[float] = mapped_column(Float)
    is_traceable: Mapped[bool] = mapped_column(Boolean, default=False)
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())

    order_status_id: Mapped[int] = mapped_column(Integer, ForeignKey("order_status.id"), nullable=True)
    order_status: Mapped["OrderStatus"] = relationship("OrderStatus", foreign_keys=[order_status_id])


# products_sold = relationship('ProductsSold', backref='order')
#  payment = relationship('Payment', backref='order')


class OrderStatus(Base):
    __tablename__ = 'order_status'

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    default: Mapped[bool] = mapped_column(Boolean, default=False)
    type: Mapped[str] = mapped_column(String(255))
    show_backoffice: Mapped[bool] = mapped_column(Boolean, default=False)
    allow_edit_order: Mapped[bool] = mapped_column(Boolean, default=False)
    description: Mapped[str] = mapped_column(String)
    status: Mapped[str] = mapped_column(String(255))
    show_status_central: Mapped[str] = mapped_column(String(255), default="")
    background: Mapped[str] = mapped_column(String(7))
    display_name: Mapped[str] = mapped_column(String(255), nullable=True)
    font_color: Mapped[str] = mapped_column(String(7), nullable=True)
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())



class Product(Base):
    __tablename__ = 'product'

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    modified: Mapped[datetime] = mapped_column(DateTime)
    ean: Mapped[str] = mapped_column(String)
    is_kit: Mapped[bool] = mapped_column(Boolean)
    slug: Mapped[str] = mapped_column(String)
    ncm: Mapped[str] = mapped_column(String)
    activation_date: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    deactivation_date: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    name: Mapped[str] = mapped_column(String)
    price: Mapped[float] = mapped_column(Float)
    cost_price: Mapped[float] = mapped_column(Float)
    dollar_cost_price: Mapped[float] = mapped_column(Float)
    promotional_price: Mapped[float] = mapped_column(Float)
    start_promotion: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    end_promotion: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    brand: Mapped[str] = mapped_column(String)
    brand_id: Mapped[str] = mapped_column(String)
    model: Mapped[str] = mapped_column(String)
    weight: Mapped[float] = mapped_column(Float)
    length: Mapped[float] = mapped_column(Float)
    width: Mapped[float] = mapped_column(Float)
    height: Mapped[float] = mapped_column(Float)
    stock: Mapped[int] = mapped_column(Integer)
    category_id: Mapped[int] = mapped_column(Integer)
    available: Mapped[bool] = mapped_column(Boolean)
    availability: Mapped[str] = mapped_column(String)
    reference: Mapped[str] = mapped_column(String)
    hot: Mapped[bool] = mapped_column(Boolean)
    release: Mapped[bool] = mapped_column(Boolean)
    additional_button: Mapped[bool] = mapped_column(Boolean)
    has_variation: Mapped[bool] = mapped_column(Boolean)
    rating: Mapped[float] = mapped_column(Float)
    count_rating: Mapped[int] = mapped_column(Integer)
    quantity_sold: Mapped[int] = mapped_column(Integer)
    url = Column(JSON)
    created: Mapped[datetime] = mapped_column(DateTime)
    payment_option: Mapped[str] = mapped_column(String)
    payment_option_details = Column(JSON)  # TODO: update to relation
    related_categories = Column(JSON)  # TODO: update to relation
    release_date: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    shortcut: Mapped[str] = mapped_column(String)
    virtual_product: Mapped[str] = mapped_column(String)
    minimum_stock: Mapped[int] = mapped_column(Integer)
    minimum_stock_alert: Mapped[bool] = mapped_column(Boolean)
    free_shipping: Mapped[bool] = mapped_column(Boolean)
    video: Mapped[str] = mapped_column(String)
    metatag = Column(JSON)  # Assuming this might be a list, hence JSON
    payment_option_html: Mapped[str] = mapped_column(String)
    upon_request: Mapped[bool] = mapped_column(Boolean)
    available_for_purchase: Mapped[bool] = mapped_column(Boolean)
    all_categories: Mapped[str] = mapped_column(String(), nullable=True)
    product_image = Column(JSON)  # Assuming this might be a list, hence JSON
    variant = Column(JSON)  # TODO: update to relation
    additional_infos = Column(JSON)  # Assuming this might be a list, hence JSON
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())



class Category(Base):
    __tablename__ = 'category'

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    parent_id: Mapped[int] = mapped_column(Integer, ForeignKey('category.id'), nullable=True)
    name: Mapped[str] = mapped_column(String)
    small_description: Mapped[str] = mapped_column(String)
    images: Mapped[str] = mapped_column(JSON)
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())

class ProductsSold(Base):
    __tablename__ = 'products_sold'

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    product_id: Mapped[int] = mapped_column(Integer, nullable=False)
    order_id: Mapped[int] = mapped_column(Integer, ForeignKey('order.id'), nullable=False)
    name: Mapped[str] = mapped_column(String)
    price: Mapped[float] = mapped_column(Float)
    original_price: Mapped[float] = mapped_column(Float)
    quantity: Mapped[int] = mapped_column(Integer)
    model: Mapped[str] = mapped_column(String)
    reference: Mapped[str] = mapped_column(String)
    variant_id: Mapped[int] = mapped_column(Integer)
    additional_information: Mapped[str] = mapped_column(String)
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())


class OrderProductsSold(Base):
    __tablename__ = 'order_products_sold'

    order_id: Mapped[int] = mapped_column(Integer, primary_key=True)
    products_sold_id: Mapped[int] = mapped_column(Integer, primary_key=True)
    audit_create_ts: Mapped[datetime] = mapped_column(DateTime, onupdate=func.now(), server_default=func.now())


#
#
# class PropertyValue(Base):
#     __tablename__ = 'property_value'
#
#     id = Column(Integer, primary_key=True)
#     name = Column(String)
#     property_id = Column(Integer, ForeignKey('property.id'))
#     image = Column(JSON)  # Assuming image has both HTTP and HTTPS links
#
#     # Relationship to Property
#     property = relationship("Property", backref=backref("PropertyValue", cascade="all, delete-orphan"))
#
#
# class Property(Base):
#     __tablename__ = 'property'
#
#     id = Column(Integer, primary_key=True)
#     active_display = Column(Boolean)
#     name = Column(String)
#     position = Column(Integer)
#     display = Column(Boolean)
#     has_product = Column(Boolean)
#
#     # Relationship to PropertyValues
#     PropertyValue = relationship("PropertyValue", backref="property")
#
#

#
#

#
#
# class Variant(Base):
#     __tablename__ = 'variant'
#
#     id = Column(Integer, primary_key=True)
#     ean = Column(String)
#     order = Column(Integer)
#     product_id = Column(Integer, nullable=False)
#     price = Column(Float)
#     cost_price = Column(Float)
#     stock = Column(Integer)
#     minimum_stock = Column(Integer)
#     reference = Column(String)
#     weight = Column(Float)
#     length = Column(Float)
#     width = Column(Float)
#     height = Column(Float)
#     start_promotion = Column(DateTime)
#     end_promotion = Column(DateTime)
#     promotional_price = Column(Float)
#     payment_option = Column(String)
#     payment_option_details = Column(JSON)  # JSON to store payment_option_details
#     available = Column(Boolean)
#     illustrative_image = Column(JSON)  # JSON to store illustrative image URLs
#     quantity_sold = Column(Integer)
#     color_id_1 = Column(Integer)
#     color_id_2 = Column(Integer)
#     cubic_weight = Column(Float)
#
#     # Relationships
#     skus = relationship('Sku', backref='variant', cascade='all, delete-orphan')
#     variant_images = relationship('VariantImage', backref='variant', cascade='all, delete-orphan')
#
# class Payment(Base):
#     __tablename__ = 'payment'
#
#     id = Column(Integer, primary_key=True)
#     order_id = Column(Integer, ForeignKey('order.id'))
