ProductController.java

package com.ctrlbuy.webshop.controller;

import com.ctrlbuy.webshop.model.Product;
import com.ctrlbuy.webshop.service.ProductService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

@Controller
@RequestMapping(value = {"/products", "/produkter"})
@RequiredArgsConstructor
@Slf4j
public class ProductController {

    private final ProductService productService;

    @GetMapping
    public String listProducts(
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String search,
            Model model) {

        log.info("=== PRODUKTCONTROLLER DEBUG START ===");
        log.info("Parameters - category: {}, search: {}", category, search);

        try {
            List<Product> products;

            if (search != null && !search.trim().isEmpty()) {
                products = productService.searchProducts(search.trim());
                model.addAttribute("pageTitle", "Sökresultat för: " + search);
                model.addAttribute("searchTerm", search);
                log.info("Searching for products with query: {}, found: {} products", search, products.size());
            } else if (category != null && !category.trim().isEmpty() && !category.equals("Alla")) {
                products = productService.getProductsByCategory(category);
                model.addAttribute("pageTitle", "Produkter i kategorin: " + category);
                model.addAttribute("selectedCategory", category);
                log.info("Filtering products by category: {}, found: {} products", category, products.size());
            } else {
                products = productService.getAllProducts();
                model.addAttribute("pageTitle", "Alla produkter");
                log.info("Loading all products, found: {} products", products.size());
            }

            model.addAttribute("products", products);
            log.info("Products loaded successfully: {} products", products.size());

        } catch (Exception e) {
            log.error("ERROR in listProducts: ", e);
            model.addAttribute("error", "Ett fel uppstod vid hämtning av produkter.");
            model.addAttribute("products", List.of());
        }

        log.info("=== PRODUKTCONTROLLER DEBUG END ===");
        return "products"; // 🔥 FIXAT: Använder products template för lista
    }

    // 🔥 FIXAT: Produktdetaljer använder nu product-detail template
    @GetMapping("/{id}")
    public String viewProduct(@PathVariable Long id,
                              Model model,
                              RedirectAttributes redirectAttributes) {
        log.info("=== PRODUKTDETALJER DEBUG START ===");
        log.info("Visar produktdetaljer för ID: {}", id);

        try {
            Optional<Product> productOpt = productService.findById(id);

            if (productOpt.isEmpty()) {
                log.warn("Produkt med ID {} hittades inte", id);
                redirectAttributes.addFlashAttribute("error", "Produkten hittades inte.");
                return "redirect:/products";
            }

            Product product = productOpt.get();
            log.info("Produkt hittad: {} (ID: {})", product.getName(), product.getId());

            // Lägg till produktdata
            model.addAttribute("product", product);
            model.addAttribute("title", product.getName() + " - CTRL+BUY Solutions");

            // 🔥 FIXAT: Bättre null-kontroll för recensioner
            try {
                // Placeholder för framtida recensioner
                model.addAttribute("reviews", List.of());
                model.addAttribute("reviewCount", 0);
                model.addAttribute("averageRating", 0.0);
                log.debug("Recensionsdata initialiserad");
            } catch (Exception e) {
                log.warn("Could not load reviews for product {}: {}", product.getName(), e.getMessage());
                model.addAttribute("reviews", List.of());
                model.addAttribute("reviewCount", 0);
                model.addAttribute("averageRating", 0.0);
            }

            // 🔥 FÖRBÄTTRAT: Relaterade produkter med bättre felhantering
            if (product.getCategory() != null && !product.getCategory().trim().isEmpty()) {
                try {
                    List<Product> relatedProducts = productService.getProductsByCategory(product.getCategory())
                            .stream()
                            .filter(p -> !p.getId().equals(id))
                            .limit(4)
                            .toList();
                    model.addAttribute("relatedProducts", relatedProducts);
                    log.info("Found {} related products för kategori: {}", relatedProducts.size(), product.getCategory());
                } catch (Exception e) {
                    log.warn("Could not load related products: {}", e.getMessage());
                    model.addAttribute("relatedProducts", List.of());
                }
            } else {
                log.warn("Ingen kategori för produkt {}, inga relaterade produkter", product.getName());
                model.addAttribute("relatedProducts", List.of());
            }

            // 🔥 FÖRBÄTTRAT: Rea-logik med bättre null-kontroller
            boolean isOnSale = false;
            if (product.getName() != null) {
                String nameLower = product.getName().toLowerCase();
                String descLower = product.getDescription() != null ? product.getDescription().toLowerCase() : "";

                isOnSale = nameLower.contains("rea") ||
                        nameLower.contains("sale") ||
                        nameLower.contains("kampanj") ||
                        descLower.contains("kampanj") ||
                        descLower.contains("rea");
            }

            if (isOnSale && product.getPrice() != null) {
                BigDecimal salePrice = product.getPrice().multiply(new BigDecimal("0.8"));
                BigDecimal savings = product.getPrice().subtract(salePrice);
                BigDecimal discountPercentage = new BigDecimal("20");

                model.addAttribute("discountPercentage", discountPercentage);
                model.addAttribute("savings", savings);
                model.addAttribute("salePrice", salePrice);
                log.info("Produkt på rea: {} - Ordinarie: {} kr, Rea: {} kr",
                        product.getName(), product.getPrice(), salePrice);
            }

            // 🔥 FÖRBÄTTRAT: Lagerstatus med bättre logik
            Integer stockQty = product.getStockQuantity();
            boolean inStock = stockQty != null && stockQty > 0;
            boolean lowStock = stockQty != null && stockQty < 5 && stockQty > 0;

            model.addAttribute("inStock", inStock);
            model.addAttribute("lowStock", lowStock);
            model.addAttribute("onSale", isOnSale);

            log.info("Lagerstatus - I lager: {}, Lågt lager: {}, Antal: {}",
                    inStock, lowStock, stockQty);
            log.info("Produktdetaljer redo för visning: {}", product.getName());

        } catch (Exception e) {
            log.error("Error loading product with id {}: {}", id, e.getMessage(), e);
            redirectAttributes.addFlashAttribute("error", "Ett fel uppstod vid hämtning av produkten.");
            return "redirect:/products";
        }

        log.info("=== PRODUKTDETALJER DEBUG END ===");
        return "product-detail"; // 🔥 FIXAT: Använder product-detail template
    }

    // API endpoint för produktsökning (AJAX)
    @GetMapping("/api/search")
    @ResponseBody
    public List<Product> searchProducts(@RequestParam String q) {
        log.debug("API-sökning efter: {}", q);

        if (q == null || q.trim().length() < 2) {
            return List.of();
        }

        try {
            return productService.searchActiveProducts(q.trim())
                    .stream()
                    .limit(10)
                    .toList();
        } catch (Exception e) {
            log.warn("Search method error: {}", e.getMessage());
            return List.of();
        }
    }

    // Kategori-endpoint
    @GetMapping("/category/{category}")
    public String viewCategory(@PathVariable String category, Model model) {
        return listProducts(category, null, model);
    }

    // Rea-sida
    @GetMapping("/sale")
    public String viewSaleProducts(Model model) {
        log.debug("Loading sale products");
        try {
            List<Product> saleProducts = productService.getProductsOnSale();
            model.addAttribute("products", saleProducts);
            model.addAttribute("pageTitle", "Produkter på rea");
            log.info("Found {} products on sale", saleProducts.size());
        } catch (Exception e) {
            log.error("Error loading sale products: {}", e.getMessage());
            model.addAttribute("products", List.of());
            model.addAttribute("error", "Kunde inte ladda rea-produkter");
        }
        return "products";
    }

    // Populära produkter
    @GetMapping("/popular")
    public String viewPopularProducts(Model model) {
        log.debug("Loading popular products");
        try {
            List<Product> popularProducts = productService.getPopularProducts(12);
            model.addAttribute("products", popularProducts);
            model.addAttribute("pageTitle", "Populära produkter");
            log.info("Found {} popular products", popularProducts.size());
        } catch (Exception e) {
            log.error("Error loading popular products: {}", e.getMessage());
            model.addAttribute("products", List.of());
            model.addAttribute("error", "Kunde inte ladda populära produkter");
        }
        return "products";
    }

    // Nya produkter
    @GetMapping("/new")
    public String viewNewProducts(Model model) {
        log.debug("Loading new products");
        try {
            List<Product> newProducts = productService.getNewestProducts(12);
            model.addAttribute("products", newProducts);
            model.addAttribute("pageTitle", "Nya produkter");
            log.info("Found {} new products", newProducts.size());
        } catch (Exception e) {
            log.error("Error loading new products: {}", e.getMessage());
            model.addAttribute("products", List.of());
            model.addAttribute("error", "Kunde inte ladda nya produkter");
        }
        return "products";
    }

    // Kontrollera lagerstatus (AJAX)
    @GetMapping("/{id}/stock")
    @ResponseBody
    public boolean checkStock(@PathVariable Long id) {
        try {
            return productService.getProductByIdWithoutView(id)
                    .map(product -> product.getStockQuantity() != null && product.getStockQuantity() > 0)
                    .orElse(false);
        } catch (Exception e) {
            log.error("Error checking stock for product {}: {}", id, e.getMessage());
            return false;
        }
    }

    // 🔥 FÖRBÄTTRAT: Error handling med bättre logging
    @ExceptionHandler(Exception.class)
    public String handleError(Exception e, Model model) {
        log.error("Fel i ProductController: {}", e.getMessage(), e);
        model.addAttribute("error", "Ett oväntat fel inträffade vid hämtning av produkter.");
        model.addAttribute("products", List.of());
        return "products";
    }
}