
import os
from datetime import datetime
from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash
from extensions import db

class SizeEnum:
  XS = 'XS'
  S = 'S'
  M = 'M'
  L = 'L'
  XL = 'XL'
  XXL = 'XXL'
  XXXL = 'XXXL'
  ALL = [XS, S, M, L, XL, XXL, XXXL]

class CategoryEnum:
  T_SHIRTS = 'T-Shirts'
  SHIRTS = 'Shirts'
  JEANS = 'Jeans'
  PANTS = 'Pants'
  JACKETS = 'Jackets'
  HOODIES = 'Hoodies'
  SWEATERS = 'Sweaters'
  SHORTS = 'Shorts'
  DRESSES = 'Dresses'
  SKIRTS = 'Skirts'
  ACTIVEWEAR = 'Activewear'
  SHOES = 'Shoes'
  ACCESSORIES = 'Accessories'
  ALL = [
      T_SHIRTS, SHIRTS, JEANS, PANTS, JACKETS, HOODIES,
      SWEATERS, SHORTS, DRESSES, SKIRTS, ACTIVEWEAR,
      SHOES, ACCESSORIES
  ]

class User(db.Model, UserMixin):
  id = db.Column(db.Integer, primary_key=True)
  email = db.Column(db.String(120), unique=True, nullable=False)
  password_hash = db.Column(db.String(255))
  is_admin = db.Column(db.Boolean, default=False)
  cart = db.relationship('Cart', backref='user', uselist=False)
  orders = db.relationship('Order', backref='user', lazy=True)
  reviews = db.relationship('Review', backref='user', lazy=True)
  likes = db.relationship('ProductLike', backref='user', lazy=True)

  def set_password(self, password):
    self.password_hash = generate_password_hash(password)

  def check_password(self, password):
    return check_password_hash(self.password_hash, password)

class Category(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(50), nullable=False)
  products = db.relationship('Product', backref='category', lazy=True)

class Product(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(120), nullable=False)
  description = db.Column(db.Text)
  price = db.Column(db.Float, nullable=False)
  stock = db.Column(db.Integer, default=0)
  color = db.Column(db.String(50))
  size = db.Column(db.String(10))
  material = db.Column(db.String(50))
  company = db.Column(db.String(100))
  sku = db.Column(db.String(50), unique=True)
  weight = db.Column(db.Float)
  dimensions = db.Column(db.String(50))
  category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
  images = db.relationship(
      'ProductImage', backref='product', lazy=True, cascade="all, delete-orphan")
  reviews = db.relationship('Review', backref='product',
                            lazy=True, cascade="all, delete-orphan")
  likes = db.relationship('ProductLike', backref='product',
                          lazy=True, cascade="all, delete-orphan")

  @property
  def average_rating(self):
    if not self.reviews:
      return 0
    total = sum(review.rating for review in self.reviews)
    return round(total / len(self.reviews), 1)

  @property
  def like_count(self):
    return len([like for like in self.likes if like.is_like])

  @property
  def dislike_count(self):
    return len([like for like in self.likes if not like.is_like])

  @property
  def review_count(self):
    return len(self.reviews)

  @property
  def primary_image(self):
    if self.images:
      primary = next((img for img in self.images if img.is_primary), None)
      if primary:
        return primary
      return self.images[0]
    return None

  def get_image_url(self):
    """Alias for template compatibility"""
    return self.get_primary_image_url()

  def in_stock(self):
    return self.stock > 0

  def get_primary_image_url(self):
    primary = self.primary_image
    if primary:
      return f"/static/uploads/products/{primary.filename}"
    return "/static/images/default-product.jpg"

  def get_all_image_urls(self):
    return [f"/static/uploads/products/{img.filename}" for img in self.images]

  def __repr__(self):
    return f'<Product {self.name}>'

class ProductImage(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  product_id = db.Column(
      db.Integer, db.ForeignKey('product.id'), nullable=False)
  filename = db.Column(db.String(200), nullable=False)
  is_primary = db.Column(db.Boolean, default=False)
  display_order = db.Column(db.Integer, default=0)
  created_at = db.Column(db.DateTime, default=datetime.utcnow)

class ProductLike(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  product_id = db.Column(
      db.Integer, db.ForeignKey('product.id'), nullable=False)
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
  is_like = db.Column(db.Boolean, default=True)
  created_at = db.Column(db.DateTime, default=datetime.utcnow)


  __table_args__ = (db.UniqueConstraint(
      'product_id', 'user_id', name='unique_product_user_like'),)

class Review(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  product_id = db.Column(
      db.Integer, db.ForeignKey('product.id'), nullable=False)
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
  rating = db.Column(db.Integer, nullable=False)
  title = db.Column(db.String(200))
  comment = db.Column(db.Text)
  is_verified_purchase = db.Column(db.Boolean, default=False)
  created_at = db.Column(db.DateTime, default=datetime.utcnow)
  updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)

class Cart(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  items = db.relationship('CartItem', backref='cart',
                          cascade="all, delete-orphan", lazy=True)

class CartItem(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  cart_id = db.Column(db.Integer, db.ForeignKey('cart.id'))
  product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
  quantity = db.Column(db.Integer, default=1)
  selected_size = db.Column(db.String(10))
  selected_color = db.Column(db.String(50))

  product = db.relationship('Product')

class Order(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
  created_at = db.Column(db.DateTime, default=datetime.utcnow)

  status = db.Column(db.String(50), default='pending')

  items = db.relationship('OrderItem', backref='order',
                          cascade='all, delete-orphan', lazy=True)

class OrderItem(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
  product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
  quantity = db.Column(db.Integer, default=1)
  price_at_purchase = db.Column(db.Float)
  selected_size = db.Column(db.String(10))
  selected_color = db.Column(db.String(50))

  product = db.relationship('Product')

