OrderService.java

package com.ctrlbuy.webshop.service;

import com.ctrlbuy.webshop.entity.Cart;
import com.ctrlbuy.webshop.entity.CartItem;
import com.ctrlbuy.webshop.entity.Order;
import com.ctrlbuy.webshop.entity.OrderItem;
import com.ctrlbuy.webshop.security.entity.User;
import com.ctrlbuy.webshop.repository.OrderRepository;

// ===== JPA IMPORTS =====
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;

// ===== SPRING IMPORTS =====
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

// ===== LOGGING IMPORTS =====
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * đŸ›Ąïž RAILWAY COMPATIBLE OrderService
 * KOMPLETT VERSION MED ALLA IMPORTER OCH METODER
 */
@Service
@Transactional
public class OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    private final OrderRepository orderRepository;
    private final UserService userService;

    @PersistenceContext
    private EntityManager entityManager;

    // Constructor injection
    public OrderService(OrderRepository orderRepository, UserService userService) {
        this.orderRepository = orderRepository;
        this.userService = userService;
        logger.info("✅ OrderService initialiserad med Repository och UserService");
    }

    // ===== ADMIN METHODS FOR ADMIN CONTROLLER - ENTITYMANAGER VERSIONER =====

    /**
     * Get all orders (for admin) - ANVÄND ENTITYMANAGER
     */
    public List<Order> getAllOrders() {
        try {
            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o ORDER BY o.orderDate DESC", Order.class);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            logger.info("✅ HĂ€mtade {} orders för admin", results.size());
            return results;
        } catch (Exception e) {
            logger.error("Error fetching all orders", e);
            return new ArrayList<>();
        }
    }

    /**
     * Get orders by user ID - ANVÄND ENTITYMANAGER
     */
    public List<Order> getOrdersByUserId(Long userId) {
        try {
            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.user.id = :userId ORDER BY o.orderDate DESC", Order.class);
            query.setParameter("userId", userId);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            logger.info("✅ HĂ€mtade {} orders för user ID: {}", results.size(), userId);
            return results;
        } catch (Exception e) {
            logger.error("Error fetching orders for user: {}", userId, e);
            return new ArrayList<>();
        }
    }

    /**
     * Get order by ID - ANVÄND ENTITYMANAGER
     */
    public Order getOrderById(Long id) {
        try {
            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o LEFT JOIN FETCH o.orderItems WHERE o.id = :id", Order.class);
            query.setParameter("id", id);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("Ingen order hittades med ID: {}", id);
                return null;
            }

            Order order = results.get(0);
            logger.info("✅ Order hittades: {} (ID: {})", order.getOrderNumber(), id);
            return order;
        } catch (Exception e) {
            logger.error("Error fetching order by ID: {}", id, e);
            return null;
        }
    }

    /**
     * Update order status - ENKEL VERSION
     */
    public void updateOrderStatus(Long orderId, String status) {
        try {
            Order order = entityManager.find(Order.class, orderId);
            if (order != null) {
                // SĂ€tt status som String direkt (Order entity hanterar konvertering)
                order.setStatus(status);
                entityManager.merge(order);
                logger.info("Updated order {} status to {}", orderId, status);
            } else {
                logger.warn("Order med ID {} hittades inte", orderId);
            }
        } catch (Exception e) {
            logger.error("Error updating order status", e);
        }
    }

    /**
     * Search orders by order number and user ID - ANVÄND ENTITYMANAGER
     */
    public List<Order> searchOrdersByNumberAndUserId(String orderNumber, Long userId) {
        try {
            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.orderNumber LIKE :orderPattern AND o.user.id = :userId ORDER BY o.orderDate DESC",
                    Order.class);
            query.setParameter("orderPattern", "%" + orderNumber + "%");
            query.setParameter("userId", userId);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            logger.info("✅ Hittade {} orders för sökning: {} (user {})", results.size(), orderNumber, userId);
            return results;
        } catch (Exception e) {
            logger.error("Error searching orders", e);
            return new ArrayList<>();
        }
    }

    /**
     * Calculate total spent by user - ANVÄND ENTITYMANAGER
     */
    public double getTotalSpentByUser(Long userId) {
        try {
            Query query = entityManager.createQuery(
                    "SELECT COALESCE(SUM(o.totalAmount), 0.0) FROM Order o WHERE o.user.id = :userId");
            query.setParameter("userId", userId);

            Double total = (Double) query.getSingleResult();
            if (total == null) {
                total = 0.0;
            }

            logger.info("✅ Total spenderat för user {}: {} kr", userId, total);
            return total;
        } catch (Exception e) {
            logger.error("Error calculating total spent for user: {}", userId, e);
            return 0.0;
        }
    }

    // ===== BEFINTLIGA METODER - SAKNADE METODER FÖR COMPILATION FIX =====

    /**
     * ✅ NYTT: getLatestOrderByUser - HĂ€mta senaste order för anvĂ€ndare (för OrderHistoryController)
     */
    public Optional<Order> getLatestOrderByUser(User user) {
        try {
            logger.info("🔍 HĂ€mtar senaste order för anvĂ€ndare: {}", user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.user = :user ORDER BY o.orderDate DESC", Order.class);
            query.setParameter("user", user);
            query.setMaxResults(1); // Bara första (senaste) resultat

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.info("â„č Ingen order hittades för anvĂ€ndare: {}", user.getUsername());
                return Optional.empty();
            }

            Order latestOrder = results.get(0);
            logger.info("✅ Senaste order hittades: {} för anvĂ€ndare {}",
                    latestOrder.getOrderNumber(), user.getUsername());
            return Optional.of(latestOrder);

        } catch (Exception e) {
            logger.error("❌ Fel vid hĂ€mtning av senaste order för anvĂ€ndare {}: {}",
                    user.getUsername(), e.getMessage());
            return Optional.empty();
        }
    }

    /**
     * ✅ NYTT: getOrderByOrderNumberAndUser - HĂ€mta order baserat pĂ„ ordernummer och anvĂ€ndare (för OrderHistoryController)
     */
    public Optional<Order> getOrderByOrderNumberAndUser(String orderNumber, User user) {
        try {
            logger.info("🔍 HĂ€mtar order {} för anvĂ€ndare: {}", orderNumber, user.getUsername());

            if (orderNumber == null || orderNumber.trim().isEmpty()) {
                logger.error("❌ Tomt ordernummer för anvĂ€ndare: {}", user.getUsername());
                return Optional.empty();
            }

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.orderNumber = :orderNumber AND o.user = :user", Order.class);
            query.setParameter("orderNumber", orderNumber.trim());
            query.setParameter("user", user);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("⚠ Ingen order med nummer {} hittades för anvĂ€ndare {}",
                        orderNumber, user.getUsername());
                return Optional.empty();
            }

            Order order = results.get(0);
            logger.info("✅ Order {} hittades för anvĂ€ndare {}",
                    order.getOrderNumber(), user.getUsername());
            return Optional.of(order);

        } catch (Exception e) {
            logger.error("❌ Fel vid hĂ€mtning av order {} för anvĂ€ndare {}: {}",
                    orderNumber, user.getUsername(), e.getMessage());
            return Optional.empty();
        }
    }

    // ===== ORDER CREATION METHODS =====

    /**
     * 🛒 Skapa bestĂ€llning frĂ„n checkout-formulĂ€r
     */
    public Order createOrder(Cart cart, String email, String firstName, String lastName,
                             String address, String city, String postalCode, String phone,
                             String notes, String paymentMethod, Authentication auth) {

        logger.info("🛒 Skapar order frĂ„n checkout för: {} {}", firstName, lastName);

        try {
            if (cart == null || cart.getItems().isEmpty()) {
                logger.error("❌ Försöker skapa order med tom kundvagn");
                throw new RuntimeException("Kundvagnen Àr tom");
            }

            // đŸ›Ąïž SAFE USER LOOKUP - anvĂ€nd UserService istĂ€llet för repository direkt
            User user = null;
            if (auth != null && auth.isAuthenticated()) {
                Optional<User> userOpt = userService.findByUsername(auth.getName());
                user = userOpt.orElse(null);
                if (user != null) {
                    logger.info("đŸ‘€ Order skapas för inloggad anvĂ€ndare: {}", user.getUsername());
                } else {
                    logger.warn("⚠ AnvĂ€ndare inte hittad för autentiserad session: {}", auth.getName());
                }
            } else {
                logger.info("đŸ‘€ Order skapas för gĂ€st");
            }

            // BerÀkna totaler
            BigDecimal subtotal = cart.getTotalAmount();
            BigDecimal shipping = BigDecimal.valueOf(49.00);
            BigDecimal total = subtotal.add(shipping);

            logger.info("💰 Order totaler - Subtotal: {}, Frakt: {}, Total: {}", subtotal, shipping, total);

            // Generera ordernummer
            String orderNumber = generateOrderNumber();
            logger.info("🔱 Genererat ordernummer: {}", orderNumber);

            // Skapa bestÀllning
            Order order = new Order();
            order.setUser(user);
            order.setOrderNumber(orderNumber);
            order.setTotalAmount(total.doubleValue());
            order.setStatus(Order.OrderStatus.PENDING);
            order.setOrderDate(LocalDateTime.now());

            // Leveransadress
            order.setDeliveryName(firstName + " " + lastName);
            order.setDeliveryAddress(address);
            order.setDeliveryCity(city);
            order.setDeliveryPostalCode(postalCode);
            order.setDeliveryPhone(phone);
            order.setPaymentMethod(paymentMethod);

            // Spara bestÀllning först
            order = orderRepository.save(order);
            logger.info("đŸ’Ÿ Bas-order sparad med ID: {}", order.getId());

            // LÀgg till orderitems frÄn cart
            for (CartItem cartItem : cart.getItems()) {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrder(order);
                orderItem.setProduct(cartItem.getProduct());
                orderItem.setQuantity(cartItem.getQuantity());
                orderItem.setPrice(cartItem.getUnitPrice().doubleValue());
                orderItem.setProductName(cartItem.getProduct().getName());

                order.addOrderItem(orderItem);
                logger.info("📩 Lagt till orderitem: {} x{}", cartItem.getProduct().getName(), cartItem.getQuantity());
            }

            // Spara igen med orderitems
            order = orderRepository.save(order);
            logger.info("✅ Order komplett sparad: {} med {} items", orderNumber, order.getOrderItems().size());

            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid skapande av order frĂ„n checkout: {}", e.getMessage(), e);
            throw new RuntimeException("Kunde inte skapa bestÀllning: " + e.getMessage(), e);
        }
    }

    /**
     * 🛒 Skapa ny bestĂ€llning frĂ„n kundvagn (för inloggade anvĂ€ndare)
     */
    public Order createOrderFromCart(User user, List<com.ctrlbuy.webshop.controller.CartController.CartItem> cartItems, OrderDetails orderDetails) {

        logger.info("🛒 Skapar order frĂ„n kundvagn för anvĂ€ndare: {}", user.getUsername());

        try {
            if (cartItems == null || cartItems.isEmpty()) {
                logger.error("❌ Försöker skapa order med tom kundvagn för anvĂ€ndare: {}", user.getUsername());
                throw new RuntimeException("Kundvagnen Àr tom");
            }

            // BerÀkna totaler
            BigDecimal subtotal = cartItems.stream()
                    .map(com.ctrlbuy.webshop.controller.CartController.CartItem::getTotalPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal shipping = subtotal.compareTo(new BigDecimal("499")) >= 0
                    ? BigDecimal.ZERO
                    : new BigDecimal("49");
            BigDecimal total = subtotal.add(shipping);

            logger.info("💰 User order totaler - Subtotal: {}, Frakt: {}, Total: {}", subtotal, shipping, total);

            // Generera ordernummer
            String orderNumber = generateOrderNumber();
            logger.info("🔱 Genererat ordernummer för anvĂ€ndare: {}", orderNumber);

            // Skapa bestÀllning
            Order order = new Order();
            order.setUser(user);
            order.setOrderNumber(orderNumber);
            order.setTotalAmount(total.doubleValue());
            order.setStatus(Order.OrderStatus.PENDING);
            order.setOrderDate(LocalDateTime.now());

            // Leveransadress
            order.setDeliveryName(orderDetails.getDeliveryName());
            order.setDeliveryAddress(orderDetails.getDeliveryAddress());
            order.setDeliveryCity(orderDetails.getDeliveryCity());
            order.setDeliveryPostalCode(orderDetails.getDeliveryPostalCode());
            order.setDeliveryPhone(orderDetails.getDeliveryPhone());
            order.setPaymentMethod(orderDetails.getPaymentMethod());

            // Spara bestÀllning först
            order = orderRepository.save(order);
            logger.info("đŸ’Ÿ User bas-order sparad med ID: {}", order.getId());

            // LĂ€gg till orderitems
            for (com.ctrlbuy.webshop.controller.CartController.CartItem cartItem : cartItems) {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrder(order);
                orderItem.setProduct(cartItem.getProduct());
                orderItem.setQuantity(cartItem.getQuantity());
                orderItem.setPrice(cartItem.getUnitPrice().doubleValue());
                orderItem.setProductName(cartItem.getProduct().getName());

                order.addOrderItem(orderItem);
                logger.info("📩 User orderitem tillagt: {} x{}", cartItem.getProduct().getName(), cartItem.getQuantity());
            }

            // Spara igen med orderitems
            order = orderRepository.save(order);
            logger.info("✅ User order komplett: {} med {} items", orderNumber, order.getOrderItems().size());

            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid skapande av user order: {}", e.getMessage(), e);
            throw new RuntimeException("Kunde inte skapa anvÀndarens bestÀllning: " + e.getMessage(), e);
        }
    }

    /**
     * đŸ‘€ Skapa bestĂ€llning för icke-inloggad anvĂ€ndare (gĂ€st)
     */
    public Order createGuestOrder(List<com.ctrlbuy.webshop.controller.CartController.CartItem> cartItems, GuestOrderDetails guestDetails) {

        logger.info("đŸ‘€ Skapar gĂ€st-order för: {} {}", guestDetails.getFirstName(), guestDetails.getLastName());

        try {
            if (cartItems == null || cartItems.isEmpty()) {
                logger.error("❌ Försöker skapa gĂ€st-order med tom kundvagn");
                throw new RuntimeException("Kundvagnen Àr tom");
            }

            // BerÀkna totaler
            BigDecimal subtotal = cartItems.stream()
                    .map(com.ctrlbuy.webshop.controller.CartController.CartItem::getTotalPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal shipping = subtotal.compareTo(new BigDecimal("499")) >= 0
                    ? BigDecimal.ZERO
                    : new BigDecimal("49");
            BigDecimal total = subtotal.add(shipping);

            logger.info("💰 GĂ€st order totaler - Subtotal: {}, Frakt: {}, Total: {}", subtotal, shipping, total);

            // Generera ordernummer
            String orderNumber = generateOrderNumber();
            logger.info("🔱 Genererat ordernummer för gĂ€st: {}", orderNumber);

            // Skapa bestÀllning utan User
            Order order = new Order();
            order.setOrderNumber(orderNumber);
            order.setTotalAmount(total.doubleValue());
            order.setStatus(Order.OrderStatus.PENDING);
            order.setOrderDate(LocalDateTime.now());

            // Leveransadress frÄn gÀst
            order.setDeliveryName(guestDetails.getFirstName() + " " + guestDetails.getLastName());
            order.setDeliveryAddress(guestDetails.getAddress());
            order.setDeliveryCity(guestDetails.getCity());
            order.setDeliveryPostalCode(guestDetails.getPostalCode());
            order.setDeliveryPhone(guestDetails.getPhone());
            order.setPaymentMethod(guestDetails.getPaymentMethod());

            // Spara bestÀllning först
            order = orderRepository.save(order);
            logger.info("đŸ’Ÿ GĂ€st bas-order sparad med ID: {}", order.getId());

            // LĂ€gg till orderitems
            for (com.ctrlbuy.webshop.controller.CartController.CartItem cartItem : cartItems) {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrder(order);
                orderItem.setProduct(cartItem.getProduct());
                orderItem.setQuantity(cartItem.getQuantity());
                orderItem.setPrice(cartItem.getUnitPrice().doubleValue());
                orderItem.setProductName(cartItem.getProduct().getName());

                order.addOrderItem(orderItem);
                logger.info("📩 GĂ€st orderitem tillagt: {} x{}", cartItem.getProduct().getName(), cartItem.getQuantity());
            }

            // Spara igen med orderitems
            order = orderRepository.save(order);
            logger.info("✅ GĂ€st order komplett: {} med {} items", orderNumber, order.getOrderItems().size());

            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid skapande av gĂ€st-order: {}", e.getMessage(), e);
            throw new RuntimeException("Kunde inte skapa gÀst-bestÀllning: " + e.getMessage(), e);
        }
    }

    // ===== SAFE ORDER LOOKUP METHODS =====

    /**
     * đŸ›Ąïž SAFE findByOrderNumberAndUser - anvĂ€nder EntityManager
     */
    public Order findByOrderNumberAndUser(String orderNumber, User user) {
        try {
            logger.info("🔍 Söker order med nummer {} för anvĂ€ndare: {}", orderNumber, user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.orderNumber = :orderNumber AND o.user = :user", Order.class);
            query.setParameter("orderNumber", orderNumber);
            query.setParameter("user", user);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("⚠ Ingen order hittades med nummer {} för anvĂ€ndare {}", orderNumber, user.getUsername());
                return null;
            }

            Order order = results.get(0);
            logger.info("✅ Order hittades: {} för anvĂ€ndare {}", orderNumber, user.getUsername());
            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid sökning av order {} för anvĂ€ndare {}: {}", orderNumber, user.getUsername(), e.getMessage());
            return null;
        }
    }

    /**
     * đŸ›Ąïž SAFE findByOrderNumber - anvĂ€nder EntityManager
     */
    public Order findByOrderNumber(String orderNumber) {
        try {
            logger.info("🔍 Söker order med nummer: {}", orderNumber);

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.orderNumber = :orderNumber", Order.class);
            query.setParameter("orderNumber", orderNumber);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("⚠ Ingen order hittades med nummer: {}", orderNumber);
                return null;
            }

            Order order = results.get(0);
            logger.info("✅ Order hittades: {}", orderNumber);
            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid sökning av order {}: {}", orderNumber, e.getMessage());
            return null;
        }
    }

    /**
     * đŸ›Ąïž SAFE findByUser - anvĂ€nder EntityManager
     */
    public List<Order> findByUser(User user) {
        try {
            logger.info("🔍 HĂ€mtar alla orders för anvĂ€ndare: {}", user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.user = :user ORDER BY o.orderDate DESC", Order.class);
            query.setParameter("user", user);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            logger.info("✅ Hittade {} orders för anvĂ€ndare: {}", results.size(), user.getUsername());
            return results;

        } catch (Exception e) {
            logger.error("❌ Fel vid hĂ€mtning av orders för anvĂ€ndare {}: {}", user.getUsername(), e.getMessage());
            return List.of();
        }
    }

    // ===== ORDER STATUS MANAGEMENT =====

    /**
     * 🔄 Uppdatera orderstatus
     */
    public Order updateOrderStatus(Long orderId, Order.OrderStatus status) {
        try {
            logger.info("🔄 Uppdaterar orderstatus för ID {} till: {}", orderId, status);

            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("BestÀllning hittades inte"));

            Order.OrderStatus oldStatus = order.getStatus();
            order.setStatus(status);
            Order savedOrder = orderRepository.save(order);

            logger.info("✅ Orderstatus uppdaterad: {} frĂ„n {} till {}", order.getOrderNumber(), oldStatus, status);
            return savedOrder;

        } catch (Exception e) {
            logger.error("❌ Fel vid uppdatering av orderstatus för ID {}: {}", orderId, e.getMessage(), e);
            throw new RuntimeException("Kunde inte uppdatera orderstatus: " + e.getMessage(), e);
        }
    }

    /**
     * 🔄 Uppdatera orderstatus med notifieringar (för AdminController)
     */
    @Transactional
    public void updateOrderStatusWithNotifications(Long orderId, Order.OrderStatus newStatus) {
        try {
            logger.info("🔄 Uppdaterar orderstatus med notifieringar för ID {} till: {}", orderId, newStatus);

            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("Order not found: " + orderId));

            Order.OrderStatus oldStatus = order.getStatus();
            order.setStatus(newStatus);
            orderRepository.save(order);

            logger.info("✅ Orderstatus med notifieringar uppdaterad: {} frĂ„n {} till {}",
                    order.getOrderNumber(), oldStatus, newStatus);

        } catch (Exception e) {
            logger.error("❌ Fel vid uppdatering av orderstatus med notifieringar för ID {}: {}", orderId, e.getMessage(), e);
            throw new RuntimeException("Kunde inte uppdatera orderstatus: " + e.getMessage(), e);
        }
    }

    // ===== ORDER NUMBER GENERATION =====

    /**
     * 🔱 Generera unikt ordernummer med datum och sekvens
     * Format: CB20250707001, CB20250707002, etc.
     */
    private String generateOrderNumber() {
        try {
            // HĂ€mta dagens datum i format YYYYMMDD
            String datePrefix = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            logger.info("📅 Genererar ordernummer för datum: {}", datePrefix);

            // Sök efter högsta ordernummer för idag
            String todayPattern = "CB" + datePrefix + "%";

            // đŸ›Ąïž SAFE QUERY - anvĂ€nd EntityManager istĂ€llet för repository method
            Query query = entityManager.createQuery(
                    "SELECT o.orderNumber FROM Order o WHERE o.orderNumber LIKE :pattern");
            query.setParameter("pattern", todayPattern);

            @SuppressWarnings("unchecked")
            List<String> todaysOrders = query.getResultList();

            int nextSequence = 1;
            if (!todaysOrders.isEmpty()) {
                // Hitta högsta sekvensen för idag
                int maxSequence = 0;
                for (String orderNum : todaysOrders) {
                    if (orderNum.length() >= 13) { // CB + 8 datum + 3 sekvens = 13
                        try {
                            String sequencePart = orderNum.substring(10); // Ta sista 3 siffrorna
                            int sequence = Integer.parseInt(sequencePart);
                            maxSequence = Math.max(maxSequence, sequence);
                        } catch (NumberFormatException e) {
                            logger.warn("⚠ Felaktigt ordernummer format: {}", orderNum);
                        }
                    }
                }
                nextSequence = maxSequence + 1;
            }

            // Generera unikt ordernummer: CB + datum + 3-siffrig sekvens
            String orderNumber = String.format("CB%s%03d", datePrefix, nextSequence);
            logger.info("🔱 Genererat ordernummer: {} (sekvens: {})", orderNumber, nextSequence);

            return orderNumber;

        } catch (Exception e) {
            logger.error("❌ Fel vid generering av ordernummer: {}", e.getMessage(), e);
            // Fallback: anvÀnd timestamp
            String fallbackNumber = "CB" + System.currentTimeMillis();
            logger.warn("⚠ AnvĂ€nder fallback ordernummer: {}", fallbackNumber);
            return fallbackNumber;
        }
    }

    // ===== ORDER RETRIEVAL METHODS =====

    /**
     * 🔍 Hitta bestĂ€llning baserat pĂ„ ID
     */
    public Order findById(Long id) {
        try {
            logger.info("🔍 Söker order med ID: {}", id);

            return orderRepository.findById(id)
                    .orElseThrow(() -> new RuntimeException("BestÀllning hittades inte"));

        } catch (Exception e) {
            logger.error("❌ Fel vid sökning av order med ID {}: {}", id, e.getMessage());
            throw e;
        }
    }

    /**
     * 🔍 Hitta bestĂ€llning med orderItems (för att undvika LazyInitializationException)
     */
    @Transactional(readOnly = true)
    public Order findOrderWithItemsById(Long orderId) {
        try {
            logger.info("🔍 Söker order med items för ID: {}", orderId);

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o LEFT JOIN FETCH o.orderItems WHERE o.id = :orderId", Order.class);
            query.setParameter("orderId", orderId);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("⚠ Ingen order med items hittades för ID: {}", orderId);
                return null;
            }

            Order order = results.get(0);
            logger.info("✅ Order med {} items hittades för ID: {}",
                    order.getOrderItems().size(), orderId);
            return order;

        } catch (Exception e) {
            logger.error("❌ Fel vid hĂ€mtning av order med items för ID {}: {}", orderId, e.getMessage());
            return null;
        }
    }

    /**
     * 📋 Alla bestĂ€llningar (admin) - ANVÄND ENTITYMANAGER
     */
    public List<Order> findAll() {
        return getAllOrders(); // AnvÀnd vÄr EntityManager-version
    }

    // ===== USER-SPECIFIC ORDER METHODS =====

    /**
     * 📊 RĂ€kna antal bestĂ€llningar för anvĂ€ndare
     */
    public Long countOrdersByUser(User user) {
        try {
            logger.info("📊 RĂ€knar orders för anvĂ€ndare: {}", user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT COUNT(o) FROM Order o WHERE o.user = :user");
            query.setParameter("user", user);

            Long count = (Long) query.getSingleResult();
            logger.info("📊 AnvĂ€ndare {} har {} orders", user.getUsername(), count);
            return count;

        } catch (Exception e) {
            logger.error("❌ Fel vid rĂ€kning av orders för anvĂ€ndare {}: {}", user.getUsername(), e.getMessage());
            return 0L;
        }
    }

    /**
     * 📄 HĂ€mta orders med paginering för orderhistorik
     */
    public Page<Order> getOrdersByUserWithPagination(User user, int page, int size) {
        try {
            logger.info("📄 HĂ€mtar orders med paginering för anvĂ€ndare: {} (sida {}, storlek {})",
                    user.getUsername(), page, size);

            Pageable pageable = PageRequest.of(page, size, Sort.by("orderDate").descending());

            // đŸ›Ąïž SAFE PAGINATION - anvĂ€nd findByUser och manuell paginering
            List<Order> allOrders = findByUser(user);

            int start = (int) pageable.getOffset();
            int end = Math.min((start + pageable.getPageSize()), allOrders.size());

            List<Order> pageContent = allOrders.subList(start, end);
            Page<Order> result = new PageImpl<>(pageContent, pageable, allOrders.size());

            logger.info("✅ Returnerar sida {} av {} orders för anvĂ€ndare {}",
                    page, pageContent.size(), user.getUsername());
            return result;

        } catch (Exception e) {
            logger.error("❌ Fel vid hĂ€mtning av paginerade orders för anvĂ€ndare {}: {}",
                    user.getUsername(), e.getMessage());
            return new PageImpl<>(List.of(), PageRequest.of(page, size), 0);
        }
    }

    /**
     * 🔐 HĂ€mta specifik order för anvĂ€ndare (sĂ€kerhetscheck)
     */
    public Optional<Order> getOrderByIdAndUser(Long orderId, User user) {
        try {
            logger.info("🔐 SĂ€kerhetscheck - hĂ€mtar order ID {} för anvĂ€ndare: {}", orderId, user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT o FROM Order o WHERE o.id = :orderId AND o.user = :user", Order.class);
            query.setParameter("orderId", orderId);
            query.setParameter("user", user);

            @SuppressWarnings("unchecked")
            List<Order> results = query.getResultList();

            if (results.isEmpty()) {
                logger.warn("⚠ Ingen order med ID {} hittades för anvĂ€ndare {}", orderId, user.getUsername());
                return Optional.empty();
            }

            Order order = results.get(0);
            logger.info("✅ SĂ€kerhetscheck OK - order {} tillhör anvĂ€ndare {}",
                    order.getOrderNumber(), user.getUsername());
            return Optional.of(order);

        } catch (Exception e) {
            logger.error("❌ Fel vid sĂ€kerhetscheck av order ID {} för anvĂ€ndare {}: {}",
                    orderId, user.getUsername(), e.getMessage());
            return Optional.empty();
        }
    }

    /**
     * 💰 BerĂ€kna total summa för alla orders av anvĂ€ndare
     */
    public Double getTotalSpentByUser(User user) {
        try {
            logger.info("💰 BerĂ€knar total summa för anvĂ€ndare: {}", user.getUsername());

            Query query = entityManager.createQuery(
                    "SELECT SUM(o.totalAmount) FROM Order o WHERE o.user = :user AND o.status != :cancelledStatus");
            query.setParameter("user", user);
            query.setParameter("cancelledStatus", Order.OrderStatus.CANCELLED);

            Double total = (Double) query.getSingleResult();
            if (total == null) {
                total = 0.0;
            }

            logger.info("💰 AnvĂ€ndare {} har spenderat totalt: {} kr", user.getUsername(), total);
            return total;

        } catch (Exception e) {
            logger.error("❌ Fel vid berĂ€kning av total summa för anvĂ€ndare {}: {}",
                    user.getUsername(), e.getMessage());
            return 0.0;
        }
    }

    // ===== UTILITY METHODS =====

    /**
     * 📊 countOrdersForUser - AdminController-kompatibel
     */
    public long countOrdersForUser(User user) {
        Long count = countOrdersByUser(user);
        return count != null ? count : 0L;
    }

    /**
     * 🕐 getRecentOrdersForUser - HĂ€mta senaste bestĂ€llningar
     */
    public List<Order> getRecentOrdersForUser(User user) {
        List<Order> allOrders = findByUser(user);
        return allOrders.stream().limit(5).collect(Collectors.toList());
    }

    /**
     * ❌ cancelOrder - Avbryt bestĂ€llning (endast om PENDING)
     */
    @Transactional
    public boolean cancelOrder(Long orderId, User user) {
        try {
            logger.info("❌ Försöker avbryta order ID {} för anvĂ€ndare: {}", orderId, user.getUsername());

            Optional<Order> orderOpt = getOrderByIdAndUser(orderId, user);
            if (!orderOpt.isPresent()) {
                logger.warn("⚠ Order ID {} tillhör inte anvĂ€ndare {}", orderId, user.getUsername());
                return false;
            }

            Order order = orderOpt.get();

            // Kan bara avbryta vÀntande bestÀllningar
            if (order.getStatus() != Order.OrderStatus.PENDING) {
                logger.warn("⚠ Kan inte avbryta order {} med status: {}",
                        order.getOrderNumber(), order.getStatus());
                return false;
            }

            order.setStatus(Order.OrderStatus.CANCELLED);
            orderRepository.save(order);

            logger.info("✅ Order {} avbruten för anvĂ€ndare: {}",
                    order.getOrderNumber(), user.getUsername());

            return true;

        } catch (Exception e) {
            logger.error("❌ Fel vid avbrytning av order ID {} för anvĂ€ndare {}: {}",
                    orderId, user.getUsername(), e.getMessage());
            return false;
        }
    }

    // ===== ADMIN METHODS =====

    /**
     * 📄 getAllOrders - HĂ€mta alla bestĂ€llningar med paginering (för admin)
     */
    public Page<Order> getAllOrders(Pageable pageable) {
        try {
            logger.info("📄 Admin - hĂ€mtar alla orders med paginering");

            List<Order> allOrders = findAll();

            int start = (int) pageable.getOffset();
            int end = Math.min((start + pageable.getPageSize()), allOrders.size());

            List<Order> pageContent = allOrders.subList(start, end);
            Page<Order> result = new PageImpl<>(pageContent, pageable, allOrders.size());

            logger.info("✅ Admin - returnerar {} orders av {} totalt", pageContent.size(), allOrders.size());
            return result;

        } catch (Exception e) {
            logger.error("❌ Fel vid admin-hĂ€mtning av paginerade orders: {}", e.getMessage());
            return new PageImpl<>(List.of(), pageable, 0);
        }
    }

    // ===== DTO CLASSES =====

    /**
     * 📋 OrderDetails - DTO för bestĂ€llningsdata
     */
    public static class OrderDetails {
        private String deliveryName;
        private String deliveryAddress;
        private String deliveryCity;
        private String deliveryPostalCode;
        private String deliveryPhone;
        private String paymentMethod;

        // Getters
        public String getDeliveryName() { return deliveryName; }
        public String getDeliveryAddress() { return deliveryAddress; }
        public String getDeliveryCity() { return deliveryCity; }
        public String getDeliveryPostalCode() { return deliveryPostalCode; }
        public String getDeliveryPhone() { return deliveryPhone; }
        public String getPaymentMethod() { return paymentMethod; }

        // Setters
        public void setDeliveryName(String deliveryName) { this.deliveryName = deliveryName; }
        public void setDeliveryAddress(String deliveryAddress) { this.deliveryAddress = deliveryAddress; }
        public void setDeliveryCity(String deliveryCity) { this.deliveryCity = deliveryCity; }
        public void setDeliveryPostalCode(String deliveryPostalCode) { this.deliveryPostalCode = deliveryPostalCode; }
        public void setDeliveryPhone(String deliveryPhone) { this.deliveryPhone = deliveryPhone; }
        public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }
    }

    /**
     * đŸ‘€ GuestOrderDetails - DTO för gĂ€st-bestĂ€llningar
     */
    public static class GuestOrderDetails {
        private String firstName;
        private String lastName;
        private String email;
        private String phone;
        private String address;
        private String city;
        private String postalCode;
        private String paymentMethod;

        // Konstruktor
        public GuestOrderDetails() {}

        // Getters
        public String getFirstName() { return firstName; }
        public String getLastName() { return lastName; }
        public String getEmail() { return email; }
        public String getPhone() { return phone; }
        public String getAddress() { return address; }
        public String getCity() { return city; }
        public String getPostalCode() { return postalCode; }
        public String getPaymentMethod() { return paymentMethod; }

        // Setters
        public void setFirstName(String firstName) { this.firstName = firstName; }
        public void setLastName(String lastName) { this.lastName = lastName; }
        public void setEmail(String email) { this.email = email; }
        public void setPhone(String phone) { this.phone = phone; }
        public void setAddress(String address) { this.address = address; }
        public void setCity(String city) { this.city = city; }
        public void setPostalCode(String postalCode) { this.postalCode = postalCode; }
        public void setPaymentMethod(String paymentMethod) { this.paymentMethod = paymentMethod; }
    }
}