import random
import uuid
from datetime import datetime, timedelta

from faker import Faker
from werkzeug.security import generate_password_hash

from app import create_app, db
from models import (
    Cart,
    CartItem,
    Category,
    CategoryEnum,
    Order,
    OrderItem,
    Product,
    ProductImage,
    ProductLike,
    Review,
    User,
)

def create_seed_data():
  """Create dummy data for testing"""
  fake = Faker()

  print("🌱 Starting database seeding...")


  print("👤 Checking/Creating admin user...")
  admin = User.query.filter_by(email="admin@wearwell.com").first()
  if not admin:
    admin = User(
        email="admin@wearwell.com",
        password_hash=generate_password_hash("admin123"),
        is_admin=True,
    )
    db.session.add(admin)
    print("✅ Created admin user")
  else:
    print("⚠️ Admin user already exists, skipping...")

  print("👥 Creating regular users...")
  users = [admin] if admin else []

  existing_users = User.query.count()
  users_to_create = max(
      0, 11 - existing_users
  )

  for i in range(users_to_create):
    email = f"user{i + 1}@example.com"


    if not User.query.filter_by(email=email).first():
      user = User(
          email=email,
          password_hash=generate_password_hash(f"password{i + 1}"),
          is_admin=False,
      )
      db.session.add(user)
      users.append(user)

  db.session.commit()

  print("🏷️ Creating categories...")
  categories = []

  for cat_name in CategoryEnum.ALL:
    category = Category.query.filter_by(name=cat_name).first()
    if not category:
      category = Category(name=cat_name)
      db.session.add(category)
    categories.append(category)

  db.session.commit()

  print("👕 Creating products...")

  existing_products_count = Product.query.count()
  products_to_create = max(0, 50 - existing_products_count)

  if products_to_create > 0:
    clothing_brands = [
        "Nike",
        "Adidas",
        "Levi's",
        "H&M",
        "Zara",
        "Uniqlo",
        "Gap",
        "Puma",
        "Under Armour",
        "Calvin Klein",
    ]
    colors = [
        "Black",
        "White",
        "Blue",
        "Red",
        "Green",
        "Gray",
        "Navy",
        "Brown",
        "Beige",
        "Maroon",
    ]
    materials = [
        "Cotton",
        "Polyester",
        "Denim",
        "Wool",
        "Linen",
        "Silk",
        "Leather",
        "Nylon",
        "Rayon",
        "Spandex",
    ]
    product_types = [
        "T-Shirt",
        "Shirt",
        "Jeans",
        "Pants",
        "Jacket",
        "Hoodie",
        "Sweater",
        "Shorts",
        "Dress",
    ]

    existing_products = Product.query.all()
    products = existing_products.copy()

    existing_skus = {p.sku for p in existing_products if p.sku}
    new_skus = set()

    for i in range(products_to_create):
      while True:
        sku = f"SKU-{uuid.uuid4().hex[:8].upper()}"
        if sku not in existing_skus and sku not in new_skus:
          new_skus.add(sku)
          break

      category = random.choice(categories)
      price = round(random.uniform(15, 150), 2)
      stock = random.randint(0, 100)

      product = Product(
          name=f"{random.choice(product_types)} - {fake.word().title()}",
          description=fake.paragraph(nb_sentences=3),
          price=price,
          stock=stock,
          color=random.choice(colors),
          size=random.choice(["XS", "S", "M", "L", "XL", "XXL"]),
          material=random.choice(materials),
          company=random.choice(clothing_brands),
          sku=sku,
          weight=round(random.uniform(0.1, 2.0), 2),
          dimensions=f"{
              random.randint(
                  30,
                  60)}x{
              random.randint(
                  20,
                  40)}x{
              random.randint(
                  2,
                  10)} cm",
          category_id=category.id,
      )
      db.session.add(product)
      products.append(product)

    db.session.commit()
    print(f"✅ Created {products_to_create} new products")
  else:
    products = Product.query.all()
    print(f"⚠️  Already have {existing_products_count} products, skipping...")

  print("🖼️ Creating product images...")
  new_products = [p for p in products if not p.images]

  for product in new_products:
    num_images = random.randint(1, 4)
    for j in range(num_images):
      image = ProductImage(
          product_id=product.id,
          filename=f"product_{product.id}_img_{j + 1}.jpg",
          is_primary=(j == 0),
          display_order=j,
      )
      db.session.add(image)

  db.session.commit()

  existing_reviews = Review.query.count()
  if existing_reviews < 100:
    print("⭐ Creating reviews...")
    products_without_reviews = [p for p in products if not p.reviews]
    products_to_review = random.sample(
        products_without_reviews, min(30, len(products_without_reviews))
    )

    for product in products_to_review:
      num_reviews = random.randint(1, 8)
      for _ in range(num_reviews):
        user = random.choice(users[1:]) if len(users) > 1 else users[0]
        review = Review(
            product_id=product.id,
            user_id=user.id,
            rating=random.randint(1, 5),
            title=fake.sentence(),
            comment=fake.paragraph(),
            is_verified_purchase=random.choice([True, False]),
            created_at=fake.date_time_between(
                start_date="-1y", end_date="now"),
        )
        db.session.add(review)

    db.session.commit()
    print(f"✅ Created {Review.query.count() - existing_reviews} new reviews")
  else:
    print(f"⚠️  Already have {existing_reviews} reviews, skipping...")

  print("🛒 Creating carts...")
  users_without_carts = [u for u in users if not u.cart]

  for user in users_without_carts[:5]:
    cart = Cart(user_id=user.id)
    db.session.add(cart)
    db.session.flush()

    num_items = random.randint(1, 5)
    for _ in range(num_items):
      product = random.choice(products)
      cart_item = CartItem(
          cart_id=cart.id,
          product_id=product.id,
          quantity=random.randint(1, 3),
          selected_size=product.size,
          selected_color=product.color,
      )
      db.session.add(cart_item)

  db.session.commit()

  existing_orders = Order.query.count()
  if existing_orders < 15:
    print("📦 Creating orders...")
    order_statuses = ["pending", "processing",
                      "shipped", "delivered", "cancelled"]

    orders_to_create = 15 - existing_orders
    for i in range(orders_to_create):
      user = random.choice(users)
      order = Order(
          user_id=user.id,
          status=random.choice(order_statuses),
          created_at=fake.date_time_between(start_date="-6m", end_date="now"),
      )
      db.session.add(order)
      db.session.flush()

      num_items = random.randint(1, 5)

      for _ in range(num_items):
        product = random.choice(products)
        quantity = random.randint(1, 3)
        price = product.price

        order_item = OrderItem(
            order_id=order.id,
            product_id=product.id,
            quantity=quantity,
            price_at_purchase=price,
            selected_size=product.size,
            selected_color=product.color,
        )
        db.session.add(order_item)

    db.session.commit()
    print(f"✅ Created {orders_to_create} new orders")
  else:
    print(f"⚠️  Already have {existing_orders} orders, skipping...")

  print("❤️ Creating product likes...")
  existing_likes = ProductLike.query.count()

  if existing_likes < 50:
    products_to_like = random.sample(products, min(20, len(products)))
    likes_created = 0

    for product in products_to_like:

      available_users = [u for u in users if u.id != 1]
      num_users_to_like = min(random.randint(3, 10), len(available_users))
      users_to_like = random.sample(available_users, num_users_to_like)

      for user in users_to_like:

        existing_like = ProductLike.query.filter_by(
            product_id=product.id, user_id=user.id
        ).first()

        if not existing_like:
          like = ProductLike(
              product_id=product.id,
              user_id=user.id,
              is_like=random.choice([True, False]),
              created_at=fake.date_time_between(
                  start_date="-3m", end_date="now"
              ),
          )
          db.session.add(like)
          likes_created += 1

    db.session.commit()
    print(f"✅ Created {likes_created} new likes")
  else:
    print(f"⚠️  Already have {existing_likes} likes, skipping...")

  print("\n" + "=" * 50)
  print("✅ DATABASE SEEDING COMPLETED SUCCESSFULLY!")
  print("=" * 50)
  print(f"\n📊 FINAL COUNTS:")
  print(f"   👥 Users: {User.query.count()}")
  print(f"   🏷️  Categories: {Category.query.count()}")
  print(f"   👕 Products: {Product.query.count()}")
  print(f"   🖼️  Product Images: {ProductImage.query.count()}")
  print(f"   ⭐ Reviews: {Review.query.count()}")
  print(f"   🛒 Carts: {Cart.query.count()}")
  print(f"   📦 Orders: {Order.query.count()}")
  print(f"   ❤️  Likes: {ProductLike.query.count()}")

  print("\n🔑 LOGIN CREDENTIALS:")
  print("   👑 Admin:")
  print("      Email: admin@wearwell.com")
  print("      Password: admin123")
  print("\n   👤 Test Users (10 available):")
  print("      Email: user1@example.com")
  print("      Password: password1")
  print("      Email: user2@example.com")
  print("      Password: password2")
  print("      ... and 8 more users (user3@example.com to user10@example.com)")

  print("\n💡 TIPS:")
  print("   • Run this script multiple times to add more data")
  print("   • Data won't duplicate (checks for existing records)")
  print("   • To start fresh, clear your database first")


def clear_and_seed():
  """Clear all data and seed fresh"""
  print("⚠️ WARNING: This will delete ALL data from the database!")
  response = input("Are you sure? Type 'YES' to continue: ")

  if response != "YES":
    print("❌ Operation cancelled")
    return

  print("🗑️  Clearing database...")

  ProductLike.query.delete()
  OrderItem.query.delete()
  Order.query.delete()
  CartItem.query.delete()
  Cart.query.delete()
  Review.query.delete()
  ProductImage.query.delete()
  Product.query.delete()
  Category.query.delete()
  User.query.delete()

  db.session.commit()
  print("✅ Database cleared!")

  create_seed_data()

if __name__ == "__main__":
  import sys

  app = create_app()
  with app.app_context():
    if len(sys.argv) > 1 and sys.argv[1] == "--fresh":
      clear_and_seed()
    else:
      create_seed_data()
