# storefront/views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login as auth_login
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
from django.core.paginator import Paginator
from django.db.models import Q

from catalog.models import Category, Product, BlogPost, ContactMessage
from .forms import ContactForm


# ---------- Home ----------
def home(request):
    categories = Category.objects.order_by("name")
    products = Product.objects.order_by("-id")[:12]  # New Arrivals
    top_sellers = Product.objects.order_by("-rating", "-reviews_count")[:8]

    # Deal of the day: prefer 'salmon' if exists, else top-rated
    deal = (
        Product.objects.filter(Q(title__icontains="salmon") | Q(slug__icontains="salmon"))
        .order_by("-rating", "-reviews_count")
        .first()
    )
    if not deal:
        deal = top_sellers.first() if hasattr(top_sellers, "first") else None

    testimonials = [
        {"quote": "Super fast delivery and the apples were incredibly fresh.", "author": "Emma T."},
        {"quote": "Great selection and fair prices. My go-to for weekly groceries.", "author": "Daniel K."},
        {"quote": "Loved the salmon deal of the day! Will order again.", "author": "Priya S."},
    ]

    return render(
        request,
        "storefront/home.html",
        {
            "categories": categories,
            "products": products,
            "top_sellers": top_sellers,
            "deal": deal,
            "testimonials": testimonials,
        },
    )


# ---------- Catalog ----------
def category_view(request, slug):
    category = get_object_or_404(Category, slug=slug)
    products = category.products.all()
    return render(request, "storefront/category.html", {"category": category, "products": products})


def product_detail(request, slug):
    product = get_object_or_404(Product, slug=slug)
    return render(request, "storefront/product_detail.html", {"product": product})


@require_POST
def add_to_cart(request, slug):
    product = get_object_or_404(Product, slug=slug)
    try:
        qty = int(request.POST.get("qty", "1") or "1")
    except ValueError:
        qty = 1
    qty = max(1, min(qty, 99))

    cart = request.session.get("cart", {}) or {}
    pid = str(product.id)
    cart[pid] = cart.get(pid, 0) + qty
    request.session["cart"] = cart
    request.session.modified = True

    nxt = request.POST.get("next") or request.GET.get("next")
    return redirect(nxt) if nxt else redirect("cart")


def cart(request):
    cart = request.session.get("cart", {})
    if not isinstance(cart, dict):
        cart = {}

    ids = [int(k) for k in cart.keys()]
    products = Product.objects.filter(id__in=ids)

    lines, total = [], 0
    for pr in products:
        q = cart.get(str(pr.id), 0)
        line_total = float(pr.price) * q
        total += line_total
        lines.append({"product": pr, "qty": q, "line_total": line_total})

    return render(request, "storefront/cart.html", {"lines": lines, "total": total})


# ---------- Auth ----------
def signup(request):
    if request.method == "POST":
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            auth_login(request, user)
            return redirect("account")
    else:
        form = UserCreationForm()
    return render(request, "registration/signup.html", {"form": form})


@login_required
def account(request):
    return render(request, "storefront/account.html")


# ---------- Newsletter ----------
@require_POST
def newsletter_subscribe(request):
    from catalog.models import NewsletterSubscriber  # local import to avoid circulars if missing

    email = (request.POST.get("email") or "").strip().lower()
    if email:
        NewsletterSubscriber.objects.get_or_create(email=email)
        messages.success(request, "You're subscribed!")
    else:
        messages.error(request, "Please enter a valid email.")
    return redirect(request.META.get("HTTP_REFERER") or "home")


# ---------- Store / About / Contact / Blog ----------
def store(request):
    q = (request.GET.get("q") or "").strip()
    cslug = request.GET.get("category")
    products = Product.objects.all().select_related("category")

    if q:
        products = products.filter(
            Q(title__icontains=q) | Q(description__icontains=q) | Q(tags__icontains=q)
        )
    if cslug:
        products = products.filter(category__slug=cslug)

    products = products.order_by("-id")
    paginator = Paginator(products, 12)
    page = paginator.get_page(request.GET.get("page"))
    categories = Category.objects.order_by("name")

    return render(
        request,
        "storefront/store.html",
        {"page": page, "q": q, "cslug": cslug, "categories": categories},
    )


def about(request):
    return render(request, "storefront/about.html")


def contact(request):
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            ContactMessage.objects.create(**form.cleaned_data)
            messages.success(request, "Thanks! We'll get back to you soon.")
            return redirect("contact")
    else:
        form = ContactForm()
    return render(request, "storefront/contact.html", {"form": form})


def blog(request):
    q = (request.GET.get("q") or "").strip()
    posts = BlogPost.objects.filter(is_published=True)
    if q:
        posts = posts.filter(
            Q(title__icontains=q) | Q(excerpt__icontains=q) | Q(content__icontains=q)
        )
    posts = posts.order_by("-published_at")
    return render(request, "storefront/blog.html", {"posts": posts, "q": q})
from decimal import Decimal
from django.db import transaction
from django.contrib import messages
from django.shortcuts import render, get_object_or_404, redirect
from .forms import CheckoutForm
from catalog.models import Product, Order, OrderItem

def _cart_lines(request):
    cart = request.session.get("cart", {})
    if not isinstance(cart, dict):
        cart = {}
    ids = [int(k) for k in cart.keys()]
    products = Product.objects.filter(id__in=ids)
    lines, total = [], Decimal("0.00")
    for pr in products:
        qty = int(cart.get(str(pr.id), 0))
        if qty <= 0:
            continue
        line_total = pr.price * qty
        total += line_total
        lines.append({"product": pr, "qty": qty, "unit_price": pr.price, "line_total": line_total})
    return lines, total

def checkout(request):
    lines, total = _cart_lines(request)
    if request.method == "POST":
        form = CheckoutForm(request.POST)
        if not lines:
            messages.error(request, "Your cart is empty.")
            return redirect("store")
        if form.is_valid():
            with transaction.atomic():
                order = Order.objects.create(
                    name=form.cleaned_data["name"],
                    email=form.cleaned_data["email"],
                    phone=form.cleaned_data["phone"],
                    address_line1=form.cleaned_data["address_line1"],
                    address_line2=form.cleaned_data.get("address_line2", ""),
                    city=form.cleaned_data["city"],
                    region=form.cleaned_data["region"],
                    postal_code=form.cleaned_data["postal_code"],
                    country=form.cleaned_data["country"],
                    notes=form.cleaned_data.get("notes", ""),
                    total=total,
                    status="pending",
                )
                for row in lines:
                    OrderItem.objects.create(
                        order=order,
                        product=row["product"],
                        title=row["product"].title,
                        unit_price=row["unit_price"],
                        qty=row["qty"],
                        line_total=row["line_total"],
                    )
            # clear cart
            request.session["cart"] = {}
            request.session.modified = True
            return redirect("checkout_success", order_id=order.id)
    else:
        form = CheckoutForm()
    return render(request, "storefront/checkout.html", {"form": form, "lines": lines, "total": total})

def checkout_success(request, order_id):
    order = get_object_or_404(Order, id=order_id)
    return render(request, "storefront/checkout_success.html", {"order": order})
from django.contrib import messages
from django.views.decorators.http import require_POST
from django.db.models import Q
from catalog.models import Product, ReviewCategory, ProductReview
from .forms import ProductReviewForm
def product_detail(request, slug):
    product = get_object_or_404(Product, slug=slug)
    revcat_slug = (request.GET.get("revcat") or "").strip()
    categories = ReviewCategory.objects.order_by("order", "name")
    reviews_qs = product.reviews.filter(status="approved").select_related("user").prefetch_related("categories")
    if revcat_slug:
        reviews_qs = reviews_qs.filter(categories__slug=revcat_slug)

    form = ProductReviewForm()
    return render(
        request,
        "storefront/product_detail.html",
        {
            "product": product,
            "reviews": reviews_qs,
            "rev_categories": categories,
            "revcat_slug": revcat_slug,
            "review_form": form,
        },
    )
@require_POST
def add_review(request, slug):
    product = get_object_or_404(Product, slug=slug)
    form = ProductReviewForm(request.POST)
    if form.is_valid():
        review = form.save(commit=False)
        review.product = product
        if request.user.is_authenticated:
            review.user = request.user
            # If no guest name/email provided, fill from user
            if not review.name:
                review.name = request.user.get_full_name() or request.user.username
            if not review.email:
                review.email = request.user.email or ""
        else:
            # guests must provide name & email
            if not review.name or not review.email:
                messages.error(request, "Please enter your name and email.")
                return redirect(product.get_absolute_url() if hasattr(product, "get_absolute_url") else f"/product/{product.slug}/")
        # keep new reviews pending for moderation
        review.status = "pending"
        review.save()
        form.save_m2m()
        messages.success(request, "Thanks! Your review is submitted and pending approval.")
    else:
        messages.error(request, "Please correct the errors in the review form.")
    # redirect back to product page
    nxt = request.POST.get("next") or (product.get_absolute_url() if hasattr(product, "get_absolute_url") else f"/product/{product.slug}/")
    return redirect(nxt)
